From 1dddaf7999fae1ccdc816d72cc84d570b2948257 Mon Sep 17 00:00:00 2001 From: Romain Beguet Date: Fri, 27 Oct 2023 17:06:42 +0200 Subject: [PATCH] A type predicate object can only be seen from within the type definition. --- ada/ast.py | 22 +++++++++++-------- .../record_self_access/test.adb | 13 +++++++++++ .../record_self_access/test.out | 9 ++++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/ada/ast.py b/ada/ast.py index 12ce3ffb8..70743ed13 100644 --- a/ada/ast.py +++ b/ada/ast.py @@ -1183,9 +1183,8 @@ def has_with_visibility(refd_unit=AnalysisUnit, @langkit_property(return_type=Bool) def has_visibility(other_entity=T.AdaNode.entity): - # If we found a synthetic type predicate object decl, it means we are - # inside the definition of the type. From there, check if we indeed - # have visibility on the synthetic object. + # We found a synthetic type predicate object decl, check if we are + # allowed to see it. return other_entity.cast(SyntheticTypePredicateObjectDecl).then( lambda sod: sod.is_referred_by(Self), default_val=True @@ -9178,11 +9177,9 @@ class SyntheticTypePredicateObjectDecl(BasicDecl): def is_referred_by(origin=T.AdaNode): """ Return whether a synthetic type predicate object can be seen from the - given ``origin`` node. This already assumes that we are inside a type - definition (otherwise the env lookup would not have found the synthetic - object), but this can be used to know if the reference points to the - synthetic object or to the type itself. By default this will always be - the synthetic object, unless we are in an access type definition. This + given ``origin`` node. If we are outside the type definition, this will + always be the type itself. Otherwise this will always be the synthetic + object, unless we are in an access type definition. In particular, this allows correctly resolving: .. code:: ada @@ -9195,7 +9192,14 @@ def is_referred_by(origin=T.AdaNode): Here, the reference (1) points to the type, whereas (2) refers to the synthetic object. """ - return Not(origin.parent.parent.is_a(TypeAccessDef)) + return And( + Not(origin.parent.parent.is_a(TypeAccessDef)), + Self.is_children_env( + Self.type_expr.cast(SyntheticTypeExpr) + .target_type.children_env, + origin.children_env + ) + ) @synthetic diff --git a/testsuite/tests/name_resolution/record_self_access/test.adb b/testsuite/tests/name_resolution/record_self_access/test.adb index 551e343cc..c423d0dbd 100644 --- a/testsuite/tests/name_resolution/record_self_access/test.adb +++ b/testsuite/tests/name_resolution/record_self_access/test.adb @@ -14,6 +14,19 @@ procedure Test is --% access_type.f_type_def.f_subtype_indication.p_designated_type_decl --% node.f_default_expr.f_prefix.p_referenced_decl() end record; + + type A is record + B : Integer; + end record; + + type B is new A; + + procedure Assign (X : in out B; Y : B) is + begin + X.B := Y.B; + --% node.f_dest.f_suffix.p_referenced_decl() + --% node.f_expr.f_suffix.p_referenced_decl() + end Assign; begin null; end Test; diff --git a/testsuite/tests/name_resolution/record_self_access/test.out b/testsuite/tests/name_resolution/record_self_access/test.out index 2cda62d90..41eee657f 100644 --- a/testsuite/tests/name_resolution/record_self_access/test.out +++ b/testsuite/tests/name_resolution/record_self_access/test.out @@ -24,3 +24,12 @@ Result: Eval 'node.f_default_expr.f_prefix.p_referenced_decl()' Result: + +Working on node +================================================ + +Eval 'node.f_dest.f_suffix.p_referenced_decl()' +Result: + +Eval 'node.f_expr.f_suffix.p_referenced_decl()' +Result: