mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-07-07 01:29:26 -04:00
completions: Lookup expressions
This commit is contained in:
parent
684ed7dc02
commit
ddcd77f212
2 changed files with 43 additions and 16 deletions
|
@ -80,20 +80,24 @@ class Binding(AstNode):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def simple_binding(self) -> T.Optional["SimpleBinding"]:
|
def simple_binding(self) -> T.Optional["SimpleBinding"]:
|
||||||
if isinstance(self.expression.last, LookupOp):
|
from .values import IdentLiteral
|
||||||
if isinstance(self.expression.last.lhs, LiteralExpr):
|
|
||||||
from .values import IdentLiteral
|
|
||||||
|
|
||||||
if isinstance(self.expression.last.lhs.literal.value, IdentLiteral):
|
if (
|
||||||
flags = [x.flag for x in self.flags]
|
not isinstance(self.expression.last, LookupOp)
|
||||||
return SimpleBinding(
|
or not isinstance(self.expression.last.lhs, LiteralExpr)
|
||||||
self.expression.last.lhs.literal.value.ident,
|
or not isinstance(self.expression.last.lhs.literal.value, IdentLiteral)
|
||||||
self.expression.last.property_name,
|
or self.expression.last.property_name is None
|
||||||
no_sync_create="no-sync-create" in flags,
|
):
|
||||||
bidirectional="bidirectional" in flags,
|
return None
|
||||||
inverted="inverted" in flags,
|
|
||||||
)
|
flags = [x.flag for x in self.flags]
|
||||||
return None
|
return SimpleBinding(
|
||||||
|
self.expression.last.lhs.literal.value.ident,
|
||||||
|
self.expression.last.property_name,
|
||||||
|
no_sync_create="no-sync-create" in flags,
|
||||||
|
bidirectional="bidirectional" in flags,
|
||||||
|
inverted="inverted" in flags,
|
||||||
|
)
|
||||||
|
|
||||||
@validate("bind")
|
@validate("bind")
|
||||||
def bind_property(self):
|
def bind_property(self):
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
|
||||||
|
|
||||||
|
from .. import annotations
|
||||||
from ..decompiler import decompile_element
|
from ..decompiler import decompile_element
|
||||||
from .common import *
|
from .common import *
|
||||||
from .contexts import ScopeCtx, ValueTypeCtx
|
from .contexts import ScopeCtx, ValueTypeCtx
|
||||||
|
@ -112,18 +113,21 @@ class LiteralExpr(ExprBase):
|
||||||
|
|
||||||
|
|
||||||
class LookupOp(InfixExpr):
|
class LookupOp(InfixExpr):
|
||||||
grammar = [".", UseIdent("property")]
|
grammar = [".", UseIdent("property").expected("property name")]
|
||||||
|
|
||||||
@context(ValueTypeCtx)
|
@context(ValueTypeCtx)
|
||||||
def value_type(self) -> ValueTypeCtx:
|
def value_type(self) -> ValueTypeCtx:
|
||||||
return ValueTypeCtx(None, must_infer_type=True)
|
return ValueTypeCtx(None, must_infer_type=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def property_name(self) -> str:
|
def property_name(self) -> T.Optional[str]:
|
||||||
return self.tokens["property"]
|
return self.tokens["property"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self) -> T.Optional[GirType]:
|
def type(self) -> T.Optional[GirType]:
|
||||||
|
if self.property_name is None:
|
||||||
|
return None
|
||||||
|
|
||||||
if isinstance(self.lhs.type, gir.Class) or isinstance(
|
if isinstance(self.lhs.type, gir.Class) or isinstance(
|
||||||
self.lhs.type, gir.Interface
|
self.lhs.type, gir.Interface
|
||||||
):
|
):
|
||||||
|
@ -167,7 +171,10 @@ class LookupOp(InfixExpr):
|
||||||
f"Type {self.lhs.type.full_name} does not have properties"
|
f"Type {self.lhs.type.full_name} does not have properties"
|
||||||
)
|
)
|
||||||
|
|
||||||
elif self.lhs.type.properties.get(self.property_name) is None:
|
elif (
|
||||||
|
self.property_name is not None
|
||||||
|
and self.lhs.type.properties.get(self.property_name) is None
|
||||||
|
):
|
||||||
raise CompileError(
|
raise CompileError(
|
||||||
f"{self.lhs.type.full_name} does not have a property called {self.property_name}",
|
f"{self.lhs.type.full_name} does not have a property called {self.property_name}",
|
||||||
did_you_mean=(self.property_name, self.lhs.type.properties.keys()),
|
did_you_mean=(self.property_name, self.lhs.type.properties.keys()),
|
||||||
|
@ -192,6 +199,22 @@ class LookupOp(InfixExpr):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@completer([LookupOp], ["."])
|
||||||
|
def complete_lookup_property(ctx: CompletionContext):
|
||||||
|
assert isinstance(ctx.ast_node, LookupOp)
|
||||||
|
|
||||||
|
t = ctx.ast_node.lhs.type
|
||||||
|
if t is not None and hasattr(t, "properties"):
|
||||||
|
for prop_name, prop in t.properties.items():
|
||||||
|
yield Completion(
|
||||||
|
prop_name,
|
||||||
|
CompletionItemKind.Property,
|
||||||
|
deprecated=prop.deprecated,
|
||||||
|
sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, prop_name),
|
||||||
|
docs=prop.doc,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CastExpr(InfixExpr):
|
class CastExpr(InfixExpr):
|
||||||
grammar = [
|
grammar = [
|
||||||
Keyword("as"),
|
Keyword("as"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue