diff --git a/ada/nodes.lkt b/ada/nodes.lkt index 976575947..bc4c52338 100644 --- a/ada/nodes.lkt +++ b/ada/nodes.lkt @@ -14583,32 +14583,54 @@ class BaseId: SingleTokNode implements TokenNode { fun parent_scope(): LexicalEnv = env @with_dynvars(env, origin) - fun designated_type_impl(): Entity[BaseTypeDecl] = node.env_get_first_visible( - env, from_node=node.origin_node(), lookup_type=if node.is_prefix() then LookupKind.recursive else LookupKind.minimal - ).do( - (env_el) => env_el.as[BaseTypeDecl].do( - (t) => if origin.is_null then { - bind origin = node.origin_node(); + fun designated_type_impl(): Entity[BaseTypeDecl] = + node.env_get_first_visible( + env, from_node=node.origin_node(), + lookup_type=if node.is_prefix() + then LookupKind.recursive + else LookupKind.minimal + ).do( + (env_el) => env_el.as[BaseTypeDecl].do( + (t) => if origin.is_null then { + bind origin = node.origin_node(); - t.most_visible_forward_part_for_name(t.name_symbol(), seq=false) - } else t.most_visible_part(), default_val=env_el + t.most_visible_forward_part_for_name( + t.name_symbol(), seq=false + ) + } else t.most_visible_part(), + default_val=env_el + ).do( + (v1) => match v1 { + case t: BaseTypeDecl => t + case tb: TaskBody => tb.task_type() + case pb: ProtectedBody => pb.protected_type() + case tbs: TaskBodyStub => + tbs.body_part_for_decl().as[TaskBody].task_type() + case pbs: ProtectedBodyStub => + pbs.body_part_for_decl().as[ProtectedBody] + .protected_type() + case _ => null[Entity[BaseTypeDecl]] + } + ) ).do( - (v1) => match v1 { - case t: BaseTypeDecl => t - case tb: TaskBody => tb.task_type() - case pb: ProtectedBody => pb.protected_type() - case tbs: TaskBodyStub => tbs.body_part_for_decl().as[TaskBody].task_type() - case pbs: ProtectedBodyStub => pbs.body_part_for_decl().as[ProtectedBody].protected_type() - case _ => null[Entity[BaseTypeDecl]] - } + (type) => + # When the type is a generic formal type, if we are resolving it + # from it's instantiation, that means that no actual has been given + # for that formal (name resolution directly calls + # resolve_generic_actual on actuals names), therefore the designated + # type should be the default one if any. On the other hand, outside + # it's own instantion context, the designated type is the formal + # type, whether it has a default value or not. + type.parent.as[GenericFormalTypeDecl].do( + (formal_decl) => + if formal_decl.generic_instantiations.any( + (inst) => inst.designated_generic_decl.node == + formal_decl.parent_decl.node + ) + then formal_decl.default_type or? type + else type + ) or? type ) - ).do( - (precise) => - # If we got a formal type declaration (i.e. a type declaration - # of a generic formal parameter), always returns its default type - # value if any. - precise.parent.as[GenericFormalTypeDecl].do((gftd) => gftd.default_type()) or? precise - ) @with_dynvars(env, origin) fun all_env_els_impl(seq: Bool = true, seq_from: AdaNode = null[AdaNode], categories: RefCategories = RefCategories(_=true)): Array[Entity[AdaNode]] = node.env_get( diff --git a/testsuite/tests/name_resolution/generic_formal_type_default_type/inner.adb b/testsuite/tests/name_resolution/generic_formal_type_default_type/inner.adb new file mode 100644 index 000000000..2f604d933 --- /dev/null +++ b/testsuite/tests/name_resolution/generic_formal_type_default_type/inner.adb @@ -0,0 +1,27 @@ +procedure Test is + + generic + package PP is + generic + type T is range <> or use Integer; + package Pkg is + X : T; + end Pkg; + + package My_Pkg_1 is new Pkg; + + package My_Pkg_2 is new Pkg (Long_Integer); + end PP; + + package M is new PP; + --% obj = node.p_designated_generic_decl.find(lal.ObjectDecl) + --% obj.f_type_expr.p_designated_type_decl + + --% insts = node.p_designated_generic_decl.findall(lal.GenericInstantiation) + --% gens = [inst.p_designated_generic_decl for inst in insts] + --% objs = [gen.find(lal.ObjectDecl) for gen in gens] + --% [obj.f_type_expr.p_designated_type_decl for obj in objs] + +begin + null; +end Test; diff --git a/testsuite/tests/name_resolution/generic_formal_type_default_type/inner2.adb b/testsuite/tests/name_resolution/generic_formal_type_default_type/inner2.adb new file mode 100644 index 000000000..237dddeb6 --- /dev/null +++ b/testsuite/tests/name_resolution/generic_formal_type_default_type/inner2.adb @@ -0,0 +1,27 @@ +procedure Inner2 is + generic + package PP is + generic + type T is range <> or use Integer; + package Pkg is + generic + package Nested is + X : T; + end Nested; + end Pkg; + + package My_Pkg_1 is new Pkg; + package My_Nested is new My_Pkg_1.Nested; + end PP; + + package M is new PP; + --% obj = node.p_designated_generic_decl.find(lal.ObjectDecl) + --% obj.f_type_expr.p_designated_type_decl + + --% insts = node.p_designated_generic_decl.findall(lal.GenericInstantiation) + --% gens = [inst.p_designated_generic_decl for inst in insts] + --% objs = [gen.find(lal.ObjectDecl) for gen in gens] + --% [obj.f_type_expr.p_designated_type_decl for obj in objs] +begin + null; +end; diff --git a/testsuite/tests/name_resolution/generic_formal_type_default_type/test.adb b/testsuite/tests/name_resolution/generic_formal_type_default_type/test.adb new file mode 100644 index 000000000..02daa6b2e --- /dev/null +++ b/testsuite/tests/name_resolution/generic_formal_type_default_type/test.adb @@ -0,0 +1,18 @@ +procedure Test is + generic + type T is range <> or use Integer; + package Pkg is + X : T; + --% node.f_type_expr.p_designated_type_decl + end Pkg; + + package My_Pkg_1 is new Pkg; + --% obj = node.p_designated_generic_decl.find(lal.ObjectDecl) + --% obj.f_type_expr.p_designated_type_decl + + package My_Pkg_2 is new Pkg (Long_Integer); + --% obj = node.p_designated_generic_decl.find(lal.ObjectDecl) + --% obj.f_type_expr.p_designated_type_decl +begin + null; +end Test; diff --git a/testsuite/tests/name_resolution/generic_formal_type_default_type/test.out b/testsuite/tests/name_resolution/generic_formal_type_default_type/test.out new file mode 100644 index 000000000..fe44bc078 --- /dev/null +++ b/testsuite/tests/name_resolution/generic_formal_type_default_type/test.out @@ -0,0 +1,73 @@ +Working on node +======================================================================== + +Set 'obj' to 'node.p_designated_generic_decl.find(lal.ObjectDecl)' +Result: <| ObjectDecl ["X"] inner.adb:8:10-8:16 [inner.adb:16:4] |> + +Eval 'obj.f_type_expr.p_designated_type_decl' +Result: <| FormalTypeDecl ["T"] inner.adb:6:10-6:44 [inner.adb:16:4] |> + +Set 'insts' to 'node.p_designated_generic_decl.findall(lal.GenericInstantiation)' +Result: [<| GenericPackageInstantiation ["My_Pkg_1"] inner.adb:11:7-11:35 [inner.adb:16:4] |>, + <| GenericPackageInstantiation ["My_Pkg_2"] inner.adb:13:7-13:50 [inner.adb:16:4] |>] + +Set 'gens' to '[inst.p_designated_generic_decl for inst in insts]' +Result: [<| GenericPackageDecl ["Pkg"] inner.adb:5:7-9:15 [inner.adb:16:4, inner.adb:11:7] |>, + <| GenericPackageDecl ["Pkg"] inner.adb:5:7-9:15 [inner.adb:16:4, inner.adb:13:7] |>] + +Set 'objs' to '[gen.find(lal.ObjectDecl) for gen in gens]' +Result: [<| ObjectDecl ["X"] inner.adb:8:10-8:16 [inner.adb:16:4, inner.adb:11:7] |>, + <| ObjectDecl ["X"] inner.adb:8:10-8:16 [inner.adb:16:4, inner.adb:13:7] |>] + +Eval '[obj.f_type_expr.p_designated_type_decl for obj in objs]' +Result: [, + ] + +Working on node +========================================================================= + +Set 'obj' to 'node.p_designated_generic_decl.find(lal.ObjectDecl)' +Result: <| ObjectDecl ["X"] inner2.adb:9:13-9:19 [inner2.adb:17:4] |> + +Eval 'obj.f_type_expr.p_designated_type_decl' +Result: <| FormalTypeDecl ["T"] inner2.adb:5:10-5:44 [inner2.adb:17:4] |> + +Set 'insts' to 'node.p_designated_generic_decl.findall(lal.GenericInstantiation)' +Result: [<| GenericPackageInstantiation ["My_Pkg_1"] inner2.adb:13:7-13:35 [inner2.adb:17:4] |>, + <| GenericPackageInstantiation ["My_Nested"] inner2.adb:14:7-14:48 [inner2.adb:17:4] |>] + +Set 'gens' to '[inst.p_designated_generic_decl for inst in insts]' +Result: [<| GenericPackageDecl ["Pkg"] inner2.adb:4:7-11:15 [inner2.adb:17:4, inner2.adb:13:7] |>, + <| GenericPackageDecl ["Nested"] inner2.adb:7:10-10:21 [inner2.adb:17:4, inner2.adb:13:7, inner2.adb:14:7] |>] + +Set 'objs' to '[gen.find(lal.ObjectDecl) for gen in gens]' +Result: [<| ObjectDecl ["X"] inner2.adb:9:13-9:19 [inner2.adb:17:4, inner2.adb:13:7] |>, + <| ObjectDecl ["X"] inner2.adb:9:13-9:19 [inner2.adb:17:4, inner2.adb:13:7, inner2.adb:14:7] |>] + +Eval '[obj.f_type_expr.p_designated_type_decl for obj in objs]' +Result: [, + ] + +Working on node +==================================================== + +Eval 'node.f_type_expr.p_designated_type_decl' +Result: + +Working on node +============================================================================ + +Set 'obj' to 'node.p_designated_generic_decl.find(lal.ObjectDecl)' +Result: <| ObjectDecl ["X"] test.adb:5:7-5:13 [test.adb:9:4] |> + +Eval 'obj.f_type_expr.p_designated_type_decl' +Result: + +Working on node +============================================================================== + +Set 'obj' to 'node.p_designated_generic_decl.find(lal.ObjectDecl)' +Result: <| ObjectDecl ["X"] test.adb:5:7-5:13 [test.adb:13:4] |> + +Eval 'obj.f_type_expr.p_designated_type_decl' +Result: diff --git a/testsuite/tests/name_resolution/generic_formal_type_default_type/test.yaml b/testsuite/tests/name_resolution/generic_formal_type_default_type/test.yaml new file mode 100644 index 000000000..28cff8fcc --- /dev/null +++ b/testsuite/tests/name_resolution/generic_formal_type_default_type/test.yaml @@ -0,0 +1,2 @@ +driver: inline-playground +input_sources: [test.adb, inner.adb, inner2.adb]