svelte-compiler 0.1.4

Core compiler API for the Rust Svelte toolchain
Documentation
use std::marker::PhantomData;

use crate::api::CompileOptions;
use crate::ast::modern::Root;
use crate::compiler::phases::parse::ParsedComponent;
use crate::{SourceId, SourceText};

#[derive(Debug, Clone)]
pub(crate) struct ComponentContext<'a> {
    parsed: ParsedComponent,
    options: &'a CompileOptions,
}

impl<'a> ComponentContext<'a> {
    pub(crate) fn new(parsed: ParsedComponent, options: &'a CompileOptions) -> Self {
        Self { parsed, options }
    }

    pub(crate) fn source(&self) -> &str {
        self.parsed.source()
    }

    pub(crate) fn options(&self) -> &'a CompileOptions {
        self.options
    }

    pub(crate) fn root(&self) -> &Root {
        self.parsed.root()
    }

    pub(crate) fn source_text(&self) -> SourceText<'_> {
        SourceText::new(
            SourceId::new(0),
            self.source(),
            self.options.filename.as_deref(),
        )
    }
}

impl AsRef<str> for ComponentContext<'_> {
    fn as_ref(&self) -> &str {
        self.source()
    }
}

impl AsRef<CompileOptions> for ComponentContext<'_> {
    fn as_ref(&self) -> &CompileOptions {
        self.options()
    }
}

impl AsRef<Root> for ComponentContext<'_> {
    fn as_ref(&self) -> &Root {
        self.root()
    }
}

mod sealed {
    pub trait Sealed {}
}

pub(crate) trait ComponentStage: sealed::Sealed {}

#[derive(Debug, Clone, Copy)]
pub(crate) struct Analyzed;

#[derive(Debug, Clone, Copy)]
pub(crate) struct Lowered;

impl sealed::Sealed for Analyzed {}
impl sealed::Sealed for Lowered {}

impl ComponentStage for Analyzed {}
impl ComponentStage for Lowered {}

#[derive(Debug, Clone)]
pub(crate) struct ComponentCompilation<'a, Stage: ComponentStage> {
    ctx: ComponentContext<'a>,
    runes: bool,
    scoped_element_starts: Box<[usize]>,
    _stage: PhantomData<Stage>,
}

pub(crate) type ComponentAnalysis<'a> = ComponentCompilation<'a, Analyzed>;
pub(crate) type LoweredComponent<'a> = ComponentCompilation<'a, Lowered>;

impl<'a, Stage: ComponentStage> ComponentCompilation<'a, Stage> {
    fn new(ctx: ComponentContext<'a>, runes: bool, scoped_element_starts: Box<[usize]>) -> Self {
        Self {
            ctx,
            runes,
            scoped_element_starts,
            _stage: PhantomData,
        }
    }

    pub(crate) fn source(&self) -> &str {
        self.ctx.source()
    }

    pub(crate) fn options(&self) -> &'a CompileOptions {
        self.ctx.options()
    }

    pub(crate) fn root(&self) -> &Root {
        self.ctx.root()
    }

    pub(crate) fn source_text(&self) -> SourceText<'_> {
        self.ctx.source_text()
    }

    pub(crate) fn runes(&self) -> bool {
        self.runes
    }

    pub(crate) fn scoped_element_starts(&self) -> &[usize] {
        &self.scoped_element_starts
    }
}

impl<'a> ComponentAnalysis<'a> {
    pub(crate) fn from_context(
        ctx: ComponentContext<'a>,
        runes: bool,
        scoped_element_starts: Box<[usize]>,
    ) -> Self {
        Self::new(ctx, runes, scoped_element_starts)
    }

    pub(crate) fn lower(self) -> LoweredComponent<'a> {
        LoweredComponent::new(self.ctx, self.runes, self.scoped_element_starts)
    }
}

impl<Stage: ComponentStage> AsRef<str> for ComponentCompilation<'_, Stage> {
    fn as_ref(&self) -> &str {
        self.source()
    }
}

impl<Stage: ComponentStage> AsRef<CompileOptions> for ComponentCompilation<'_, Stage> {
    fn as_ref(&self) -> &CompileOptions {
        self.options()
    }
}

impl<Stage: ComponentStage> AsRef<Root> for ComponentCompilation<'_, Stage> {
    fn as_ref(&self) -> &Root {
        self.root()
    }
}