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::Dollar,
|
||||
'@' => SyntaxKind::At,
|
||||
_ => SyntaxKind::Error,
|
||||
};
|
||||
prev_spacing = p.spacing();
|
||||
|
|
|
@ -272,6 +272,7 @@ declare_syntax! {
|
|||
Dot -> ".",
|
||||
Question -> "?",
|
||||
Dollar -> "$",
|
||||
At -> "@",
|
||||
}
|
||||
// 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)
|
||||
Expression-> [ ?Expression, ?BangExpression, ?FunctionCallExpression, ?SelfAssignment,
|
||||
?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)
|
||||
StringTemplate -> [*Expression],
|
||||
/// `foo!bar`
|
||||
BangExpression -> [Expression],
|
||||
/// `@image-url("foo.png")`
|
||||
AtImageUrl -> [],
|
||||
/// expression()
|
||||
FunctionCallExpression -> [*Expression],
|
||||
/// `expression += expression`
|
||||
|
|
|
@ -19,7 +19,7 @@ use super::prelude::*;
|
|||
/// 42px
|
||||
/// #aabbcc
|
||||
/// (something)
|
||||
/// img!"something"
|
||||
/// @image-url("something")
|
||||
/// some_id.some_property
|
||||
/// function_call()
|
||||
/// 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::LBrace => parse_object_notation(&mut *p),
|
||||
SyntaxKind::Plus => {
|
||||
SyntaxKind::Plus | SyntaxKind::Minus | SyntaxKind::Bang => {
|
||||
let mut p = p.start_node(SyntaxKind::UnaryOpExpression);
|
||||
p.consume();
|
||||
parse_expression_helper(&mut *p, OperatorPrecedence::Unary);
|
||||
}
|
||||
SyntaxKind::Minus => {
|
||||
let mut p = p.start_node(SyntaxKind::UnaryOpExpression);
|
||||
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);
|
||||
SyntaxKind::At => {
|
||||
parse_at_keyword(&mut *p);
|
||||
}
|
||||
_ => {
|
||||
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)]
|
||||
/// ```test,BangExpression
|
||||
/// foo!bar
|
||||
|
|
|
@ -370,6 +370,7 @@ impl Expression {
|
|||
.or_else(|| {
|
||||
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.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
|
||||
fn from_qualified_name_node(node: SyntaxNodeWithSourceFile, ctx: &mut LookupCtx) -> Self {
|
||||
debug_assert_eq!(node.kind(), SyntaxKind::QualifiedName);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue