fail on modifier with attrkind any
This commit is contained in:
parent
6e8c226834
commit
476578cdc6
@ -5,7 +5,7 @@ use std::string::ToString;
|
|||||||
use super::{Selector, SelectorKind};
|
use super::{Selector, SelectorKind};
|
||||||
use crate::error::SassResult;
|
use crate::error::SassResult;
|
||||||
use crate::scope::Scope;
|
use crate::scope::Scope;
|
||||||
use crate::utils::{devour_whitespace, eat_ident, parse_interpolation, parse_quoted_string};
|
use crate::utils::{devour_whitespace, eat_ident, parse_interpolation, parse_quoted_string, is_ident_char};
|
||||||
use crate::Token;
|
use crate::Token;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
@ -23,12 +23,17 @@ impl Attribute {
|
|||||||
super_selector: &Selector,
|
super_selector: &Selector,
|
||||||
) -> SassResult<SelectorKind> {
|
) -> SassResult<SelectorKind> {
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
let attr = match toks.next().ok_or("Expected identifier.")?.kind {
|
let attr = match toks.peek().ok_or("Expected identifier.")?.kind {
|
||||||
v @ 'a'..='z' | v @ 'A'..='Z' | v @ '-' | v @ '_' => {
|
c if is_ident_char(c) => {
|
||||||
format!("{}{}", v, eat_ident(toks, scope, super_selector)?)
|
eat_ident(toks, scope, super_selector)?
|
||||||
}
|
}
|
||||||
'#' if toks.next().ok_or("Expected expression.")?.kind == '{' => {
|
'#' => {
|
||||||
|
toks.next();
|
||||||
|
if toks.next().ok_or("Expected expression.")?.kind == '{' {
|
||||||
parse_interpolation(toks, scope, super_selector)?.to_string()
|
parse_interpolation(toks, scope, super_selector)?.to_string()
|
||||||
|
} else {
|
||||||
|
return Err("Expected expression.".into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
q @ '"' | q @ '\'' => parse_quoted_string(toks, scope, q, super_selector)?.to_string(),
|
q @ '"' | q @ '\'' => parse_quoted_string(toks, scope, q, super_selector)?.to_string(),
|
||||||
_ => return Err("Expected identifier.".into()),
|
_ => return Err("Expected identifier.".into()),
|
||||||
@ -37,18 +42,7 @@ impl Attribute {
|
|||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
|
|
||||||
let kind = match toks.next().ok_or("expected \"{\".")?.kind {
|
let kind = match toks.next().ok_or("expected \"{\".")?.kind {
|
||||||
v @ 'a'..='z' | v @ 'A'..='Z' => {
|
c if is_ident_char(c) => return Err("expected \"]\".".into()),
|
||||||
match toks.next().ok_or("expected \"]\".")?.kind {
|
|
||||||
']' => {}
|
|
||||||
_ => return Err("expected \"]\".".into()),
|
|
||||||
}
|
|
||||||
return Ok(SelectorKind::Attribute(Attribute {
|
|
||||||
kind: AttributeKind::Any,
|
|
||||||
attr,
|
|
||||||
value: String::new(),
|
|
||||||
modifier: Some(v),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
']' => {
|
']' => {
|
||||||
return Ok(SelectorKind::Attribute(Attribute {
|
return Ok(SelectorKind::Attribute(Attribute {
|
||||||
kind: AttributeKind::Any,
|
kind: AttributeKind::Any,
|
||||||
@ -63,7 +57,7 @@ impl Attribute {
|
|||||||
'^' => AttributeKind::Prefix,
|
'^' => AttributeKind::Prefix,
|
||||||
'$' => AttributeKind::Suffix,
|
'$' => AttributeKind::Suffix,
|
||||||
'*' => AttributeKind::Contains,
|
'*' => AttributeKind::Contains,
|
||||||
_ => return Err("Expected \"]\".".into()),
|
_ => return Err("expected \"]\".".into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if kind != AttributeKind::Equals {
|
if kind != AttributeKind::Equals {
|
||||||
@ -101,7 +95,7 @@ impl Attribute {
|
|||||||
}
|
}
|
||||||
Some(v)
|
Some(v)
|
||||||
}
|
}
|
||||||
_ => return Err("Expected \"]\".".into()),
|
_ => return Err("expected \"]\".".into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(SelectorKind::Attribute(Attribute {
|
Ok(SelectorKind::Attribute(Attribute {
|
||||||
|
@ -702,3 +702,7 @@ pub(crate) fn read_until_char<I: Iterator<Item = Token>>(
|
|||||||
}
|
}
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_ident_char(c: char) -> bool {
|
||||||
|
c.is_ascii_alphabetic() || c == '_' || c == '\\' || (!c.is_ascii() && !c.is_control())
|
||||||
|
}
|
||||||
|
@ -318,3 +318,8 @@ test!(
|
|||||||
test!(escaped_space, "a\\ b {\n color: foo;\n}\n");
|
test!(escaped_space, "a\\ b {\n color: foo;\n}\n");
|
||||||
// blocked on whitespace
|
// blocked on whitespace
|
||||||
// test!(multiple_consecutive_immediate_child,"> > foo {\n color: foo;\n}\n",);
|
// test!(multiple_consecutive_immediate_child,"> > foo {\n color: foo;\n}\n",);
|
||||||
|
error!(
|
||||||
|
modifier_on_any_attr,
|
||||||
|
"[attr i] {color: foo;}",
|
||||||
|
"Error: expected \"]\"."
|
||||||
|
);
|
Loading…
x
Reference in New Issue
Block a user