add more span information
this resolves a lot of panics that occurred when there was no more input
This commit is contained in:
parent
6e7f1cc319
commit
b58ed29fd0
@ -221,7 +221,7 @@ pub(crate) fn eat_func_args<I: Iterator<Item = Token>>(
|
|||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
while let Some(Token { kind, pos }) = toks.next() {
|
while let Some(Token { kind, pos }) = toks.next() {
|
||||||
let name = match kind {
|
let name = match kind {
|
||||||
'$' => eat_ident(toks, scope, super_selector)?,
|
'$' => eat_ident(toks, scope, super_selector, pos)?,
|
||||||
')' => {
|
')' => {
|
||||||
close_paren_span = pos;
|
close_paren_span = pos;
|
||||||
break;
|
break;
|
||||||
|
@ -98,7 +98,7 @@ pub(crate) fn parse_each<I: Iterator<Item = Token>>(
|
|||||||
let next = toks.next().ok_or(("expected \"$\".", span))?;
|
let next = toks.next().ok_or(("expected \"$\".", span))?;
|
||||||
span = next.pos();
|
span = next.pos();
|
||||||
match next.kind {
|
match next.kind {
|
||||||
'$' => vars.push(eat_ident(toks, scope, super_selector)?),
|
'$' => vars.push(eat_ident(toks, scope, super_selector, next.pos)?),
|
||||||
_ => return Err(("expected \"$\".", next.pos()).into()),
|
_ => return Err(("expected \"$\".", next.pos()).into()),
|
||||||
}
|
}
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
@ -114,10 +114,7 @@ pub(crate) fn parse_each<I: Iterator<Item = Token>>(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if toks.peek().is_none() {
|
let i = eat_ident(toks, scope, super_selector, span)?;
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
let i = eat_ident(toks, scope, super_selector)?;
|
|
||||||
if i.node.to_ascii_lowercase() != "in" {
|
if i.node.to_ascii_lowercase() != "in" {
|
||||||
return Err(("Expected \"in\".", i.span).into());
|
return Err(("Expected \"in\".", i.span).into());
|
||||||
}
|
}
|
||||||
|
@ -89,14 +89,17 @@ pub(crate) fn parse_for<I: Iterator<Item = Token>>(
|
|||||||
span: Span,
|
span: Span,
|
||||||
) -> SassResult<AtRule> {
|
) -> SassResult<AtRule> {
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let var = match toks.next().ok_or(("expected \"$\".", span))?.kind {
|
let next = toks.next().ok_or(("expected \"$\".", span))?;
|
||||||
'$' => eat_ident(toks, scope, super_selector)?,
|
let var = match next.kind {
|
||||||
|
'$' => eat_ident(toks, scope, super_selector, next.pos)?,
|
||||||
_ => return Err(("expected \"$\".", span).into()),
|
_ => return Err(("expected \"$\".", span).into()),
|
||||||
};
|
};
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
if toks.peek().is_none()
|
if toks.peek().is_none() {
|
||||||
|| eat_ident(toks, scope, super_selector)?.to_ascii_lowercase() != "from"
|
return Err(("Expected \"from\".", var.span).into());
|
||||||
{
|
}
|
||||||
|
let span_before = toks.peek().unwrap().pos;
|
||||||
|
if eat_ident(toks, scope, super_selector, span_before)?.to_ascii_lowercase() != "from" {
|
||||||
return Err(("Expected \"from\".", var.span).into());
|
return Err(("Expected \"from\".", var.span).into());
|
||||||
}
|
}
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
|
@ -44,8 +44,9 @@ impl Function {
|
|||||||
toks: &mut PeekMoreIterator<I>,
|
toks: &mut PeekMoreIterator<I>,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
super_selector: &Selector,
|
super_selector: &Selector,
|
||||||
|
span_before: Span,
|
||||||
) -> SassResult<(String, Function)> {
|
) -> SassResult<(String, Function)> {
|
||||||
let Spanned { node: name, span } = eat_ident(toks, &scope, super_selector)?;
|
let Spanned { node: name, span } = eat_ident(toks, &scope, super_selector, span_before)?;
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let args = match toks.next() {
|
let args = match toks.next() {
|
||||||
Some(Token { kind: '(', .. }) => eat_func_args(toks, &scope, super_selector)?,
|
Some(Token { kind: '(', .. }) => eat_func_args(toks, &scope, super_selector)?,
|
||||||
|
@ -57,11 +57,13 @@ impl If {
|
|||||||
if first_char != 'e' && first_char != 'E' {
|
if first_char != 'e' && first_char != 'E' {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
toks.next();
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if eat_ident(toks, &Scope::new(), &Selector::new())?.to_ascii_lowercase() == "else"
|
let span_before = toks.next().unwrap().pos;
|
||||||
|
if eat_ident(toks, &Scope::new(), &Selector::new(), span_before)?
|
||||||
|
.to_ascii_lowercase()
|
||||||
|
== "else"
|
||||||
{
|
{
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
if let Some(tok) = toks.next() {
|
if let Some(tok) = toks.next() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
|
|
||||||
use codemap::Spanned;
|
use codemap::{Span, Spanned};
|
||||||
|
|
||||||
use peekmore::{PeekMore, PeekMoreIterator};
|
use peekmore::{PeekMore, PeekMoreIterator};
|
||||||
|
|
||||||
@ -34,9 +34,10 @@ impl Mixin {
|
|||||||
toks: &mut PeekMoreIterator<I>,
|
toks: &mut PeekMoreIterator<I>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
super_selector: &Selector,
|
super_selector: &Selector,
|
||||||
|
span_before: Span,
|
||||||
) -> SassResult<Spanned<(String, Mixin)>> {
|
) -> SassResult<Spanned<(String, Mixin)>> {
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let Spanned { node: name, span } = eat_ident(toks, scope, super_selector)?;
|
let Spanned { node: name, span } = eat_ident(toks, scope, super_selector, span_before)?;
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let args = match toks.next() {
|
let args = match toks.next() {
|
||||||
Some(Token { kind: '(', .. }) => eat_func_args(toks, scope, super_selector)?,
|
Some(Token { kind: '(', .. }) => eat_func_args(toks, scope, super_selector)?,
|
||||||
@ -185,9 +186,10 @@ pub(crate) fn eat_include<I: Iterator<Item = Token>>(
|
|||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
super_selector: &Selector,
|
super_selector: &Selector,
|
||||||
content: Option<&[Spanned<Stmt>]>,
|
content: Option<&[Spanned<Stmt>]>,
|
||||||
|
span_before: Span,
|
||||||
) -> SassResult<Vec<Spanned<Stmt>>> {
|
) -> SassResult<Vec<Spanned<Stmt>>> {
|
||||||
devour_whitespace_or_comment(toks)?;
|
devour_whitespace_or_comment(toks)?;
|
||||||
let name = eat_ident(toks, scope, super_selector)?;
|
let name = eat_ident(toks, scope, super_selector, span_before)?;
|
||||||
|
|
||||||
devour_whitespace_or_comment(toks)?;
|
devour_whitespace_or_comment(toks)?;
|
||||||
|
|
||||||
|
@ -121,14 +121,15 @@ impl AtRule {
|
|||||||
let Spanned {
|
let Spanned {
|
||||||
node: (name, mixin),
|
node: (name, mixin),
|
||||||
span,
|
span,
|
||||||
} = Mixin::decl_from_tokens(toks, scope, super_selector)?;
|
} = Mixin::decl_from_tokens(toks, scope, super_selector, kind_span)?;
|
||||||
Spanned {
|
Spanned {
|
||||||
node: AtRule::Mixin(name, Box::new(mixin)),
|
node: AtRule::Mixin(name, Box::new(mixin)),
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AtRuleKind::Function => {
|
AtRuleKind::Function => {
|
||||||
let (name, func) = Function::decl_from_tokens(toks, scope.clone(), super_selector)?;
|
let (name, func) =
|
||||||
|
Function::decl_from_tokens(toks, scope.clone(), super_selector, kind_span)?;
|
||||||
Spanned {
|
Spanned {
|
||||||
node: AtRule::Function(name, Box::new(func)),
|
node: AtRule::Function(name, Box::new(func)),
|
||||||
span: kind_span,
|
span: kind_span,
|
||||||
@ -236,7 +237,13 @@ impl AtRule {
|
|||||||
span: kind_span,
|
span: kind_span,
|
||||||
},
|
},
|
||||||
AtRuleKind::Include => Spanned {
|
AtRuleKind::Include => Spanned {
|
||||||
node: AtRule::Include(eat_include(toks, scope, super_selector, content)?),
|
node: AtRule::Include(eat_include(
|
||||||
|
toks,
|
||||||
|
scope,
|
||||||
|
super_selector,
|
||||||
|
content,
|
||||||
|
kind_span,
|
||||||
|
)?),
|
||||||
span: kind_span,
|
span: kind_span,
|
||||||
},
|
},
|
||||||
AtRuleKind::Import => todo!("@import not yet implemented"),
|
AtRuleKind::Import => todo!("@import not yet implemented"),
|
||||||
|
25
src/lib.rs
25
src/lib.rs
@ -197,6 +197,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
|
|||||||
scope,
|
scope,
|
||||||
super_selector,
|
super_selector,
|
||||||
String::new(),
|
String::new(),
|
||||||
|
tok.unwrap().pos,
|
||||||
)?;
|
)?;
|
||||||
return Ok(Some(Spanned {
|
return Ok(Some(Spanned {
|
||||||
node: Style::from_tokens(toks, scope, super_selector, prop)?,
|
node: Style::from_tokens(toks, scope, super_selector, prop)?,
|
||||||
@ -207,7 +208,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
';' => {
|
';' => {
|
||||||
toks.next();
|
let span_before = toks.next().unwrap().pos;
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
// special edge case where there was no space between the colon
|
// special edge case where there was no space between the colon
|
||||||
// in a style, e.g. `color:red`. todo: refactor
|
// in a style, e.g. `color:red`. todo: refactor
|
||||||
@ -223,7 +224,13 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
|
|||||||
span,
|
span,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
let property = Style::parse_property(&mut v, scope, super_selector, String::new())?;
|
let property = Style::parse_property(
|
||||||
|
&mut v,
|
||||||
|
scope,
|
||||||
|
super_selector,
|
||||||
|
String::new(),
|
||||||
|
span_before,
|
||||||
|
)?;
|
||||||
let value = Style::parse_value(&mut v, scope, super_selector)?;
|
let value = Style::parse_value(&mut v, scope, super_selector)?;
|
||||||
return Ok(Some(Spanned {
|
return Ok(Some(Spanned {
|
||||||
node: Expr::Style(Box::new(Style { property, value })),
|
node: Expr::Style(Box::new(Style { property, value })),
|
||||||
@ -244,8 +251,13 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
|
|||||||
// and no semicolon following the style
|
// and no semicolon following the style
|
||||||
// in a style `color:red`. todo: refactor
|
// in a style `color:red`. todo: refactor
|
||||||
let mut v = values.into_iter().peekmore();
|
let mut v = values.into_iter().peekmore();
|
||||||
let property =
|
let property = Style::parse_property(
|
||||||
Style::parse_property(&mut v, scope, super_selector, String::new())?;
|
&mut v,
|
||||||
|
scope,
|
||||||
|
super_selector,
|
||||||
|
String::new(),
|
||||||
|
tok.pos,
|
||||||
|
)?;
|
||||||
let value = Style::parse_value(&mut v, scope, super_selector)?;
|
let value = Style::parse_value(&mut v, scope, super_selector)?;
|
||||||
return Ok(Some(Spanned {
|
return Ok(Some(Spanned {
|
||||||
node: Expr::Style(Box::new(Style { property, value })),
|
node: Expr::Style(Box::new(Style { property, value })),
|
||||||
@ -327,10 +339,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
|
|||||||
}
|
}
|
||||||
'@' => {
|
'@' => {
|
||||||
let span = toks.next().unwrap().pos();
|
let span = toks.next().unwrap().pos();
|
||||||
if toks.peek().is_none() {
|
let Spanned { node: ident, span } = eat_ident(toks, scope, super_selector, span)?;
|
||||||
return Err(("Expected identifier.", span).into());
|
|
||||||
}
|
|
||||||
let Spanned { node: ident, span } = eat_ident(toks, scope, super_selector)?;
|
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let rule = AtRule::from_tokens(
|
let rule = AtRule::from_tokens(
|
||||||
&AtRuleKind::from(ident.as_str()),
|
&AtRuleKind::from(ident.as_str()),
|
||||||
|
@ -35,15 +35,16 @@ fn attribute_name<I: Iterator<Item = Token>>(
|
|||||||
return Err(("expected \"|\".", pos).into());
|
return Err(("expected \"|\".", pos).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
toks.next();
|
let span_before = toks.next().unwrap().pos();
|
||||||
|
|
||||||
let ident = eat_ident(toks, scope, super_selector)?.node;
|
let ident = eat_ident(toks, scope, super_selector, span_before)?.node;
|
||||||
return Ok(QualifiedName {
|
return Ok(QualifiedName {
|
||||||
ident,
|
ident,
|
||||||
namespace: Some('*'.to_string()),
|
namespace: Some('*'.to_string()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let name_or_namespace = eat_ident(toks, scope, super_selector)?;
|
let span_before = next.pos;
|
||||||
|
let name_or_namespace = eat_ident(toks, scope, super_selector, span_before)?;
|
||||||
match toks.peek() {
|
match toks.peek() {
|
||||||
Some(v) if v.kind != '|' => {
|
Some(v) if v.kind != '|' => {
|
||||||
return Ok(QualifiedName {
|
return Ok(QualifiedName {
|
||||||
@ -67,8 +68,8 @@ fn attribute_name<I: Iterator<Item = Token>>(
|
|||||||
}
|
}
|
||||||
None => return Err(("expected more input.", name_or_namespace.span).into()),
|
None => return Err(("expected more input.", name_or_namespace.span).into()),
|
||||||
}
|
}
|
||||||
toks.next();
|
let span_before = toks.next().unwrap().pos();
|
||||||
let ident = eat_ident(toks, scope, super_selector)?.node;
|
let ident = eat_ident(toks, scope, super_selector, span_before)?.node;
|
||||||
Ok(QualifiedName {
|
Ok(QualifiedName {
|
||||||
ident,
|
ident,
|
||||||
namespace: Some(name_or_namespace.node),
|
namespace: Some(name_or_namespace.node),
|
||||||
@ -118,7 +119,7 @@ impl Attribute {
|
|||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
|
|
||||||
let peek = toks.peek().ok_or(("expected more input.", start))?;
|
let peek = toks.peek().ok_or(("expected more input.", start))?;
|
||||||
|
let span_before = peek.pos;
|
||||||
let value = match peek.kind {
|
let value = match peek.kind {
|
||||||
q @ '\'' | q @ '"' => {
|
q @ '\'' | q @ '"' => {
|
||||||
toks.next();
|
toks.next();
|
||||||
@ -127,7 +128,7 @@ impl Attribute {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => eat_ident(toks, scope, super_selector)?.node,
|
_ => eat_ident(toks, scope, super_selector, span_before)?.node,
|
||||||
};
|
};
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
|
|
||||||
|
13
src/style.rs
13
src/style.rs
@ -1,6 +1,6 @@
|
|||||||
use peekmore::PeekMoreIterator;
|
use peekmore::PeekMoreIterator;
|
||||||
|
|
||||||
use codemap::Spanned;
|
use codemap::{Span, Spanned};
|
||||||
|
|
||||||
use crate::error::SassResult;
|
use crate::error::SassResult;
|
||||||
use crate::scope::Scope;
|
use crate::scope::Scope;
|
||||||
@ -22,8 +22,9 @@ impl Style {
|
|||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
super_selector: &Selector,
|
super_selector: &Selector,
|
||||||
super_property: String,
|
super_property: String,
|
||||||
|
span_before: Span,
|
||||||
) -> SassResult<String> {
|
) -> SassResult<String> {
|
||||||
StyleParser::new(scope, super_selector).parse_property(toks, super_property)
|
StyleParser::new(scope, super_selector).parse_property(toks, super_property, span_before)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string(&self) -> SassResult<String> {
|
pub fn to_string(&self) -> SassResult<String> {
|
||||||
@ -95,10 +96,11 @@ impl<'a> StyleParser<'a> {
|
|||||||
while let Some(tok) = toks.peek() {
|
while let Some(tok) = toks.peek() {
|
||||||
match tok.kind {
|
match tok.kind {
|
||||||
'{' => {
|
'{' => {
|
||||||
toks.next();
|
let span_before = toks.next().unwrap().pos;
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
loop {
|
loop {
|
||||||
let property = self.parse_property(toks, super_property.clone())?;
|
let property =
|
||||||
|
self.parse_property(toks, super_property.clone(), span_before)?;
|
||||||
if let Some(tok) = toks.peek() {
|
if let Some(tok) = toks.peek() {
|
||||||
if tok.kind == '{' {
|
if tok.kind == '{' {
|
||||||
match self.eat_style_group(toks, property, scope)? {
|
match self.eat_style_group(toks, property, scope)? {
|
||||||
@ -194,9 +196,10 @@ impl<'a> StyleParser<'a> {
|
|||||||
&self,
|
&self,
|
||||||
toks: &mut PeekMoreIterator<I>,
|
toks: &mut PeekMoreIterator<I>,
|
||||||
mut super_property: String,
|
mut super_property: String,
|
||||||
|
span_before: Span,
|
||||||
) -> SassResult<String> {
|
) -> SassResult<String> {
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let property = eat_ident(toks, self.scope, self.super_selector)?.node;
|
let property = eat_ident(toks, self.scope, self.super_selector, span_before)?.node;
|
||||||
devour_whitespace_or_comment(toks)?;
|
devour_whitespace_or_comment(toks)?;
|
||||||
if toks.peek().is_some() && toks.peek().unwrap().kind == ':' {
|
if toks.peek().is_some() && toks.peek().unwrap().kind == ':' {
|
||||||
toks.next();
|
toks.next();
|
||||||
|
@ -164,8 +164,13 @@ impl<'a> StyleSheetParser<'a> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
'$' => {
|
'$' => {
|
||||||
self.lexer.next();
|
let span_before = self.lexer.next().unwrap().pos();
|
||||||
let name = eat_ident(&mut self.lexer, &Scope::new(), &Selector::new())?;
|
let name = eat_ident(
|
||||||
|
&mut self.lexer,
|
||||||
|
&Scope::new(),
|
||||||
|
&Selector::new(),
|
||||||
|
span_before
|
||||||
|
)?;
|
||||||
devour_whitespace(&mut self.lexer);
|
devour_whitespace(&mut self.lexer);
|
||||||
let Token { kind, pos } = self
|
let Token { kind, pos } = self
|
||||||
.lexer
|
.lexer
|
||||||
@ -194,8 +199,13 @@ impl<'a> StyleSheetParser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
'@' => {
|
'@' => {
|
||||||
self.lexer.next();
|
let span_before = self.lexer.next().unwrap().pos();
|
||||||
let Spanned { node: at_rule_kind, span } = eat_ident(&mut self.lexer, &Scope::new(), &Selector::new())?;
|
let Spanned { node: at_rule_kind, span } = eat_ident(
|
||||||
|
&mut self.lexer,
|
||||||
|
&Scope::new(),
|
||||||
|
&Selector::new(),
|
||||||
|
span_before
|
||||||
|
)?;
|
||||||
if at_rule_kind.is_empty() {
|
if at_rule_kind.is_empty() {
|
||||||
return Err(("Expected identifier.", span).into());
|
return Err(("Expected identifier.", span).into());
|
||||||
}
|
}
|
||||||
@ -205,6 +215,7 @@ impl<'a> StyleSheetParser<'a> {
|
|||||||
&Scope::new(),
|
&Scope::new(),
|
||||||
&Selector::new(),
|
&Selector::new(),
|
||||||
None,
|
None,
|
||||||
|
span
|
||||||
)?),
|
)?),
|
||||||
AtRuleKind::Import => {
|
AtRuleKind::Import => {
|
||||||
devour_whitespace(&mut self.lexer);
|
devour_whitespace(&mut self.lexer);
|
||||||
|
@ -169,9 +169,12 @@ pub(crate) fn eat_ident<I: Iterator<Item = Token>>(
|
|||||||
toks: &mut PeekMoreIterator<I>,
|
toks: &mut PeekMoreIterator<I>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
super_selector: &Selector,
|
super_selector: &Selector,
|
||||||
|
span_before: Span,
|
||||||
) -> SassResult<Spanned<String>> {
|
) -> SassResult<Spanned<String>> {
|
||||||
// TODO: take span as param because we use unwrap here
|
let mut span = toks
|
||||||
let mut span = toks.peek().unwrap().pos();
|
.peek()
|
||||||
|
.ok_or(("Expected identifier.", span_before))?
|
||||||
|
.pos();
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
if toks.peek().unwrap().kind == '-' {
|
if toks.peek().unwrap().kind == '-' {
|
||||||
toks.next();
|
toks.next();
|
||||||
|
@ -52,7 +52,7 @@ fn parse_hex<I: Iterator<Item = Token>>(
|
|||||||
s.push(tok.kind);
|
s.push(tok.kind);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let i = eat_ident(toks, scope, super_selector)?;
|
let i = eat_ident(toks, scope, super_selector, span)?;
|
||||||
if i.node.chars().all(|c| c.is_ascii_hexdigit()) {
|
if i.node.chars().all(|c| c.is_ascii_hexdigit()) {
|
||||||
s = i.node;
|
s = i.node;
|
||||||
span = span.merge(i.span);
|
span = span.merge(i.span);
|
||||||
@ -524,8 +524,9 @@ impl Value {
|
|||||||
toks: &mut PeekMoreIterator<I>,
|
toks: &mut PeekMoreIterator<I>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
super_selector: &Selector,
|
super_selector: &Selector,
|
||||||
|
span_before: Span,
|
||||||
) -> SassResult<IntermediateValue> {
|
) -> SassResult<IntermediateValue> {
|
||||||
let Spanned { node: mut s, span } = eat_ident(toks, scope, super_selector)?;
|
let Spanned { node: mut s, span } = eat_ident(toks, scope, super_selector, span_before)?;
|
||||||
|
|
||||||
let lower = s.to_ascii_lowercase();
|
let lower = s.to_ascii_lowercase();
|
||||||
|
|
||||||
@ -636,7 +637,7 @@ impl Value {
|
|||||||
|| (!kind.is_ascii() && !kind.is_control())
|
|| (!kind.is_ascii() && !kind.is_control())
|
||||||
|| (kind == '-' && next_is_hypen(toks)) =>
|
|| (kind == '-' && next_is_hypen(toks)) =>
|
||||||
{
|
{
|
||||||
return Some(Self::ident(toks, scope, super_selector));
|
return Some(Self::ident(toks, scope, super_selector, span));
|
||||||
}
|
}
|
||||||
'0'..='9' | '.' => {
|
'0'..='9' | '.' => {
|
||||||
let Spanned {
|
let Spanned {
|
||||||
@ -723,9 +724,10 @@ impl Value {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
'#' => {
|
'#' => {
|
||||||
if let Some(Token { kind: '{', .. }) = toks.peek_forward(1) {
|
if let Some(Token { kind: '{', pos }) = toks.peek_forward(1) {
|
||||||
|
let span_before = *pos;
|
||||||
toks.reset_view();
|
toks.reset_view();
|
||||||
return Some(Self::ident(toks, scope, super_selector));
|
return Some(Self::ident(toks, scope, super_selector, span_before));
|
||||||
}
|
}
|
||||||
toks.reset_view();
|
toks.reset_view();
|
||||||
toks.next();
|
toks.next();
|
||||||
@ -847,7 +849,7 @@ impl Value {
|
|||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let v = match eat_ident(toks, scope, super_selector) {
|
let v = match eat_ident(toks, scope, super_selector, span) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => return Some(Err(e)),
|
Err(e) => return Some(Err(e)),
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user