mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
More errors for duplicates
This commit is contained in:
parent
2ca71de061
commit
6ac798ea6f
13 changed files with 105 additions and 9 deletions
|
@ -175,7 +175,9 @@ class AstNode:
|
|||
for child in self.children:
|
||||
yield from child.get_semantic_tokens()
|
||||
|
||||
def validate_unique_in_parent(self, error, check=None):
|
||||
def validate_unique_in_parent(
|
||||
self, error: str, check: T.Optional[T.Callable[["AstNode"], bool]] = None
|
||||
):
|
||||
for child in self.parent.children:
|
||||
if child is self:
|
||||
break
|
||||
|
|
|
@ -24,6 +24,23 @@ from .contexts import ScopeCtx
|
|||
from .common import *
|
||||
|
||||
|
||||
class SignalFlag(AstNode):
|
||||
grammar = AnyOf(
|
||||
UseExact("flag", "swapped"),
|
||||
UseExact("flag", "after"),
|
||||
)
|
||||
|
||||
@property
|
||||
def flag(self) -> str:
|
||||
return self.tokens["flag"]
|
||||
|
||||
@validate()
|
||||
def unique(self):
|
||||
self.validate_unique_in_parent(
|
||||
f"Duplicate flag '{self.flag}'", lambda x: x.flag == self.flag
|
||||
)
|
||||
|
||||
|
||||
class Signal(AstNode):
|
||||
grammar = Statement(
|
||||
UseIdent("name"),
|
||||
|
@ -39,12 +56,7 @@ class Signal(AstNode):
|
|||
Match("(").expected("argument list"),
|
||||
Optional(UseIdent("object")).expected("object identifier"),
|
||||
Match(")").expected(),
|
||||
ZeroOrMore(
|
||||
AnyOf(
|
||||
[Keyword("swapped"), UseLiteral("swapped", True)],
|
||||
[Keyword("after"), UseLiteral("after", True)],
|
||||
)
|
||||
),
|
||||
ZeroOrMore(SignalFlag),
|
||||
)
|
||||
|
||||
@property
|
||||
|
@ -55,6 +67,13 @@ class Signal(AstNode):
|
|||
def detail_name(self) -> T.Optional[str]:
|
||||
return self.tokens["detail_name"]
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
if self.detail_name is None:
|
||||
return self.name
|
||||
else:
|
||||
return self.name + "::" + self.detail_name
|
||||
|
||||
@property
|
||||
def handler(self) -> str:
|
||||
return self.tokens["handler"]
|
||||
|
@ -63,13 +82,17 @@ class Signal(AstNode):
|
|||
def object_id(self) -> T.Optional[str]:
|
||||
return self.tokens["object"]
|
||||
|
||||
@property
|
||||
def flags(self) -> T.List[SignalFlag]:
|
||||
return self.children[SignalFlag]
|
||||
|
||||
@property
|
||||
def is_swapped(self) -> bool:
|
||||
return self.tokens["swapped"] or False
|
||||
return any(x.flag == "swapped" for x in self.flags)
|
||||
|
||||
@property
|
||||
def is_after(self) -> bool:
|
||||
return self.tokens["after"] or False
|
||||
return any(x.flag == "after" for x in self.flags)
|
||||
|
||||
@property
|
||||
def gir_signal(self):
|
||||
|
|
|
@ -38,6 +38,13 @@ class Item(AstNode):
|
|||
def value(self) -> StringValue:
|
||||
return self.children[StringValue][0]
|
||||
|
||||
@validate("name")
|
||||
def unique_in_parent(self):
|
||||
if self.name is not None:
|
||||
self.validate_unique_in_parent(
|
||||
f"Duplicate item '{self.name}'", lambda x: x.name == self.name
|
||||
)
|
||||
|
||||
|
||||
class ExtComboBoxItems(AstNode):
|
||||
grammar = [
|
||||
|
|
|
@ -46,6 +46,13 @@ class FilterString(AstNode):
|
|||
def item(self) -> str:
|
||||
return self.tokens["name"]
|
||||
|
||||
@validate()
|
||||
def unique_in_parent(self):
|
||||
self.validate_unique_in_parent(
|
||||
f"Duplicate {self.tokens['tag_name']} '{self.item}'",
|
||||
check=lambda child: child.item == self.item,
|
||||
)
|
||||
|
||||
|
||||
def create_node(tag_name: str, singular: str):
|
||||
return Group(
|
||||
|
|
|
@ -29,6 +29,10 @@ class ExtListItemFactory(AstNode):
|
|||
"sub-templates",
|
||||
)
|
||||
|
||||
@validate("template")
|
||||
def unique_in_parent(self):
|
||||
self.validate_unique_in_parent("Duplicate template block")
|
||||
|
||||
@validate()
|
||||
def type_is_list_item(self):
|
||||
if self.type_name is not None:
|
||||
|
|
|
@ -69,6 +69,12 @@ class MenuAttribute(AstNode):
|
|||
def value_type(self) -> ValueTypeCtx:
|
||||
return ValueTypeCtx(None)
|
||||
|
||||
@validate("name")
|
||||
def unique(self):
|
||||
self.validate_unique_in_parent(
|
||||
f"Duplicate attribute '{self.name}'", lambda x: x.name == self.name
|
||||
)
|
||||
|
||||
|
||||
menu_child = AnyOf()
|
||||
|
||||
|
|
|
@ -47,6 +47,12 @@ class Widget(AstNode):
|
|||
f"Cannot assign {object.gir_class.full_name} to {type.full_name}"
|
||||
)
|
||||
|
||||
@validate("name")
|
||||
def unique_in_parent(self):
|
||||
self.validate_unique_in_parent(
|
||||
f"Object '{self.name}' is listed twice", lambda x: x.name == self.name
|
||||
)
|
||||
|
||||
|
||||
class ExtSizeGroupWidgets(AstNode):
|
||||
grammar = [
|
||||
|
|
|
@ -29,6 +29,12 @@ class StyleClass(AstNode):
|
|||
def name(self) -> str:
|
||||
return self.tokens["name"]
|
||||
|
||||
@validate("name")
|
||||
def unique_in_parent(self):
|
||||
self.validate_unique_in_parent(
|
||||
f"Duplicate style class '{self.name}'", lambda x: x.name == self.name
|
||||
)
|
||||
|
||||
|
||||
class ExtStyles(AstNode):
|
||||
grammar = [
|
||||
|
|
|
@ -112,6 +112,20 @@ class Child(AstNode):
|
|||
else:
|
||||
return None
|
||||
|
||||
@validate()
|
||||
def internal_child_unique(self):
|
||||
if self.annotation is not None:
|
||||
if isinstance(self.annotation.child, ChildInternal):
|
||||
internal_child = self.annotation.child.internal_child
|
||||
self.validate_unique_in_parent(
|
||||
f"Duplicate internal child '{internal_child}'",
|
||||
lambda x: (
|
||||
x.annotation
|
||||
and isinstance(x.annotation.child, ChildInternal)
|
||||
and x.annotation.child.internal_child == internal_child
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@decompiler("child")
|
||||
def decompile_child(ctx, gir, type=None, internal_child=None):
|
||||
|
|
|
@ -44,6 +44,12 @@ class PropertyBindingFlag(AstNode):
|
|||
actions=[CodeAction("remove 'sync-create'", "")],
|
||||
)
|
||||
|
||||
@validate()
|
||||
def unique(self):
|
||||
self.validate_unique_in_parent(
|
||||
f"Duplicate flag '{self.flag}'", lambda x: x.flag == self.flag
|
||||
)
|
||||
|
||||
|
||||
class PropertyBinding(AstNode):
|
||||
grammar = AnyOf(
|
||||
|
|
|
@ -229,6 +229,12 @@ class Flag(AstNode):
|
|||
did_you_mean=(self.tokens["value"], expected_type.members.keys()),
|
||||
)
|
||||
|
||||
@validate()
|
||||
def unique(self):
|
||||
self.validate_unique_in_parent(
|
||||
f"Duplicate flag '{self.name}'", lambda x: x.name == self.name
|
||||
)
|
||||
|
||||
|
||||
class Flags(AstNode):
|
||||
grammar = [Flag, "|", Flag, ZeroOrMore(["|", Flag])]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue