mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
types: Add UncheckedType
This allows us to remember information about an external type, such as its name, while still marking it as unchecked.
This commit is contained in:
parent
f7aa7d0be2
commit
2033bd9e16
7 changed files with 55 additions and 11 deletions
|
@ -120,7 +120,7 @@ def gtk_object_completer(ast_node, match_variables):
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def property_completer(ast_node, match_variables):
|
def property_completer(ast_node, match_variables):
|
||||||
if ast_node.gir_class:
|
if ast_node.gir_class and not isinstance(ast_node.gir_class, gir.UncheckedType):
|
||||||
for prop in ast_node.gir_class.properties:
|
for prop in ast_node.gir_class.properties:
|
||||||
yield Completion(prop, CompletionItemKind.Property, snippet=f"{prop}: $0;")
|
yield Completion(prop, CompletionItemKind.Property, snippet=f"{prop}: $0;")
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ def prop_value_completer(ast_node, match_variables):
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def signal_completer(ast_node, match_variables):
|
def signal_completer(ast_node, match_variables):
|
||||||
if ast_node.gir_class:
|
if ast_node.gir_class and not isinstance(ast_node.gir_class, gir.UncheckedType):
|
||||||
for signal in ast_node.gir_class.signals:
|
for signal in ast_node.gir_class.signals:
|
||||||
if not isinstance(ast_node.parent, language.Object):
|
if not isinstance(ast_node.parent, language.Object):
|
||||||
name = "on"
|
name = "on"
|
||||||
|
|
|
@ -93,13 +93,36 @@ class GirType:
|
||||||
def doc(self):
|
def doc(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def assignable_to(self, other) -> bool:
|
def assignable_to(self, other: "GirType") -> bool:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def full_name(self) -> str:
|
def full_name(self) -> str:
|
||||||
|
"""The GIR name of the type to use in diagnostics"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def glib_type_name(self) -> str:
|
||||||
|
"""The name of the type in the GObject type system, suitable to pass to `g_type_from_name()`."""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
class UncheckedType(GirType):
|
||||||
|
def __init__(self, name) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self._name = name
|
||||||
|
|
||||||
|
def assignable_to(self, other: GirType) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def full_name(self) -> str:
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def glib_type_name(self) -> str:
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
|
||||||
class BasicType(GirType):
|
class BasicType(GirType):
|
||||||
name: str = "unknown type"
|
name: str = "unknown type"
|
||||||
|
@ -111,6 +134,7 @@ class BasicType(GirType):
|
||||||
|
|
||||||
class BoolType(BasicType):
|
class BoolType(BasicType):
|
||||||
name = "bool"
|
name = "bool"
|
||||||
|
glib_type_name: str = "gboolean"
|
||||||
|
|
||||||
def assignable_to(self, other) -> bool:
|
def assignable_to(self, other) -> bool:
|
||||||
return isinstance(other, BoolType)
|
return isinstance(other, BoolType)
|
||||||
|
@ -118,6 +142,7 @@ class BoolType(BasicType):
|
||||||
|
|
||||||
class IntType(BasicType):
|
class IntType(BasicType):
|
||||||
name = "int"
|
name = "int"
|
||||||
|
glib_type_name: str = "gint"
|
||||||
|
|
||||||
def assignable_to(self, other) -> bool:
|
def assignable_to(self, other) -> bool:
|
||||||
return (
|
return (
|
||||||
|
@ -129,6 +154,7 @@ class IntType(BasicType):
|
||||||
|
|
||||||
class UIntType(BasicType):
|
class UIntType(BasicType):
|
||||||
name = "uint"
|
name = "uint"
|
||||||
|
glib_type_name: str = "guint"
|
||||||
|
|
||||||
def assignable_to(self, other) -> bool:
|
def assignable_to(self, other) -> bool:
|
||||||
return (
|
return (
|
||||||
|
@ -140,6 +166,7 @@ class UIntType(BasicType):
|
||||||
|
|
||||||
class FloatType(BasicType):
|
class FloatType(BasicType):
|
||||||
name = "float"
|
name = "float"
|
||||||
|
glib_type_name: str = "gfloat"
|
||||||
|
|
||||||
def assignable_to(self, other) -> bool:
|
def assignable_to(self, other) -> bool:
|
||||||
return isinstance(other, FloatType)
|
return isinstance(other, FloatType)
|
||||||
|
@ -147,6 +174,7 @@ class FloatType(BasicType):
|
||||||
|
|
||||||
class StringType(BasicType):
|
class StringType(BasicType):
|
||||||
name = "string"
|
name = "string"
|
||||||
|
glib_type_name: str = "gchararray"
|
||||||
|
|
||||||
def assignable_to(self, other) -> bool:
|
def assignable_to(self, other) -> bool:
|
||||||
return isinstance(other, StringType)
|
return isinstance(other, StringType)
|
||||||
|
@ -154,6 +182,7 @@ class StringType(BasicType):
|
||||||
|
|
||||||
class TypeType(BasicType):
|
class TypeType(BasicType):
|
||||||
name = "GType"
|
name = "GType"
|
||||||
|
glib_type_name: str = "GType"
|
||||||
|
|
||||||
def assignable_to(self, other) -> bool:
|
def assignable_to(self, other) -> bool:
|
||||||
return isinstance(other, TypeType)
|
return isinstance(other, TypeType)
|
||||||
|
|
|
@ -24,7 +24,15 @@ from ..errors import CompileError, MultipleErrors
|
||||||
from ..completions_utils import *
|
from ..completions_utils import *
|
||||||
from .. import decompiler as decompile
|
from .. import decompiler as decompile
|
||||||
from ..decompiler import DecompileCtx, decompiler
|
from ..decompiler import DecompileCtx, decompiler
|
||||||
from ..gir import StringType, BoolType, IntType, FloatType, GirType, Enumeration
|
from ..gir import (
|
||||||
|
StringType,
|
||||||
|
BoolType,
|
||||||
|
IntType,
|
||||||
|
FloatType,
|
||||||
|
GirType,
|
||||||
|
Enumeration,
|
||||||
|
UncheckedType,
|
||||||
|
)
|
||||||
from ..lsp_utils import Completion, CompletionItemKind, SemanticToken, SemanticTokenType
|
from ..lsp_utils import Completion, CompletionItemKind, SemanticToken, SemanticTokenType
|
||||||
from ..parse_tree import *
|
from ..parse_tree import *
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ class Property(AstNode):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gir_property(self):
|
def gir_property(self):
|
||||||
if self.gir_class is not None:
|
if self.gir_class is not None and not isinstance(self.gir_class, UncheckedType):
|
||||||
return self.gir_class.properties.get(self.tokens["name"])
|
return self.gir_class.properties.get(self.tokens["name"])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -79,7 +79,7 @@ class Property(AstNode):
|
||||||
|
|
||||||
@validate("name")
|
@validate("name")
|
||||||
def property_exists(self):
|
def property_exists(self):
|
||||||
if self.gir_class is None:
|
if self.gir_class is None or isinstance(self.gir_class, UncheckedType):
|
||||||
# Objects that we have no gir data on should not be validated
|
# Objects that we have no gir data on should not be validated
|
||||||
# This happens for classes defined by the app itself
|
# This happens for classes defined by the app itself
|
||||||
return
|
return
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Signal(AstNode):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gir_signal(self):
|
def gir_signal(self):
|
||||||
if self.gir_class is not None:
|
if self.gir_class is not None and not isinstance(self.gir_class, UncheckedType):
|
||||||
return self.gir_class.signals.get(self.tokens["name"])
|
return self.gir_class.signals.get(self.tokens["name"])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -80,7 +80,7 @@ class Signal(AstNode):
|
||||||
|
|
||||||
@validate("name")
|
@validate("name")
|
||||||
def signal_exists(self):
|
def signal_exists(self):
|
||||||
if self.gir_class is None:
|
if self.gir_class is None or isinstance(self.gir_class, UncheckedType):
|
||||||
# Objects that we have no gir data on should not be validated
|
# Objects that we have no gir data on should not be validated
|
||||||
# This happens for classes defined by the app itself
|
# This happens for classes defined by the app itself
|
||||||
return
|
return
|
||||||
|
|
|
@ -53,6 +53,8 @@ class Template(Object):
|
||||||
# Templates might not have a parent class defined
|
# Templates might not have a parent class defined
|
||||||
if class_name := self.class_name:
|
if class_name := self.class_name:
|
||||||
return class_name.gir_type
|
return class_name.gir_type
|
||||||
|
else:
|
||||||
|
return gir.UncheckedType(self.id)
|
||||||
|
|
||||||
@validate("id")
|
@validate("id")
|
||||||
def unique_in_parent(self):
|
def unique_in_parent(self):
|
||||||
|
|
|
@ -56,12 +56,13 @@ class TypeName(AstNode):
|
||||||
return self.root.gir.namespaces.get(self.tokens["namespace"] or "Gtk")
|
return self.root.gir.namespaces.get(self.tokens["namespace"] or "Gtk")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gir_type(self) -> T.Optional[gir.Class]:
|
def gir_type(self) -> gir.GirType:
|
||||||
if self.tokens["class_name"] and not self.tokens["ignore_gir"]:
|
if self.tokens["class_name"] and not self.tokens["ignore_gir"]:
|
||||||
return self.root.gir.get_type(
|
return self.root.gir.get_type(
|
||||||
self.tokens["class_name"], self.tokens["namespace"]
|
self.tokens["class_name"], self.tokens["namespace"]
|
||||||
)
|
)
|
||||||
return None
|
|
||||||
|
return gir.UncheckedType(self.tokens["class_name"])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def glib_type_name(self) -> str:
|
def glib_type_name(self) -> str:
|
||||||
|
@ -84,7 +85,11 @@ class TypeName(AstNode):
|
||||||
class ClassName(TypeName):
|
class ClassName(TypeName):
|
||||||
@validate("namespace", "class_name")
|
@validate("namespace", "class_name")
|
||||||
def gir_class_exists(self):
|
def gir_class_exists(self):
|
||||||
if self.gir_type is not None and not isinstance(self.gir_type, Class):
|
if (
|
||||||
|
self.gir_type
|
||||||
|
and not isinstance(self.gir_type, UncheckedType)
|
||||||
|
and not isinstance(self.gir_type, Class)
|
||||||
|
):
|
||||||
if isinstance(self.gir_type, Interface):
|
if isinstance(self.gir_type, Interface):
|
||||||
raise CompileError(
|
raise CompileError(
|
||||||
f"{self.gir_type.full_name} is an interface, not a class"
|
f"{self.gir_type.full_name} is an interface, not a class"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue