From c74887ce023c23ca541c8e50d9548338f47642e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Th=C3=A9venoux?= Date: Tue, 28 May 2024 14:15:34 +0200 Subject: [PATCH] Rework xref equations of type expressions This change adds a new property: xref_type_equation, reworking xref_no_overloading for types name resolution. The goal is to unify xref equations and designated_type properties behavior when resolving types. --- ada/ast.py | 97 +++++++++++-------- .../pkg-sub.adb | 6 ++ .../pkg-sub.ads | 8 ++ .../pkg.ads | 5 + .../test.out | 14 +++ .../test.yaml | 2 + 6 files changed, 92 insertions(+), 40 deletions(-) create mode 100644 testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg-sub.adb create mode 100644 testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg-sub.ads create mode 100644 testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg.ads create mode 100644 testsuite/tests/name_resolution/designated_type_is_referenced_type/test.out create mode 100644 testsuite/tests/name_resolution/designated_type_is_referenced_type/test.yaml diff --git a/ada/ast.py b/ada/ast.py index 8e0fc9bdd..6f99d621c 100644 --- a/ada/ast.py +++ b/ada/ast.py @@ -5644,7 +5644,7 @@ def xref_equation(): And(e.is_a(Name), Not(e.cast(Name).name_designated_type.is_null)), - e.cast(Name).xref_no_overloading, + e.cast(Name).xref_type_equation, Bind(e.expected_type_var, Self.discr_name.type_val) & e.sub_equation @@ -9932,7 +9932,7 @@ def index_type(dim=Int): def xref_equation(): return Entity.types.logic_all( lambda typ: - typ.subtype_name.xref_no_overloading + typ.subtype_name.xref_type_equation & If(typ.lower_bound.is_null, LogicTrue(), typ.lower_bound.sub_equation) @@ -10679,7 +10679,7 @@ class UseTypeClause(UseClause): ) xref_equation = Property( - Entity.types.logic_all(lambda p: p.xref_no_overloading) + Entity.types.logic_all(lambda p: p.xref_type_equation) ) @@ -11603,7 +11603,7 @@ class EnumRepClause(AspectClause): @langkit_property() def xref_equation(): # TODO: resolve names in ``aggregate`` - return Entity.type_name.xref_no_overloading + return Entity.type_name.xref_type_equation @langkit_property(public=True, return_type=ParamActual.array) def params(): @@ -11712,7 +11712,7 @@ class RecordRepClause(AspectClause): @langkit_property() def xref_equation(): return And( - Entity.name.xref_no_overloading, + Entity.name.xref_type_equation, Entity.at_expr.then( lambda e: e.sub_equation, default_val=LogicTrue() @@ -12641,7 +12641,7 @@ def parent_instantiation_env(): ).logic_all(lambda pm: Let( lambda actual_name=pm.actual.assoc.expr.cast(T.Name): pm.formal.formal_decl.cast(T.GenericFormal).decl.match( - lambda _=T.BaseTypeDecl: actual_name.xref_no_overloading, + lambda _=T.BaseTypeDecl: actual_name.xref_type_equation, lambda _=T.GenericPackageInstantiation: actual_name.xref_no_overloading, @@ -13185,11 +13185,11 @@ class FormalSubpDecl(ClassicSubpDecl): lambda _=T.BoxExpr: LogicTrue(), lambda n=T.Name: And( - And(n.xref_no_overloading(all_els=True), - Predicate(BasicDecl.subp_decl_match_signature, - n.ref_var, Entity.cast(T.BasicDecl))), - - If(n.is_a(AttributeRef), n.sub_equation, LogicTrue()) + If(n.is_a(AttributeRef), + n.sub_equation, + n.xref_no_overloading(all_els=True)), + Predicate(BasicDecl.subp_decl_match_signature, + n.ref_var, Entity.cast(T.BasicDecl)) ), lambda _: PropertyError(Equation, "Should not happen") @@ -14930,7 +14930,7 @@ class MembershipExpr(Expr): Not(typ.is_null), # Tagged type check or subtype membership check - m.cast(T.Name).xref_no_overloading + m.cast(T.Name).xref_type_equation & If( # If testing a specific tagged type membership, the # expected type of the tested expression is the type at @@ -15023,7 +15023,7 @@ def xref_equation(): lambda ae: Cond( And(ae.is_a(Name), Not(ae.cast(Name).name_designated_type.is_null)), - ae.cast(Name).xref_no_overloading, + ae.cast(Name).xref_type_equation, Self.is_a(DeltaAggregate), ae.sub_equation, @@ -15762,7 +15762,7 @@ def parent_name_equation(typ=T.BaseTypeDecl.entity, root=T.Name): @langkit_property(return_type=Equation, dynamic_vars=[env, origin, entry_point]) def subtype_indication_equation(): - return Entity.xref_no_overloading + return Entity.xref_type_equation @langkit_property(return_type=Bool) def can_designate_primitive(): @@ -16150,6 +16150,41 @@ def use_package_name_designated_env(): type=T.Symbol, ) + @langkit_property(return_type=Equation, + dynamic_vars=[env, origin, entry_point]) + def xref_type_equation(): + """ + Simple xref equation for names designating types. Doesn't try to + resolve overloads. Originally derived from xref_no_overloading to match + the behavior of designated_type properties. + """ + return Entity.match( + lambda dn=T.DottedName: + dn.prefix.xref_no_overloading( + sequential=True, all_els=False + ) & env.bind( + dn.prefix.designated_env_no_overloading, + dn.suffix.xref_type_equation + ), + lambda i=T.BaseId: Bind(i.ref_var, i.designated_type_impl), + + lambda ar=T.AttributeRef: + ar.prefix.xref_type_equation + & Cond( + ar.attribute.sym == 'Class', + Bind(ar.prefix.ref_var, ar.ref_var, + conv_prop=BaseTypeDecl.classwide_type), + + ar.attribute.sym == 'Base', + Bind(ar.prefix.ref_var, ar.ref_var, + conv_prop=BaseTypeDecl.scalar_base_type), + + LogicTrue() + ), + + lambda _: LogicFalse() + ) + @langkit_property(return_type=Equation, dynamic_vars=[env, origin, entry_point]) def xref_no_overloading(sequential=(Bool, True), @@ -16188,24 +16223,6 @@ def xref_no_overloading(sequential=(Bool, True), ) ) ), - - # xref_no_overloading can be used to resolve type references in - # generic instantiations. In that case, we might encounter a 'Class - # attribute. - lambda ar=T.AttributeRef: - ar.prefix.xref_no_overloading(sequential, all_els) - & Cond( - ar.attribute.sym == 'Class', - Bind(ar.prefix.ref_var, ar.ref_var, - conv_prop=BaseTypeDecl.classwide_type), - - ar.attribute.sym == 'Base', - Bind(ar.prefix.ref_var, ar.ref_var, - conv_prop=BaseTypeDecl.scalar_base_type), - - LogicTrue() - ), - lambda _: LogicFalse() ) @@ -16995,7 +17012,7 @@ def subscriptable_type_equation(typ=T.BaseTypeDecl.entity): lambda name: If( name.name_designated_type.is_null, LogicFalse(), - name.xref_no_overloading + name.xref_type_equation & Bind(Self.type_var, real_typ) ), default_val=LogicFalse(), @@ -17416,7 +17433,7 @@ def array_assoc_equation(atd=ArrayTypeDef.entity, And(n.is_a(Name), Not(n.cast(Name).name_designated_type.is_null)), - n.cast(Name).xref_no_overloading, + n.cast(Name).xref_type_equation, n.cast(T.Expr).then( lambda n: @@ -18099,7 +18116,7 @@ def xref_equation(): And(e.is_a(Name), Not(e.cast(Name).name_designated_type.is_null)), - e.cast(Name).xref_no_overloading, + e.cast(Name).xref_type_equation, Bind(e.expected_type_var, Self.expr.type_val) & e.sub_equation @@ -21405,7 +21422,7 @@ def image_equation(str_type=T.AdaNode.entity): Entity.prefix.sub_equation & Bind(Self.type_var, str_type), - Entity.prefix.xref_no_overloading + Entity.prefix.xref_type_equation & Bind(Self.ref_var, Entity.attribute_subprogram) ) @@ -21432,7 +21449,7 @@ def enum_rep_equation(): Entity.prefix.sub_equation & Bind(Self.type_var, Self.universal_int_type), - Entity.prefix.xref_no_overloading + Entity.prefix.xref_type_equation & Bind(Self.ref_var, Entity.attribute_subprogram) ) @@ -21445,7 +21462,7 @@ def self_type_equation(): """ typ = Var(Entity.prefix.name_designated_type) return And( - Entity.prefix.xref_no_overloading, + Entity.prefix.xref_type_equation, Bind(Self.type_var, typ) ) @@ -21544,7 +21561,7 @@ def array_attr_equation(): Not(typ.is_null), # Prefix is a type - Entity.prefix.xref_no_overloading & Cond( + Entity.prefix.xref_type_equation & Cond( typ.is_array_def_with_deref & is_length, Self.universal_int_bind(Self.type_var), @@ -23396,7 +23413,7 @@ def xref_equation(): And(e.is_a(Name), Not(e.cast(Name).name_designated_type.is_null)), - e.cast(Name).xref_no_overloading, + e.cast(Name).xref_type_equation, Bind(e.expected_type_var, selected_type) & e.sub_equation diff --git a/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg-sub.adb b/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg-sub.adb new file mode 100644 index 000000000..8190beb71 --- /dev/null +++ b/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg-sub.adb @@ -0,0 +1,6 @@ +package body Pkg.Sub is + procedure P (X : T) is + begin + null; + end P; +end Pkg.Sub; diff --git a/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg-sub.ads b/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg-sub.ads new file mode 100644 index 000000000..d31eeb90f --- /dev/null +++ b/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg-sub.ads @@ -0,0 +1,8 @@ +package Pkg.Sub is + procedure P (X : T); + --% type_expr=node.find(lal.TypeExpr) + --% designated_type=type_expr.p_designated_type_decl + --% referenced_type=type_expr.p_type_name.p_referenced_decl() + -- designated_type should be equal to referenced_type + --% designated_type is referenced_type +end Pkg.Sub; diff --git a/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg.ads b/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg.ads new file mode 100644 index 000000000..3058819dc --- /dev/null +++ b/testsuite/tests/name_resolution/designated_type_is_referenced_type/pkg.ads @@ -0,0 +1,5 @@ +package Pkg is + type T is private; +private + type T is null record; +end Pkg; diff --git a/testsuite/tests/name_resolution/designated_type_is_referenced_type/test.out b/testsuite/tests/name_resolution/designated_type_is_referenced_type/test.out new file mode 100644 index 000000000..948c925f0 --- /dev/null +++ b/testsuite/tests/name_resolution/designated_type_is_referenced_type/test.out @@ -0,0 +1,14 @@ +Working on node +===================================================== + +Set 'type_expr' to 'node.find(lal.TypeExpr)' +Result: + +Set 'designated_type' to 'type_expr.p_designated_type_decl' +Result: + +Set 'referenced_type' to 'type_expr.p_type_name.p_referenced_decl()' +Result: + +Eval 'designated_type is referenced_type' +Result: True diff --git a/testsuite/tests/name_resolution/designated_type_is_referenced_type/test.yaml b/testsuite/tests/name_resolution/designated_type_is_referenced_type/test.yaml new file mode 100644 index 000000000..df2c8d013 --- /dev/null +++ b/testsuite/tests/name_resolution/designated_type_is_referenced_type/test.yaml @@ -0,0 +1,2 @@ +driver: inline-playground +input_sources: [pkg-sub.ads]