completions: Lookup expressions

This commit is contained in:
James Westman 2025-05-15 19:56:10 -05:00
parent 684ed7dc02
commit ddcd77f212
No known key found for this signature in database
GPG key ID: CE2DBA0ADB654EA6
2 changed files with 43 additions and 16 deletions

View file

@ -80,20 +80,24 @@ class Binding(AstNode):
@property
def simple_binding(self) -> T.Optional["SimpleBinding"]:
if isinstance(self.expression.last, LookupOp):
if isinstance(self.expression.last.lhs, LiteralExpr):
from .values import IdentLiteral
from .values import IdentLiteral
if isinstance(self.expression.last.lhs.literal.value, IdentLiteral):
flags = [x.flag for x in self.flags]
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,
)
return None
if (
not isinstance(self.expression.last, LookupOp)
or not isinstance(self.expression.last.lhs, LiteralExpr)
or not isinstance(self.expression.last.lhs.literal.value, IdentLiteral)
or self.expression.last.property_name is None
):
return None
flags = [x.flag for x in self.flags]
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")
def bind_property(self):

View file

@ -18,6 +18,7 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
from .. import annotations
from ..decompiler import decompile_element
from .common import *
from .contexts import ScopeCtx, ValueTypeCtx
@ -112,18 +113,21 @@ class LiteralExpr(ExprBase):
class LookupOp(InfixExpr):
grammar = [".", UseIdent("property")]
grammar = [".", UseIdent("property").expected("property name")]
@context(ValueTypeCtx)
def value_type(self) -> ValueTypeCtx:
return ValueTypeCtx(None, must_infer_type=True)
@property
def property_name(self) -> str:
def property_name(self) -> T.Optional[str]:
return self.tokens["property"]
@property
def type(self) -> T.Optional[GirType]:
if self.property_name is None:
return None
if isinstance(self.lhs.type, gir.Class) or isinstance(
self.lhs.type, gir.Interface
):
@ -167,7 +171,10 @@ class LookupOp(InfixExpr):
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(
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()),
@ -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):
grammar = [
Keyword("as"),