mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 22:31:14 +00:00
Parse @image-url
This commit is contained in:
parent
48b226c017
commit
5debc08f98
4 changed files with 68 additions and 12 deletions
|
@ -197,6 +197,7 @@ fn fill_token_vec(stream: impl Iterator<Item = TokenTree>, vec: &mut Vec<parser:
|
||||||
SyntaxKind::Error
|
SyntaxKind::Error
|
||||||
}
|
}
|
||||||
'$' => SyntaxKind::Dollar,
|
'$' => SyntaxKind::Dollar,
|
||||||
|
'@' => SyntaxKind::At,
|
||||||
_ => SyntaxKind::Error,
|
_ => SyntaxKind::Error,
|
||||||
};
|
};
|
||||||
prev_spacing = p.spacing();
|
prev_spacing = p.spacing();
|
||||||
|
|
|
@ -272,6 +272,7 @@ declare_syntax! {
|
||||||
Dot -> ".",
|
Dot -> ".",
|
||||||
Question -> "?",
|
Question -> "?",
|
||||||
Dollar -> "$",
|
Dollar -> "$",
|
||||||
|
At -> "@",
|
||||||
}
|
}
|
||||||
// syntax kind
|
// syntax kind
|
||||||
{
|
{
|
||||||
|
@ -309,11 +310,13 @@ declare_syntax! {
|
||||||
// FIXME: the test should test that as alternative rather than several of them (but it can also be a literal)
|
// FIXME: the test should test that as alternative rather than several of them (but it can also be a literal)
|
||||||
Expression-> [ ?Expression, ?BangExpression, ?FunctionCallExpression, ?SelfAssignment,
|
Expression-> [ ?Expression, ?BangExpression, ?FunctionCallExpression, ?SelfAssignment,
|
||||||
?ConditionalExpression, ?QualifiedName, ?BinaryExpression, ?Array, ?ObjectLiteral,
|
?ConditionalExpression, ?QualifiedName, ?BinaryExpression, ?Array, ?ObjectLiteral,
|
||||||
?UnaryOpExpression, ?CodeBlock, ?StringTemplate],
|
?UnaryOpExpression, ?CodeBlock, ?StringTemplate, ?AtImageUrl],
|
||||||
/// Concetenate the Expressions to make a string (usually expended from a template string)
|
/// Concetenate the Expressions to make a string (usually expended from a template string)
|
||||||
StringTemplate -> [*Expression],
|
StringTemplate -> [*Expression],
|
||||||
/// `foo!bar`
|
/// `foo!bar`
|
||||||
BangExpression -> [Expression],
|
BangExpression -> [Expression],
|
||||||
|
/// `@image-url("foo.png")`
|
||||||
|
AtImageUrl -> [],
|
||||||
/// expression()
|
/// expression()
|
||||||
FunctionCallExpression -> [*Expression],
|
FunctionCallExpression -> [*Expression],
|
||||||
/// `expression += expression`
|
/// `expression += expression`
|
||||||
|
|
|
@ -19,7 +19,7 @@ use super::prelude::*;
|
||||||
/// 42px
|
/// 42px
|
||||||
/// #aabbcc
|
/// #aabbcc
|
||||||
/// (something)
|
/// (something)
|
||||||
/// img!"something"
|
/// @image-url("something")
|
||||||
/// some_id.some_property
|
/// some_id.some_property
|
||||||
/// function_call()
|
/// function_call()
|
||||||
/// function_call(hello, world)
|
/// function_call(hello, world)
|
||||||
|
@ -81,20 +81,13 @@ fn parse_expression_helper(p: &mut impl Parser, precedence: OperatorPrecedence)
|
||||||
}
|
}
|
||||||
SyntaxKind::LBracket => parse_array(&mut *p),
|
SyntaxKind::LBracket => parse_array(&mut *p),
|
||||||
SyntaxKind::LBrace => parse_object_notation(&mut *p),
|
SyntaxKind::LBrace => parse_object_notation(&mut *p),
|
||||||
SyntaxKind::Plus => {
|
SyntaxKind::Plus | SyntaxKind::Minus | SyntaxKind::Bang => {
|
||||||
let mut p = p.start_node(SyntaxKind::UnaryOpExpression);
|
let mut p = p.start_node(SyntaxKind::UnaryOpExpression);
|
||||||
p.consume();
|
p.consume();
|
||||||
parse_expression_helper(&mut *p, OperatorPrecedence::Unary);
|
parse_expression_helper(&mut *p, OperatorPrecedence::Unary);
|
||||||
}
|
}
|
||||||
SyntaxKind::Minus => {
|
SyntaxKind::At => {
|
||||||
let mut p = p.start_node(SyntaxKind::UnaryOpExpression);
|
parse_at_keyword(&mut *p);
|
||||||
p.consume();
|
|
||||||
parse_expression_helper(&mut *p, OperatorPrecedence::Unary);
|
|
||||||
}
|
|
||||||
SyntaxKind::Bang => {
|
|
||||||
let mut p = p.start_node(SyntaxKind::UnaryOpExpression);
|
|
||||||
p.consume();
|
|
||||||
parse_expression_helper(&mut *p, OperatorPrecedence::Unary);
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
p.error("invalid expression");
|
p.error("invalid expression");
|
||||||
|
@ -196,6 +189,27 @@ fn parse_expression_helper(p: &mut impl Parser, precedence: OperatorPrecedence)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(test, parser_test)]
|
||||||
|
/// ```test
|
||||||
|
/// @image-url("/foo/bar.png")
|
||||||
|
/// ```
|
||||||
|
fn parse_at_keyword(p: &mut impl Parser) {
|
||||||
|
let checkpoint = p.checkpoint();
|
||||||
|
p.expect(SyntaxKind::At);
|
||||||
|
match p.peek().as_str() {
|
||||||
|
"image-url" | "image_url" => {
|
||||||
|
let mut p = p.start_node_at(checkpoint, SyntaxKind::AtImageUrl);
|
||||||
|
p.consume(); // "image-url"
|
||||||
|
p.expect(SyntaxKind::LParent);
|
||||||
|
p.expect(SyntaxKind::StringLiteral);
|
||||||
|
p.expect(SyntaxKind::RParent);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
p.error("Expected 'image-url' after '@'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(test, parser_test)]
|
#[cfg_attr(test, parser_test)]
|
||||||
/// ```test,BangExpression
|
/// ```test,BangExpression
|
||||||
/// foo!bar
|
/// foo!bar
|
||||||
|
|
|
@ -370,6 +370,7 @@ impl Expression {
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
node.BangExpression().map(|n| Self::from_bang_expression_node(n.into(), ctx))
|
node.BangExpression().map(|n| Self::from_bang_expression_node(n.into(), ctx))
|
||||||
})
|
})
|
||||||
|
.or_else(|| node.AtImageUrl().map(|n| Self::from_at_image_url_node(n, ctx)))
|
||||||
.or_else(|| node.QualifiedName().map(|s| Self::from_qualified_name_node(s.into(), ctx)))
|
.or_else(|| node.QualifiedName().map(|s| Self::from_qualified_name_node(s.into(), ctx)))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
node.child_text(SyntaxKind::StringLiteral).map(|s| {
|
node.child_text(SyntaxKind::StringLiteral).map(|s| {
|
||||||
|
@ -473,6 +474,43 @@ impl Expression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_at_image_url_node(node: syntax_nodes::AtImageUrl, ctx: &mut LookupCtx) -> Self {
|
||||||
|
let s = match node.child_text(SyntaxKind::StringLiteral).and_then(|x| unescape_string(&x)) {
|
||||||
|
Some(s) => s,
|
||||||
|
None => {
|
||||||
|
ctx.diag.push_error("Cannot parse string literal".into(), &node);
|
||||||
|
return Self::Invalid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let absolute_source_path = {
|
||||||
|
let path = std::path::Path::new(&s);
|
||||||
|
|
||||||
|
if path.is_absolute() || s.starts_with("http://") || s.starts_with("https://") {
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
ctx.type_loader
|
||||||
|
.and_then(|loader| {
|
||||||
|
loader
|
||||||
|
.import_file(
|
||||||
|
node.source_file.as_ref().map(|path_rc| path_rc.as_path()),
|
||||||
|
&s,
|
||||||
|
)
|
||||||
|
.map(|resolved_file| resolved_file.path)
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
std::env::current_dir()
|
||||||
|
.map(|b| b.join(&path))
|
||||||
|
.unwrap_or_else(|_| path.into())
|
||||||
|
})
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Expression::ResourceReference(ResourceReference::AbsolutePath(absolute_source_path))
|
||||||
|
}
|
||||||
|
|
||||||
/// Perform the lookup
|
/// Perform the lookup
|
||||||
fn from_qualified_name_node(node: SyntaxNodeWithSourceFile, ctx: &mut LookupCtx) -> Self {
|
fn from_qualified_name_node(node: SyntaxNodeWithSourceFile, ctx: &mut LookupCtx) -> Self {
|
||||||
debug_assert_eq!(node.kind(), SyntaxKind::QualifiedName);
|
debug_assert_eq!(node.kind(), SyntaxKind::QualifiedName);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue