From 0057429b34a794cd69c721a0bdd3c14cacc4f6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Th=C3=A9venoux?= Date: Mon, 24 Jun 2024 10:56:58 +0200 Subject: [PATCH] Fix support for Ada2022 defaults for generic formal types --- ada/nodes.lkt | 24 ++++-- .../inner.adb | 27 +++++++ .../inner2.adb | 27 +++++++ .../generic_formal_type_default_type/test.adb | 18 +++++ .../generic_formal_type_default_type/test.out | 73 +++++++++++++++++++ .../test.yaml | 2 + 6 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 testsuite/tests/name_resolution/generic_formal_type_default_type/inner.adb create mode 100644 testsuite/tests/name_resolution/generic_formal_type_default_type/inner2.adb create mode 100644 testsuite/tests/name_resolution/generic_formal_type_default_type/test.adb create mode 100644 testsuite/tests/name_resolution/generic_formal_type_default_type/test.out create mode 100644 testsuite/tests/name_resolution/generic_formal_type_default_type/test.yaml diff --git a/ada/nodes.lkt b/ada/nodes.lkt index b76022823..bc4c52338 100644 --- a/ada/nodes.lkt +++ b/ada/nodes.lkt @@ -14613,13 +14613,23 @@ class BaseId: SingleTokNode implements TokenNode { } ) ).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 + (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 ) @with_dynvars(env, origin) 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]