Skip to content

Commit

Permalink
Merge branch 'topic/1370' into 'master'
Browse files Browse the repository at this point in the history
Fix support for Ada2022 defaults for generic formal types

Closes #1370

See merge request eng/libadalang/libadalang!1678
  • Loading branch information
thvnx committed Jul 10, 2024
2 parents 44cda3c + 0057429 commit 9574683
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 23 deletions.
68 changes: 45 additions & 23 deletions ada/nodes.lkt
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
Working on node <GenericPackageInstantiation ["M"] inner.adb:16:4-16:24>
========================================================================

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: [<ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>,
<ConcreteTypeDecl ["Long_Integer"] __standard:9:3-9:69>]

Working on node <GenericPackageInstantiation ["M"] inner2.adb:17:4-17:24>
=========================================================================

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: [<ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>,
<ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>]

Working on node <ObjectDecl ["X"] test.adb:5:7-5:13>
====================================================

Eval 'node.f_type_expr.p_designated_type_decl'
Result: <FormalTypeDecl ["T"] test.adb:3:7-3:41>

Working on node <GenericPackageInstantiation ["My_Pkg_1"] test.adb:9:4-9:32>
============================================================================

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: <ConcreteTypeDecl ["Integer"] __standard:4:3-4:54>

Working on node <GenericPackageInstantiation ["My_Pkg_2"] test.adb:13:4-13:47>
==============================================================================

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: <ConcreteTypeDecl ["Long_Integer"] __standard:9:3-9:69>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
driver: inline-playground
input_sources: [test.adb, inner.adb, inner2.adb]

0 comments on commit 9574683

Please sign in to comment.