expose more AST internals in grass_compiler
This commit is contained in:
parent
8363ca1dd3
commit
8b34d0ee2a
@ -9,6 +9,9 @@
|
|||||||
|
|
||||||
# 0.13.0
|
# 0.13.0
|
||||||
|
|
||||||
|
- fix various module system bugs when combined with `@import`
|
||||||
|
- expose more AST internals in `grass_compiler`
|
||||||
|
|
||||||
# 0.12.4
|
# 0.12.4
|
||||||
|
|
||||||
- implement builtin map-module functions `map.deep-merge(..)` and `map.deep-remove(..)`
|
- implement builtin map-module functions `map.deep-merge(..)` and `map.deep-remove(..)`
|
||||||
|
@ -16,13 +16,13 @@ use crate::{
|
|||||||
use super::AstExpr;
|
use super::AstExpr;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Argument {
|
pub struct Argument {
|
||||||
pub name: Identifier,
|
pub name: Identifier,
|
||||||
pub default: Option<AstExpr>,
|
pub default: Option<AstExpr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ArgumentDeclaration {
|
pub struct ArgumentDeclaration {
|
||||||
pub args: Vec<Argument>,
|
pub args: Vec<Argument>,
|
||||||
pub rest: Option<Identifier>,
|
pub rest: Option<Identifier>,
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ impl ArgumentDeclaration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ArgumentInvocation {
|
pub struct ArgumentInvocation {
|
||||||
pub(crate) positional: Vec<AstExpr>,
|
pub(crate) positional: Vec<AstExpr>,
|
||||||
pub(crate) named: BTreeMap<Identifier, AstExpr>,
|
pub(crate) named: BTreeMap<Identifier, AstExpr>,
|
||||||
pub(crate) rest: Option<AstExpr>,
|
pub(crate) rest: Option<AstExpr>,
|
||||||
|
@ -13,17 +13,17 @@ use super::{ArgumentInvocation, AstSupportsCondition, Interpolation, Interpolati
|
|||||||
|
|
||||||
/// Represented by the `if` function
|
/// Represented by the `if` function
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Ternary(pub ArgumentInvocation);
|
pub struct Ternary(pub ArgumentInvocation);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ListExpr {
|
pub struct ListExpr {
|
||||||
pub elems: Vec<Spanned<AstExpr>>,
|
pub elems: Vec<Spanned<AstExpr>>,
|
||||||
pub separator: ListSeparator,
|
pub separator: ListSeparator,
|
||||||
pub brackets: Brackets,
|
pub brackets: Brackets,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct FunctionCallExpr {
|
pub struct FunctionCallExpr {
|
||||||
pub namespace: Option<Spanned<Identifier>>,
|
pub namespace: Option<Spanned<Identifier>>,
|
||||||
pub name: Identifier,
|
pub name: Identifier,
|
||||||
pub arguments: Arc<ArgumentInvocation>,
|
pub arguments: Arc<ArgumentInvocation>,
|
||||||
@ -31,17 +31,17 @@ pub(crate) struct FunctionCallExpr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct InterpolatedFunction {
|
pub struct InterpolatedFunction {
|
||||||
pub name: Interpolation,
|
pub name: Interpolation,
|
||||||
pub arguments: ArgumentInvocation,
|
pub arguments: ArgumentInvocation,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub(crate) struct AstSassMap(pub Vec<(Spanned<AstExpr>, AstExpr)>);
|
pub struct AstSassMap(pub Vec<(Spanned<AstExpr>, AstExpr)>);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct BinaryOpExpr {
|
pub struct BinaryOpExpr {
|
||||||
pub lhs: AstExpr,
|
pub lhs: AstExpr,
|
||||||
pub op: BinaryOp,
|
pub op: BinaryOp,
|
||||||
pub rhs: AstExpr,
|
pub rhs: AstExpr,
|
||||||
@ -50,7 +50,7 @@ pub(crate) struct BinaryOpExpr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum AstExpr {
|
pub enum AstExpr {
|
||||||
BinaryOp(Arc<BinaryOpExpr>),
|
BinaryOp(Arc<BinaryOpExpr>),
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
@ -83,7 +83,7 @@ pub(crate) enum AstExpr {
|
|||||||
// todo: make quotes bool
|
// todo: make quotes bool
|
||||||
// todo: track span inside
|
// todo: track span inside
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct StringExpr(pub Interpolation, pub QuoteKind);
|
pub struct StringExpr(pub Interpolation, pub QuoteKind);
|
||||||
|
|
||||||
impl StringExpr {
|
impl StringExpr {
|
||||||
fn quote_inner_text(
|
fn quote_inner_text(
|
||||||
|
@ -3,7 +3,7 @@ use codemap::Spanned;
|
|||||||
use super::AstExpr;
|
use super::AstExpr;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Interpolation {
|
pub struct Interpolation {
|
||||||
pub contents: Vec<InterpolationPart>,
|
pub contents: Vec<InterpolationPart>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ impl Interpolation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum InterpolationPart {
|
pub enum InterpolationPart {
|
||||||
String(String),
|
String(String),
|
||||||
Expr(Spanned<AstExpr>),
|
Expr(Spanned<AstExpr>),
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ pub(crate) struct MediaRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub(crate) struct MediaQuery {
|
pub struct MediaQuery {
|
||||||
pub modifier: Option<String>,
|
pub modifier: Option<String>,
|
||||||
pub media_type: Option<String>,
|
pub media_type: Option<String>,
|
||||||
pub conditions: Vec<String>,
|
pub conditions: Vec<String>,
|
||||||
@ -60,7 +60,7 @@ impl MediaQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::if_not_else)]
|
#[allow(clippy::if_not_else)]
|
||||||
pub fn merge(&self, other: &Self) -> MediaQueryMergeResult {
|
pub(crate) fn merge(&self, other: &Self) -> MediaQueryMergeResult {
|
||||||
if !self.conjunction || !other.conjunction {
|
if !self.conjunction || !other.conjunction {
|
||||||
return MediaQueryMergeResult::Unrepresentable;
|
return MediaQueryMergeResult::Unrepresentable;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
pub(crate) use args::*;
|
pub use args::*;
|
||||||
pub(crate) use css::*;
|
pub(crate) use css::*;
|
||||||
pub(crate) use expr::*;
|
pub use expr::*;
|
||||||
pub(crate) use interpolation::*;
|
pub use interpolation::*;
|
||||||
pub(crate) use media::*;
|
pub(crate) use media::*;
|
||||||
pub(crate) use mixin::*;
|
pub(crate) use mixin::*;
|
||||||
pub(crate) use stmt::*;
|
pub use stmt::*;
|
||||||
pub(crate) use style::*;
|
pub(crate) use style::*;
|
||||||
pub(crate) use unknown::*;
|
pub(crate) use unknown::*;
|
||||||
|
|
||||||
|
@ -17,13 +17,13 @@ use crate::{
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) struct AstSilentComment {
|
pub struct AstSilentComment {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstPlainCssImport {
|
pub struct AstPlainCssImport {
|
||||||
pub url: Interpolation,
|
pub url: Interpolation,
|
||||||
pub modifiers: Option<Interpolation>,
|
pub modifiers: Option<Interpolation>,
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@ -31,25 +31,25 @@ pub(crate) struct AstPlainCssImport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstSassImport {
|
pub struct AstSassImport {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstIf {
|
pub struct AstIf {
|
||||||
pub if_clauses: Vec<AstIfClause>,
|
pub if_clauses: Vec<AstIfClause>,
|
||||||
pub else_clause: Option<Vec<AstStmt>>,
|
pub else_clause: Option<Vec<AstStmt>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstIfClause {
|
pub struct AstIfClause {
|
||||||
pub condition: AstExpr,
|
pub condition: AstExpr,
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstFor {
|
pub struct AstFor {
|
||||||
pub variable: Spanned<Identifier>,
|
pub variable: Spanned<Identifier>,
|
||||||
pub from: Spanned<AstExpr>,
|
pub from: Spanned<AstExpr>,
|
||||||
pub to: Spanned<AstExpr>,
|
pub to: Spanned<AstExpr>,
|
||||||
@ -58,14 +58,14 @@ pub(crate) struct AstFor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstReturn {
|
pub struct AstReturn {
|
||||||
pub val: AstExpr,
|
pub val: AstExpr,
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstRuleSet {
|
pub struct AstRuleSet {
|
||||||
pub selector: Interpolation,
|
pub selector: Interpolation,
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
pub selector_span: Span,
|
pub selector_span: Span,
|
||||||
@ -73,7 +73,7 @@ pub(crate) struct AstRuleSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstStyle {
|
pub struct AstStyle {
|
||||||
pub name: Interpolation,
|
pub name: Interpolation,
|
||||||
pub value: Option<Spanned<AstExpr>>,
|
pub value: Option<Spanned<AstExpr>>,
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
@ -87,30 +87,30 @@ impl AstStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstEach {
|
pub struct AstEach {
|
||||||
pub variables: Vec<Identifier>,
|
pub variables: Vec<Identifier>,
|
||||||
pub list: AstExpr,
|
pub list: AstExpr,
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstMedia {
|
pub struct AstMedia {
|
||||||
pub query: Interpolation,
|
pub query: Interpolation,
|
||||||
pub query_span: Span,
|
pub query_span: Span,
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type CssMediaQuery = MediaQuery;
|
pub type CssMediaQuery = MediaQuery;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstWhile {
|
pub struct AstWhile {
|
||||||
pub condition: AstExpr,
|
pub condition: AstExpr,
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstVariableDecl {
|
pub struct AstVariableDecl {
|
||||||
pub namespace: Option<Spanned<Identifier>>,
|
pub namespace: Option<Spanned<Identifier>>,
|
||||||
pub name: Identifier,
|
pub name: Identifier,
|
||||||
pub value: AstExpr,
|
pub value: AstExpr,
|
||||||
@ -120,26 +120,26 @@ pub(crate) struct AstVariableDecl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstFunctionDecl {
|
pub struct AstFunctionDecl {
|
||||||
pub name: Spanned<Identifier>,
|
pub name: Spanned<Identifier>,
|
||||||
pub arguments: ArgumentDeclaration,
|
pub arguments: ArgumentDeclaration,
|
||||||
pub children: Vec<AstStmt>,
|
pub children: Vec<AstStmt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstDebugRule {
|
pub struct AstDebugRule {
|
||||||
pub value: AstExpr,
|
pub value: AstExpr,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstWarn {
|
pub struct AstWarn {
|
||||||
pub value: AstExpr,
|
pub value: AstExpr,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstErrorRule {
|
pub struct AstErrorRule {
|
||||||
pub value: AstExpr,
|
pub value: AstExpr,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
@ -153,13 +153,13 @@ impl PartialEq for AstFunctionDecl {
|
|||||||
impl Eq for AstFunctionDecl {}
|
impl Eq for AstFunctionDecl {}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstLoudComment {
|
pub struct AstLoudComment {
|
||||||
pub text: Interpolation,
|
pub text: Interpolation,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstMixin {
|
pub struct AstMixin {
|
||||||
pub name: Identifier,
|
pub name: Identifier,
|
||||||
pub args: ArgumentDeclaration,
|
pub args: ArgumentDeclaration,
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
@ -168,18 +168,18 @@ pub(crate) struct AstMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstContentRule {
|
pub struct AstContentRule {
|
||||||
pub args: ArgumentInvocation,
|
pub args: ArgumentInvocation,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstContentBlock {
|
pub struct AstContentBlock {
|
||||||
pub args: ArgumentDeclaration,
|
pub args: ArgumentDeclaration,
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstInclude {
|
pub struct AstInclude {
|
||||||
pub namespace: Option<Spanned<Identifier>>,
|
pub namespace: Option<Spanned<Identifier>>,
|
||||||
pub name: Spanned<Identifier>,
|
pub name: Spanned<Identifier>,
|
||||||
pub args: ArgumentInvocation,
|
pub args: ArgumentInvocation,
|
||||||
@ -188,7 +188,7 @@ pub(crate) struct AstInclude {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstUnknownAtRule {
|
pub struct AstUnknownAtRule {
|
||||||
pub name: Interpolation,
|
pub name: Interpolation,
|
||||||
pub value: Option<Interpolation>,
|
pub value: Option<Interpolation>,
|
||||||
pub children: Option<Vec<AstStmt>>,
|
pub children: Option<Vec<AstStmt>>,
|
||||||
@ -196,14 +196,15 @@ pub(crate) struct AstUnknownAtRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstExtendRule {
|
pub struct AstExtendRule {
|
||||||
pub value: Interpolation,
|
pub value: Interpolation,
|
||||||
pub is_optional: bool,
|
pub is_optional: bool,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstAtRootRule {
|
pub struct AstAtRootRule {
|
||||||
|
// todo: rename to body
|
||||||
pub children: Vec<AstStmt>,
|
pub children: Vec<AstStmt>,
|
||||||
pub query: Option<Spanned<Interpolation>>,
|
pub query: Option<Spanned<Interpolation>>,
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@ -211,7 +212,7 @@ pub(crate) struct AstAtRootRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AtRootQuery {
|
pub struct AtRootQuery {
|
||||||
pub include: bool,
|
pub include: bool,
|
||||||
pub names: HashSet<String>,
|
pub names: HashSet<String>,
|
||||||
pub all: bool,
|
pub all: bool,
|
||||||
@ -239,7 +240,7 @@ impl AtRootQuery {
|
|||||||
(self.all || self.rule) != self.include
|
(self.all || self.rule) != self.include
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn excludes(&self, stmt: &CssStmt) -> bool {
|
pub(crate) fn excludes(&self, stmt: &CssStmt) -> bool {
|
||||||
if self.all {
|
if self.all {
|
||||||
return !self.include;
|
return !self.include;
|
||||||
}
|
}
|
||||||
@ -266,12 +267,12 @@ impl Default for AtRootQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstImportRule {
|
pub struct AstImportRule {
|
||||||
pub imports: Vec<AstImport>,
|
pub imports: Vec<AstImport>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum AstImport {
|
pub enum AstImport {
|
||||||
Plain(AstPlainCssImport),
|
Plain(AstPlainCssImport),
|
||||||
Sass(AstSassImport),
|
Sass(AstSassImport),
|
||||||
}
|
}
|
||||||
@ -283,7 +284,7 @@ impl AstImport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstUseRule {
|
pub struct AstUseRule {
|
||||||
pub url: PathBuf,
|
pub url: PathBuf,
|
||||||
pub namespace: Option<String>,
|
pub namespace: Option<String>,
|
||||||
pub configuration: Vec<ConfiguredVariable>,
|
pub configuration: Vec<ConfiguredVariable>,
|
||||||
@ -291,18 +292,18 @@ pub(crate) struct AstUseRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ConfiguredVariable {
|
pub struct ConfiguredVariable {
|
||||||
pub name: Spanned<Identifier>,
|
pub name: Spanned<Identifier>,
|
||||||
pub expr: Spanned<AstExpr>,
|
pub expr: Spanned<AstExpr>,
|
||||||
pub is_guarded: bool,
|
pub is_guarded: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Configuration {
|
pub struct Configuration {
|
||||||
pub values: Arc<dyn MapView<Value = ConfiguredValue>>,
|
pub(crate) values: Arc<dyn MapView<Value = ConfiguredValue>>,
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub original_config: Option<Arc<RefCell<Self>>>,
|
pub(crate) original_config: Option<Arc<RefCell<Self>>>,
|
||||||
pub span: Option<Span>,
|
pub(crate) span: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Configuration {
|
impl Configuration {
|
||||||
@ -403,7 +404,7 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ConfiguredValue {
|
pub struct ConfiguredValue {
|
||||||
pub value: Value,
|
pub value: Value,
|
||||||
pub configuration_span: Option<Span>,
|
pub configuration_span: Option<Span>,
|
||||||
}
|
}
|
||||||
@ -425,7 +426,7 @@ impl ConfiguredValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstForwardRule {
|
pub struct AstForwardRule {
|
||||||
pub url: PathBuf,
|
pub url: PathBuf,
|
||||||
pub shown_mixins_and_functions: Option<HashSet<Identifier>>,
|
pub shown_mixins_and_functions: Option<HashSet<Identifier>>,
|
||||||
pub shown_variables: Option<HashSet<Identifier>>,
|
pub shown_variables: Option<HashSet<Identifier>>,
|
||||||
@ -497,7 +498,7 @@ impl AstForwardRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum AstSupportsCondition {
|
pub enum AstSupportsCondition {
|
||||||
Anything {
|
Anything {
|
||||||
contents: Interpolation,
|
contents: Interpolation,
|
||||||
},
|
},
|
||||||
@ -519,14 +520,14 @@ pub(crate) enum AstSupportsCondition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct AstSupportsRule {
|
pub struct AstSupportsRule {
|
||||||
pub condition: AstSupportsCondition,
|
pub condition: AstSupportsCondition,
|
||||||
pub children: Vec<AstStmt>,
|
pub children: Vec<AstStmt>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum AstStmt {
|
pub enum AstStmt {
|
||||||
If(AstIf),
|
If(AstIf),
|
||||||
For(AstFor),
|
For(AstFor),
|
||||||
Return(AstReturn),
|
Return(AstReturn),
|
||||||
@ -555,12 +556,13 @@ pub(crate) enum AstStmt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct StyleSheet {
|
pub struct StyleSheet {
|
||||||
pub body: Vec<AstStmt>,
|
pub body: Vec<AstStmt>,
|
||||||
pub url: PathBuf,
|
pub url: PathBuf,
|
||||||
pub is_plain_css: bool,
|
pub is_plain_css: bool,
|
||||||
/// Array of indices into body
|
/// Array of indices into `body`
|
||||||
pub uses: Vec<usize>,
|
pub uses: Vec<usize>,
|
||||||
|
/// Array of indices into `body`
|
||||||
pub forwards: Vec<usize>,
|
pub forwards: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,11 +21,11 @@ use super::{scope::Scopes, visitor::CallableContentBlock};
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Environment {
|
pub(crate) struct Environment {
|
||||||
pub scopes: Scopes,
|
pub scopes: Scopes,
|
||||||
pub modules: Arc<RefCell<Modules>>,
|
pub modules: Mutable<Modules>,
|
||||||
pub global_modules: Vec<Arc<RefCell<Module>>>,
|
pub global_modules: Vec<Mutable<Module>>,
|
||||||
pub content: Option<Arc<CallableContentBlock>>,
|
pub content: Option<Arc<CallableContentBlock>>,
|
||||||
pub forwarded_modules: Arc<RefCell<Vec<Arc<RefCell<Module>>>>>,
|
pub forwarded_modules: Mutable<Vec<Mutable<Module>>>,
|
||||||
pub imported_modules: Arc<RefCell<Vec<Arc<RefCell<Module>>>>>,
|
pub imported_modules: Mutable<Vec<Mutable<Module>>>,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub nested_forwarded_modules: Option<Mutable<Vec<Mutable<Vec<Mutable<Module>>>>>>,
|
pub nested_forwarded_modules: Option<Mutable<Vec<Mutable<Vec<Mutable<Module>>>>>>,
|
||||||
}
|
}
|
||||||
@ -175,7 +175,6 @@ impl Environment {
|
|||||||
imported_modules.extend(forwarded.borrow().iter().map(Arc::clone));
|
imported_modules.extend(forwarded.borrow().iter().map(Arc::clone));
|
||||||
forwarded_modules.extend(forwarded.borrow().iter().map(Arc::clone));
|
forwarded_modules.extend(forwarded.borrow().iter().map(Arc::clone));
|
||||||
} else {
|
} else {
|
||||||
self.scopes.last_variable_index = None;
|
|
||||||
self.nested_forwarded_modules
|
self.nested_forwarded_modules
|
||||||
.get_or_insert_with(|| {
|
.get_or_insert_with(|| {
|
||||||
Arc::new(RefCell::new(
|
Arc::new(RefCell::new(
|
||||||
|
@ -111,7 +111,10 @@ pub struct Visitor<'a> {
|
|||||||
pub(crate) media_queries: Option<Vec<MediaQuery>>,
|
pub(crate) media_queries: Option<Vec<MediaQuery>>,
|
||||||
pub(crate) media_query_sources: Option<IndexSet<MediaQuery>>,
|
pub(crate) media_query_sources: Option<IndexSet<MediaQuery>>,
|
||||||
pub(crate) extender: ExtensionStore,
|
pub(crate) extender: ExtensionStore,
|
||||||
pub(crate) current_import_path: PathBuf,
|
|
||||||
|
/// The complete file path of the current file being visited. Imports are
|
||||||
|
/// resolved relative to this path
|
||||||
|
pub current_import_path: PathBuf,
|
||||||
pub(crate) is_plain_css: bool,
|
pub(crate) is_plain_css: bool,
|
||||||
pub(crate) modules: BTreeMap<PathBuf, Arc<RefCell<Module>>>,
|
pub(crate) modules: BTreeMap<PathBuf, Arc<RefCell<Module>>>,
|
||||||
pub(crate) active_modules: BTreeSet<PathBuf>,
|
pub(crate) active_modules: BTreeSet<PathBuf>,
|
||||||
@ -119,10 +122,10 @@ pub struct Visitor<'a> {
|
|||||||
parent: Option<CssTreeIdx>,
|
parent: Option<CssTreeIdx>,
|
||||||
configuration: Arc<RefCell<Configuration>>,
|
configuration: Arc<RefCell<Configuration>>,
|
||||||
import_nodes: Vec<CssStmt>,
|
import_nodes: Vec<CssStmt>,
|
||||||
pub(crate) options: &'a Options<'a>,
|
pub options: &'a Options<'a>,
|
||||||
pub(crate) map: &'a mut CodeMap,
|
pub(crate) map: &'a mut CodeMap,
|
||||||
// todo: remove
|
// todo: remove
|
||||||
span_before: Span,
|
empty_span: Span,
|
||||||
import_cache: BTreeMap<PathBuf, StyleSheet>,
|
import_cache: BTreeMap<PathBuf, StyleSheet>,
|
||||||
/// As a simple heuristic, we don't cache the results of an import unless it
|
/// As a simple heuristic, we don't cache the results of an import unless it
|
||||||
/// has been seen in the past. In the majority of cases, files are imported
|
/// has been seen in the past. In the majority of cases, files are imported
|
||||||
@ -131,16 +134,16 @@ pub struct Visitor<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Visitor<'a> {
|
impl<'a> Visitor<'a> {
|
||||||
pub(crate) fn new(
|
pub fn new(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
options: &'a Options<'a>,
|
options: &'a Options<'a>,
|
||||||
map: &'a mut CodeMap,
|
map: &'a mut CodeMap,
|
||||||
span_before: Span,
|
empty_span: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut flags = ContextFlags::empty();
|
let mut flags = ContextFlags::empty();
|
||||||
flags.set(ContextFlags::IN_SEMI_GLOBAL_SCOPE, true);
|
flags.set(ContextFlags::IN_SEMI_GLOBAL_SCOPE, true);
|
||||||
|
|
||||||
let extender = ExtensionStore::new(span_before);
|
let extender = ExtensionStore::new(empty_span);
|
||||||
|
|
||||||
let current_import_path = path.to_path_buf();
|
let current_import_path = path.to_path_buf();
|
||||||
|
|
||||||
@ -162,7 +165,7 @@ impl<'a> Visitor<'a> {
|
|||||||
modules: BTreeMap::new(),
|
modules: BTreeMap::new(),
|
||||||
active_modules: BTreeSet::new(),
|
active_modules: BTreeSet::new(),
|
||||||
options,
|
options,
|
||||||
span_before,
|
empty_span,
|
||||||
map,
|
map,
|
||||||
import_cache: BTreeMap::new(),
|
import_cache: BTreeMap::new(),
|
||||||
files_seen: BTreeSet::new(),
|
files_seen: BTreeSet::new(),
|
||||||
@ -433,7 +436,7 @@ impl<'a> Visitor<'a> {
|
|||||||
self.parenthesize_supports_condition(*condition, None)?
|
self.parenthesize_supports_condition(*condition, None)?
|
||||||
)),
|
)),
|
||||||
AstSupportsCondition::Interpolation(expr) => {
|
AstSupportsCondition::Interpolation(expr) => {
|
||||||
self.evaluate_to_css(expr, QuoteKind::None, self.span_before)
|
self.evaluate_to_css(expr, QuoteKind::None, self.empty_span)
|
||||||
}
|
}
|
||||||
AstSupportsCondition::Declaration { name, value } => {
|
AstSupportsCondition::Declaration { name, value } => {
|
||||||
let old_in_supports_decl = self.flags.in_supports_declaration();
|
let old_in_supports_decl = self.flags.in_supports_declaration();
|
||||||
@ -448,9 +451,9 @@ impl<'a> Visitor<'a> {
|
|||||||
|
|
||||||
let result = format!(
|
let result = format!(
|
||||||
"({}:{}{})",
|
"({}:{}{})",
|
||||||
self.evaluate_to_css(name, QuoteKind::Quoted, self.span_before)?,
|
self.evaluate_to_css(name, QuoteKind::Quoted, self.empty_span)?,
|
||||||
if is_custom_property { "" } else { " " },
|
if is_custom_property { "" } else { " " },
|
||||||
self.evaluate_to_css(value, QuoteKind::Quoted, self.span_before)?,
|
self.evaluate_to_css(value, QuoteKind::Quoted, self.empty_span)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.flags
|
self.flags
|
||||||
@ -578,7 +581,7 @@ impl<'a> Visitor<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let env = Environment::new();
|
let env = Environment::new();
|
||||||
let mut extension_store = ExtensionStore::new(self.span_before);
|
let mut extension_store = ExtensionStore::new(self.empty_span);
|
||||||
|
|
||||||
self.with_environment::<SassResult<()>, _>(env.new_closure(), |visitor| {
|
self.with_environment::<SassResult<()>, _>(env.new_closure(), |visitor| {
|
||||||
let old_parent = visitor.parent;
|
let old_parent = visitor.parent;
|
||||||
@ -795,7 +798,7 @@ impl<'a> Visitor<'a> {
|
|||||||
/// <https://sass-lang.com/documentation/at-rules/import#finding-the-file>
|
/// <https://sass-lang.com/documentation/at-rules/import#finding-the-file>
|
||||||
/// <https://sass-lang.com/documentation/at-rules/import#load-paths>
|
/// <https://sass-lang.com/documentation/at-rules/import#load-paths>
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
fn find_import(&self, path: &Path) -> Option<PathBuf> {
|
pub fn find_import(&self, path: &Path) -> Option<PathBuf> {
|
||||||
let path_buf = if path.is_absolute() {
|
let path_buf = if path.is_absolute() {
|
||||||
path.into()
|
path.into()
|
||||||
} else {
|
} else {
|
||||||
@ -869,17 +872,17 @@ impl<'a> Visitor<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
lexer: Lexer,
|
lexer: Lexer,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
span_before: Span,
|
empty_span: Span,
|
||||||
) -> SassResult<StyleSheet> {
|
) -> SassResult<StyleSheet> {
|
||||||
match InputSyntax::for_path(path) {
|
match InputSyntax::for_path(path) {
|
||||||
InputSyntax::Scss => {
|
InputSyntax::Scss => {
|
||||||
ScssParser::new(lexer, self.map, self.options, span_before, path).__parse()
|
ScssParser::new(lexer, self.map, self.options, empty_span, path).__parse()
|
||||||
}
|
}
|
||||||
InputSyntax::Sass => {
|
InputSyntax::Sass => {
|
||||||
SassParser::new(lexer, self.map, self.options, span_before, path).__parse()
|
SassParser::new(lexer, self.map, self.options, empty_span, path).__parse()
|
||||||
}
|
}
|
||||||
InputSyntax::Css => {
|
InputSyntax::Css => {
|
||||||
CssParser::new(lexer, self.map, self.options, span_before, path).__parse()
|
CssParser::new(lexer, self.map, self.options, empty_span, path).__parse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -988,7 +991,7 @@ impl<'a> Visitor<'a> {
|
|||||||
// Create a dummy module with empty CSS and no extensions to make forwarded
|
// Create a dummy module with empty CSS and no extensions to make forwarded
|
||||||
// members available in the current import context and to combine all the
|
// members available in the current import context and to combine all the
|
||||||
// CSS from modules used by [stylesheet].
|
// CSS from modules used by [stylesheet].
|
||||||
let module = env.to_dummy_module(self.span_before);
|
let module = env.to_dummy_module(self.empty_span);
|
||||||
self.env.import_forwards(module);
|
self.env.import_forwards(module);
|
||||||
|
|
||||||
if loads_user_defined_modules {
|
if loads_user_defined_modules {
|
||||||
@ -2096,7 +2099,7 @@ impl<'a> Visitor<'a> {
|
|||||||
// todo: emit warning. we don't currently because it can be quite loud
|
// todo: emit warning. we don't currently because it can be quite loud
|
||||||
// self.emit_warning(
|
// self.emit_warning(
|
||||||
// Cow::Borrowed("Using / for division is deprecated and will be removed at some point in the future"),
|
// Cow::Borrowed("Using / for division is deprecated and will be removed at some point in the future"),
|
||||||
// self.span_before,
|
// self.empty_span,
|
||||||
// );
|
// );
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -2567,7 +2570,7 @@ impl<'a> Visitor<'a> {
|
|||||||
AstExpr::True => Value::True,
|
AstExpr::True => Value::True,
|
||||||
AstExpr::False => Value::False,
|
AstExpr::False => Value::False,
|
||||||
AstExpr::Calculation { name, args } => {
|
AstExpr::Calculation { name, args } => {
|
||||||
self.visit_calculation_expr(name, args, self.span_before)?
|
self.visit_calculation_expr(name, args, self.empty_span)?
|
||||||
}
|
}
|
||||||
AstExpr::FunctionCall(func_call) => self.visit_function_call_expr(func_call)?,
|
AstExpr::FunctionCall(func_call) => self.visit_function_call_expr(func_call)?,
|
||||||
AstExpr::If(if_expr) => self.visit_ternary((*if_expr).clone())?,
|
AstExpr::If(if_expr) => self.visit_ternary((*if_expr).clone())?,
|
||||||
|
@ -84,6 +84,7 @@ grass input.scss
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use parse::{CssParser, SassParser, StylesheetParser};
|
use parse::{CssParser, SassParser, StylesheetParser};
|
||||||
|
use sass_ast::StyleSheet;
|
||||||
use serializer::Serializer;
|
use serializer::Serializer;
|
||||||
#[cfg(feature = "wasm-exports")]
|
#[cfg(feature = "wasm-exports")]
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
@ -112,6 +113,12 @@ pub mod sass_value {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod sass_ast {
|
||||||
|
pub use crate::ast::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use codemap;
|
||||||
|
|
||||||
mod ast;
|
mod ast;
|
||||||
mod builtin;
|
mod builtin;
|
||||||
mod color;
|
mod color;
|
||||||
@ -135,6 +142,42 @@ fn raw_to_parse_error(map: &CodeMap, err: Error, unicode: bool) -> Box<Error> {
|
|||||||
Box::new(Error::from_loc(message, map.look_up_span(span), unicode))
|
Box::new(Error::from_loc(message, map.look_up_span(span), unicode))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_stylesheet<P: AsRef<Path>>(
|
||||||
|
input: String,
|
||||||
|
file_name: P,
|
||||||
|
options: &Options,
|
||||||
|
) -> Result<StyleSheet> {
|
||||||
|
// todo: much of this logic is duplicated in `from_string_with_file_name`
|
||||||
|
let mut map = CodeMap::new();
|
||||||
|
let path = file_name.as_ref();
|
||||||
|
let file = map.add_file(path.to_string_lossy().into_owned(), input);
|
||||||
|
let empty_span = file.span.subspan(0, 0);
|
||||||
|
let lexer = Lexer::new_from_file(&file);
|
||||||
|
|
||||||
|
let input_syntax = options
|
||||||
|
.input_syntax
|
||||||
|
.unwrap_or_else(|| InputSyntax::for_path(path));
|
||||||
|
|
||||||
|
let stylesheet = match input_syntax {
|
||||||
|
InputSyntax::Scss => {
|
||||||
|
ScssParser::new(lexer, &mut map, options, empty_span, file_name.as_ref()).__parse()
|
||||||
|
}
|
||||||
|
InputSyntax::Sass => {
|
||||||
|
SassParser::new(lexer, &mut map, options, empty_span, file_name.as_ref()).__parse()
|
||||||
|
}
|
||||||
|
InputSyntax::Css => {
|
||||||
|
CssParser::new(lexer, &mut map, options, empty_span, file_name.as_ref()).__parse()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let stylesheet = match stylesheet {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => return Err(raw_to_parse_error(&map, *e, options.unicode_error_messages)),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(stylesheet)
|
||||||
|
}
|
||||||
|
|
||||||
fn from_string_with_file_name<P: AsRef<Path>>(
|
fn from_string_with_file_name<P: AsRef<Path>>(
|
||||||
input: String,
|
input: String,
|
||||||
file_name: P,
|
file_name: P,
|
||||||
|
@ -191,7 +191,12 @@ pub enum InputSyntax {
|
|||||||
|
|
||||||
impl InputSyntax {
|
impl InputSyntax {
|
||||||
pub(crate) fn for_path(path: &Path) -> Self {
|
pub(crate) fn for_path(path: &Path) -> Self {
|
||||||
match path.extension().and_then(|ext| ext.to_str()) {
|
match path
|
||||||
|
.extension()
|
||||||
|
.and_then(|ext| ext.to_str())
|
||||||
|
.map(str::to_ascii_lowercase)
|
||||||
|
.as_deref()
|
||||||
|
{
|
||||||
Some("css") => Self::Css,
|
Some("css") => Self::Css,
|
||||||
Some("sass") => Self::Sass,
|
Some("sass") => Self::Sass,
|
||||||
_ => Self::Scss,
|
_ => Self::Scss,
|
||||||
|
@ -14,7 +14,7 @@ pub(crate) struct CssParser<'a> {
|
|||||||
// todo: likely superfluous
|
// todo: likely superfluous
|
||||||
pub map: &'a mut CodeMap,
|
pub map: &'a mut CodeMap,
|
||||||
pub path: &'a Path,
|
pub path: &'a Path,
|
||||||
pub span_before: Span,
|
pub empty_span: Span,
|
||||||
pub flags: ContextFlags,
|
pub flags: ContextFlags,
|
||||||
pub options: &'a Options<'a>,
|
pub options: &'a Options<'a>,
|
||||||
}
|
}
|
||||||
@ -70,8 +70,8 @@ impl<'a> StylesheetParser<'a> for CssParser<'a> {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn span_before(&self) -> Span {
|
fn empty_span(&self) -> Span {
|
||||||
self.span_before
|
self.empty_span
|
||||||
}
|
}
|
||||||
|
|
||||||
const IDENTIFIER_LIKE: Option<fn(&mut Self) -> SassResult<Spanned<AstExpr>>> =
|
const IDENTIFIER_LIKE: Option<fn(&mut Self) -> SassResult<Spanned<AstExpr>>> =
|
||||||
@ -112,14 +112,14 @@ impl<'a> CssParser<'a> {
|
|||||||
toks: Lexer<'a>,
|
toks: Lexer<'a>,
|
||||||
map: &'a mut CodeMap,
|
map: &'a mut CodeMap,
|
||||||
options: &'a Options<'a>,
|
options: &'a Options<'a>,
|
||||||
span_before: Span,
|
empty_span: Span,
|
||||||
file_name: &'a Path,
|
file_name: &'a Path,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
CssParser {
|
CssParser {
|
||||||
toks,
|
toks,
|
||||||
map,
|
map,
|
||||||
path: file_name,
|
path: file_name,
|
||||||
span_before,
|
empty_span,
|
||||||
flags: ContextFlags::empty(),
|
flags: ContextFlags::empty(),
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ pub(crate) struct SassParser<'a> {
|
|||||||
// todo: likely superfluous
|
// todo: likely superfluous
|
||||||
pub map: &'a mut CodeMap,
|
pub map: &'a mut CodeMap,
|
||||||
pub path: &'a Path,
|
pub path: &'a Path,
|
||||||
pub span_before: Span,
|
pub empty_span: Span,
|
||||||
pub flags: ContextFlags,
|
pub flags: ContextFlags,
|
||||||
pub options: &'a Options<'a>,
|
pub options: &'a Options<'a>,
|
||||||
pub current_indentation: usize,
|
pub current_indentation: usize,
|
||||||
@ -103,8 +103,8 @@ impl<'a> StylesheetParser<'a> for SassParser<'a> {
|
|||||||
self.current_indentation
|
self.current_indentation
|
||||||
}
|
}
|
||||||
|
|
||||||
fn span_before(&self) -> Span {
|
fn empty_span(&self) -> Span {
|
||||||
self.span_before
|
self.empty_span
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_style_rule_selector(&mut self) -> SassResult<Interpolation> {
|
fn parse_style_rule_selector(&mut self) -> SassResult<Interpolation> {
|
||||||
@ -353,7 +353,7 @@ impl<'a> SassParser<'a> {
|
|||||||
toks: Lexer<'a>,
|
toks: Lexer<'a>,
|
||||||
map: &'a mut CodeMap,
|
map: &'a mut CodeMap,
|
||||||
options: &'a Options<'a>,
|
options: &'a Options<'a>,
|
||||||
span_before: Span,
|
empty_span: Span,
|
||||||
file_name: &'a Path,
|
file_name: &'a Path,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut flags = ContextFlags::empty();
|
let mut flags = ContextFlags::empty();
|
||||||
@ -364,7 +364,7 @@ impl<'a> SassParser<'a> {
|
|||||||
toks,
|
toks,
|
||||||
map,
|
map,
|
||||||
path: file_name,
|
path: file_name,
|
||||||
span_before,
|
empty_span,
|
||||||
flags,
|
flags,
|
||||||
options,
|
options,
|
||||||
current_indentation: 0,
|
current_indentation: 0,
|
||||||
|
@ -11,7 +11,7 @@ pub(crate) struct ScssParser<'a> {
|
|||||||
// todo: likely superfluous
|
// todo: likely superfluous
|
||||||
pub map: &'a mut CodeMap,
|
pub map: &'a mut CodeMap,
|
||||||
pub path: &'a Path,
|
pub path: &'a Path,
|
||||||
pub span_before: Span,
|
pub empty_span: Span,
|
||||||
pub flags: ContextFlags,
|
pub flags: ContextFlags,
|
||||||
pub options: &'a Options<'a>,
|
pub options: &'a Options<'a>,
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ impl<'a> ScssParser<'a> {
|
|||||||
toks: Lexer<'a>,
|
toks: Lexer<'a>,
|
||||||
map: &'a mut CodeMap,
|
map: &'a mut CodeMap,
|
||||||
options: &'a Options<'a>,
|
options: &'a Options<'a>,
|
||||||
span_before: Span,
|
empty_span: Span,
|
||||||
file_name: &'a Path,
|
file_name: &'a Path,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut flags = ContextFlags::empty();
|
let mut flags = ContextFlags::empty();
|
||||||
@ -32,7 +32,7 @@ impl<'a> ScssParser<'a> {
|
|||||||
toks,
|
toks,
|
||||||
map,
|
map,
|
||||||
path: file_name,
|
path: file_name,
|
||||||
span_before,
|
empty_span,
|
||||||
flags,
|
flags,
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ impl<'a> StylesheetParser<'a> for ScssParser<'a> {
|
|||||||
&mut self.flags
|
&mut self.flags
|
||||||
}
|
}
|
||||||
|
|
||||||
fn span_before(&self) -> Span {
|
fn empty_span(&self) -> Span {
|
||||||
self.span_before
|
self.empty_span
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ pub(crate) trait StylesheetParser<'a>: BaseParser<'a> + Sized {
|
|||||||
fn options(&self) -> &Options;
|
fn options(&self) -> &Options;
|
||||||
fn path(&self) -> &Path;
|
fn path(&self) -> &Path;
|
||||||
fn map(&mut self) -> &mut CodeMap;
|
fn map(&mut self) -> &mut CodeMap;
|
||||||
fn span_before(&self) -> Span;
|
fn empty_span(&self) -> Span;
|
||||||
fn current_indentation(&self) -> usize;
|
fn current_indentation(&self) -> usize;
|
||||||
fn flags(&self) -> &ContextFlags;
|
fn flags(&self) -> &ContextFlags;
|
||||||
fn flags_mut(&mut self) -> &mut ContextFlags;
|
fn flags_mut(&mut self) -> &mut ContextFlags;
|
||||||
@ -184,6 +184,7 @@ pub(crate) trait StylesheetParser<'a>: BaseParser<'a> + Sized {
|
|||||||
Ok(stmts)
|
Ok(stmts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: rename
|
||||||
fn __parse(&mut self) -> SassResult<StyleSheet> {
|
fn __parse(&mut self) -> SassResult<StyleSheet> {
|
||||||
let mut style_sheet = StyleSheet::new(
|
let mut style_sheet = StyleSheet::new(
|
||||||
self.is_plain_css(),
|
self.is_plain_css(),
|
||||||
@ -758,8 +759,7 @@ pub(crate) trait StylesheetParser<'a>: BaseParser<'a> + Sized {
|
|||||||
buffer.add_char('(');
|
buffer.add_char('(');
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer
|
buffer.add_expr(AstExpr::Supports(Arc::new(query)).span(self.empty_span()));
|
||||||
.add_expr(AstExpr::Supports(Arc::new(query)).span(self.span_before()));
|
|
||||||
|
|
||||||
if !is_declaration {
|
if !is_declaration {
|
||||||
buffer.add_char(')');
|
buffer.add_char(')');
|
||||||
@ -1552,7 +1552,7 @@ pub(crate) trait StylesheetParser<'a>: BaseParser<'a> + Sized {
|
|||||||
// if namespace is empty, avoid attempting to parse an identifier from
|
// if namespace is empty, avoid attempting to parse an identifier from
|
||||||
// an empty string, as there will be no span to emit
|
// an empty string, as there will be no span to emit
|
||||||
let identifier = if namespace.is_empty() {
|
let identifier = if namespace.is_empty() {
|
||||||
Err(("", self.span_before()).into())
|
Err(("", self.empty_span()).into())
|
||||||
} else {
|
} else {
|
||||||
mem::swap(self.toks_mut(), &mut toks);
|
mem::swap(self.toks_mut(), &mut toks);
|
||||||
let ident = self.parse_identifier(false, false);
|
let ident = self.parse_identifier(false, false);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user