mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-05 16:09:07 -04:00
tests: Test custom types in lookup expressions
This commit is contained in:
parent
c7c32cbb4a
commit
52f7d790bd
10 changed files with 82 additions and 14 deletions
|
@ -32,6 +32,10 @@ class Expr(AstNode):
|
|||
def gir_type(self):
|
||||
return self.children[-1].gir_type
|
||||
|
||||
@property
|
||||
def glib_type_name(self):
|
||||
return self.children[-1].glib_type_name
|
||||
|
||||
def emit_xml(self, xml: XmlEmitter):
|
||||
self.children[-1].emit_xml(xml)
|
||||
|
||||
|
@ -71,6 +75,15 @@ class IdentExpr(AstNode):
|
|||
elif self.tokens["ident"] in scope.get_objects():
|
||||
return scope.get_objects()[self.tokens["ident"]].gir_class
|
||||
|
||||
@property
|
||||
def glib_type_name(self):
|
||||
scope = self.parent_by_type(Scope)
|
||||
|
||||
if self.is_this:
|
||||
return scope.this_type_glib_name
|
||||
elif self.tokens["ident"] in scope.get_objects():
|
||||
return scope.get_objects()[self.tokens["ident"]].glib_type_name
|
||||
|
||||
def emit_xml(self, xml: XmlEmitter):
|
||||
if self.is_this:
|
||||
raise CompilerBugError()
|
||||
|
@ -97,6 +110,10 @@ class ClosureExpr(AstNode):
|
|||
def gir_type(self):
|
||||
return self.parent.parent.gir_type
|
||||
|
||||
@property
|
||||
def glib_type_name(self):
|
||||
return self.parent.parent.glib_type_name
|
||||
|
||||
def emit_xml(self, xml: XmlEmitter):
|
||||
xml.start_tag("closure", function=self.tokens["function"], type=self.gir_type)
|
||||
for child in self.children[Expr]:
|
||||
|
@ -113,6 +130,11 @@ class LookupOp(InfixExpr):
|
|||
if prop := parent_type.properties.get(self.tokens["property"]):
|
||||
return prop.type
|
||||
|
||||
@property
|
||||
def glib_type_name(self):
|
||||
if self.gir_type is not None:
|
||||
return self.gir_type.glib_type_name
|
||||
|
||||
@validate("property")
|
||||
def property_exists(self):
|
||||
if parent_type := self.lhs.gir_type:
|
||||
|
@ -127,9 +149,9 @@ class LookupOp(InfixExpr):
|
|||
|
||||
def emit_xml(self, xml: XmlEmitter):
|
||||
if isinstance(self.lhs, IdentExpr) and self.lhs.is_this:
|
||||
xml.put_self_closing("lookup", name=self.tokens["property"], type=self.parent_by_type(Scope).this_type)
|
||||
xml.put_self_closing("lookup", name=self.tokens["property"], type=self.parent_by_type(Scope).this_type_glib_name)
|
||||
else:
|
||||
xml.start_tag("lookup", name=self.tokens["property"], type=self.lhs.gir_type)
|
||||
xml.start_tag("lookup", name=self.tokens["property"], type=self.lhs.glib_type_name)
|
||||
self.lhs.emit_xml(xml)
|
||||
xml.end_tag()
|
||||
|
||||
|
@ -141,6 +163,10 @@ class CastExpr(AstNode):
|
|||
def gir_type(self):
|
||||
return self.children[TypeName][0].gir_type
|
||||
|
||||
@property
|
||||
def glib_type_name(self):
|
||||
return self.children[TypeName][0].glib_type_name
|
||||
|
||||
def emit_xml(self, xml: XmlEmitter):
|
||||
self.children[Expr][0].emit_xml(xml)
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
import typing as T
|
||||
from functools import cached_property
|
||||
|
||||
from ..gir import Class
|
||||
from .types import ConcreteClassName, ClassName
|
||||
from .common import *
|
||||
from .response_id import ResponseId
|
||||
|
@ -60,10 +61,13 @@ class Object(AstNode):
|
|||
@property
|
||||
def gir_class(self):
|
||||
class_names = self.children[ClassName]
|
||||
if len(class_names) == 0:
|
||||
return None
|
||||
else:
|
||||
return class_names[0].gir_type
|
||||
if len(class_names) > 0:
|
||||
if isinstance(class_names[0].gir_type, Class):
|
||||
return class_names[0].gir_type
|
||||
|
||||
@property
|
||||
def glib_type_name(self) -> str:
|
||||
return self.children[ClassName][0].glib_type_name
|
||||
|
||||
@docs("namespace")
|
||||
def namespace_docs(self):
|
||||
|
@ -94,7 +98,7 @@ class Object(AstNode):
|
|||
from .gtkbuilder_child import Child
|
||||
|
||||
xml.start_tag("object", **{
|
||||
"class": self.children[ClassName][0].glib_type_name,
|
||||
"class": self.glib_type_name,
|
||||
"id": self.tokens["id"],
|
||||
})
|
||||
for child in self.children:
|
||||
|
|
|
@ -51,3 +51,7 @@ class Lambda(Value, Scope):
|
|||
@property
|
||||
def this_type(self) -> str:
|
||||
return self.children[TypeName][0].gir_type
|
||||
|
||||
@property
|
||||
def this_type_glib_name(self) -> str:
|
||||
return self.children[TypeName][0].glib_type_name
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
import typing as T
|
||||
from .common import *
|
||||
from ..gir import Class, Interface
|
||||
|
||||
|
||||
class TypeName(AstNode):
|
||||
|
@ -80,16 +81,19 @@ class TypeName(AstNode):
|
|||
|
||||
|
||||
class ClassName(TypeName):
|
||||
@validate("class_name")
|
||||
def gir_type_is_class(self):
|
||||
if self.gir_type is not None and not isinstance(self.gir_type, gir.Class):
|
||||
raise CompileError(f"{self.gir_type.full_name} is not a class")
|
||||
@validate("namespace", "class_name")
|
||||
def gir_class_exists(self):
|
||||
if self.gir_type is not None and not isinstance(self.gir_type, Class):
|
||||
if isinstance(self.gir_type, Interface):
|
||||
raise CompileError(f"{self.gir_type.full_name} is an interface, not a class")
|
||||
else:
|
||||
raise CompileError(f"{self.gir_type.full_name} is not a class")
|
||||
|
||||
|
||||
class ConcreteClassName(ClassName):
|
||||
@validate("namespace", "class_name")
|
||||
def not_abstract(self):
|
||||
if self.gir_type is not None and self.gir_type.abstract:
|
||||
if isinstance(self.gir_type, Class) and self.gir_type.abstract:
|
||||
raise CompileError(
|
||||
f"{self.gir_type.full_name} can't be instantiated because it's abstract",
|
||||
hints=[f"did you mean to use a subclass of {self.gir_type.full_name}?"]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue