Use <> instead of () for casts & typeof

This makes it clearer that they aren't functions, and it eliminates
syntactic ambiguity with closure expressions.
This commit is contained in:
James Westman 2023-04-10 09:38:56 -05:00
parent d6bd282e58
commit 02796fd830
10 changed files with 66 additions and 11 deletions

View file

@ -159,7 +159,17 @@ class LookupOp(InfixExpr):
class CastExpr(InfixExpr): class CastExpr(InfixExpr):
grammar = ["as", "(", TypeName, ")"] grammar = [
"as",
AnyOf(
["<", TypeName, Match(">").expected()],
[
UseExact("lparen", "("),
TypeName,
UseExact("rparen", ")").expected("')'"),
],
),
]
@context(ValueTypeCtx) @context(ValueTypeCtx)
def value_type(self): def value_type(self):
@ -183,6 +193,19 @@ class CastExpr(InfixExpr):
f"Invalid cast. No instance of {self.lhs.type.full_name} can be an instance of {self.type.full_name}." f"Invalid cast. No instance of {self.lhs.type.full_name} can be an instance of {self.type.full_name}."
) )
@validate("lparen", "rparen")
def upgrade_to_angle_brackets(self):
if self.tokens["lparen"]:
raise UpgradeWarning(
"Use angle bracket syntax introduced in blueprint 0.8.0",
actions=[
CodeAction(
"Use <> instead of ()",
f"<{self.children[TypeName][0].as_string}>",
)
],
)
class ClosureArg(AstNode): class ClosureArg(AstNode):
grammar = ExprChain grammar = ExprChain

View file

@ -89,6 +89,15 @@ class TypeName(AstNode):
if self.gir_type: if self.gir_type:
return self.gir_type.doc return self.gir_type.doc
@property
def as_string(self) -> str:
if self.tokens["extern"]:
return "$" + self.tokens["class_name"]
elif self.tokens["namespace"]:
return f"{self.tokens['namespace']}.{self.tokens['class_name']}"
else:
return self.tokens["class_name"]
class ClassName(TypeName): class ClassName(TypeName):
@validate("namespace", "class_name") @validate("namespace", "class_name")

View file

@ -74,9 +74,18 @@ class Translated(AstNode):
class TypeLiteral(AstNode): class TypeLiteral(AstNode):
grammar = [ grammar = [
"typeof", "typeof",
"(", AnyOf(
to_parse_node(TypeName).expected("type name"), [
Match(")").expected(), "<",
to_parse_node(TypeName).expected("type name"),
Match(">").expected(),
],
[
UseExact("lparen", "("),
to_parse_node(TypeName).expected("type name"),
UseExact("rparen", ")").expected("')'"),
],
),
] ]
@property @property
@ -93,6 +102,19 @@ class TypeLiteral(AstNode):
if expected_type is not None and not isinstance(expected_type, gir.TypeType): if expected_type is not None and not isinstance(expected_type, gir.TypeType):
raise CompileError(f"Cannot convert GType to {expected_type.full_name}") raise CompileError(f"Cannot convert GType to {expected_type.full_name}")
@validate("lparen", "rparen")
def upgrade_to_angle_brackets(self):
if self.tokens["lparen"]:
raise UpgradeWarning(
"Use angle bracket syntax introduced in blueprint 0.8.0",
actions=[
CodeAction(
"Use <> instead of ()",
f"<{self.children[TypeName][0].as_string}>",
)
],
)
class QuotedLiteral(AstNode): class QuotedLiteral(AstNode):
grammar = UseQuoted("value") grammar = UseQuoted("value")

View file

@ -1,3 +1,4 @@
3,1,8,Use the '$' extern syntax introduced in blueprint 0.8.0 3,1,8,Use the '$' extern syntax introduced in blueprint 0.8.0
4,15,15,Use angle bracket syntax introduced in blueprint 0.8.0
4,16,13,Use the '$' extern syntax introduced in blueprint 0.8.0 4,16,13,Use the '$' extern syntax introduced in blueprint 0.8.0
5,14,7,Use the '$' extern syntax introduced in blueprint 0.8.0 5,14,7,Use the '$' extern syntax introduced in blueprint 0.8.0

View file

@ -1,5 +1,5 @@
using Gtk 4.0; using Gtk 4.0;
Label my-label { Label my-label {
label: bind ($my-closure(my-label.margin-bottom)) as (string); label: bind ($my-closure(my-label.margin-bottom)) as <string>;
} }

View file

@ -1,5 +1,5 @@
using Gtk 4.0; using Gtk 4.0;
Label { Label {
label: bind $my-closure (true, 10, "Hello") as (string); label: bind $my-closure (true, 10, "Hello") as <string>;
} }

View file

@ -5,5 +5,5 @@ Overlay {
} }
Label { Label {
label: bind (label.parent) as (Overlay).child as (Label).label; label: bind (label.parent) as <Overlay>.child as <Label>.label;
} }

View file

@ -1,5 +1,5 @@
using Gtk 4.0; using Gtk 4.0;
template MyTemplate : Box { template MyTemplate : Box {
prop1: bind MyTemplate.prop2 as ($MyObject).prop3; prop1: bind MyTemplate.prop2 as <$MyObject>.prop3;
} }

View file

@ -1,5 +1,5 @@
using Gtk 4.0; using Gtk 4.0;
template MyTemplate : $MyParentClass { template MyTemplate : $MyParentClass {
prop1: bind MyTemplate.prop2 as ($MyObject).prop3; prop1: bind MyTemplate.prop2 as <$MyObject>.prop3;
} }

View file

@ -3,9 +3,9 @@ using GObject 2.0;
using Gio 2.0; using Gio 2.0;
Gio.ListStore { Gio.ListStore {
item-type: typeof(GObject.Object); item-type: typeof<GObject.Object>;
} }
Gio.ListStore { Gio.ListStore {
item-type: typeof($MyObject); item-type: typeof<$MyObject>;
} }