From 80e1d3ff144477f870c782c6147cf46542dd6e1a Mon Sep 17 00:00:00 2001 From: Romain Beguet Date: Mon, 12 Sep 2022 17:40:49 +0200 Subject: [PATCH] V713-005: Improve `get_aspect` for pragma `Convention` & co. --- ada/ast.py | 22 ++++++++++++++++++- .../get_aspect_pragma_convention/test.adb | 12 ++++++++++ .../get_aspect_pragma_convention/test.out | 11 ++++++++++ .../get_aspect_pragma_convention/test.yaml | 2 ++ user_manual/changes/V713-005.yaml | 21 ++++++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 testsuite/tests/properties/get_aspect_pragma_convention/test.adb create mode 100644 testsuite/tests/properties/get_aspect_pragma_convention/test.out create mode 100644 testsuite/tests/properties/get_aspect_pragma_convention/test.yaml create mode 100644 user_manual/changes/V713-005.yaml diff --git a/ada/ast.py b/ada/ast.py index 2d20ebe5f..fcc448254 100644 --- a/ada/ast.py +++ b/ada/ast.py @@ -9645,6 +9645,26 @@ def xref_equation(): ) ) + @langkit_property(return_type=T.Expr.entity) + def value_expr(): + """ + Return the expression representing the "value" of this pragma, which + will be used to fill the ``value`` field of the ``Aspect`` struct + returned by calls to ``get_aspect``. This property doesn't make sense + for all pragmas but tries to give the most reasonable answer, and in + particular tries to match what ``get_aspect`` would return if the + pragma was replaced by its equivalent aspect. + For example, on ``pragma Convention (C, X)``, the returned value is + ``C`` because one would write ``X : Integer with Convention => C``. + """ + return If( + Entity.id.name_symbol.any_of( + 'Import', 'Export', 'Interface', 'Convention' + ), + Entity.args.at(0).assoc_expr, + Entity.args._.at(1)._.assoc_expr + ) + @langkit_property(return_type=T.Name.entity.array) def associated_entity_names(): return Cond( @@ -15967,7 +15987,7 @@ def get_aspect_impl(name=Symbol): """ return Entity.get_pragma(name).then( lambda p: Aspect.new( - exists=True, node=p, value=p.args._.at(1)._.assoc_expr + exists=True, node=p, value=p.value_expr ) )._or(Entity.basic_decl.get_aspect_assoc(name).then( lambda aa: Aspect.new(exists=True, node=aa, value=aa.expr) diff --git a/testsuite/tests/properties/get_aspect_pragma_convention/test.adb b/testsuite/tests/properties/get_aspect_pragma_convention/test.adb new file mode 100644 index 000000000..0c1f26502 --- /dev/null +++ b/testsuite/tests/properties/get_aspect_pragma_convention/test.adb @@ -0,0 +1,12 @@ +procedure Test is + X : Integer := 0 + with Convention => C; + --% node.p_get_aspect("Convention").value + + Y : Integer := 0; + --% node.p_get_aspect("Convention").value + pragma Convention (C, Y); +begin + null; +end Test; + diff --git a/testsuite/tests/properties/get_aspect_pragma_convention/test.out b/testsuite/tests/properties/get_aspect_pragma_convention/test.out new file mode 100644 index 000000000..81ee29cf3 --- /dev/null +++ b/testsuite/tests/properties/get_aspect_pragma_convention/test.out @@ -0,0 +1,11 @@ +Working on node +==================================================== + +Eval 'node.p_get_aspect("Convention").value' +Result: + +Working on node +==================================================== + +Eval 'node.p_get_aspect("Convention").value' +Result: diff --git a/testsuite/tests/properties/get_aspect_pragma_convention/test.yaml b/testsuite/tests/properties/get_aspect_pragma_convention/test.yaml new file mode 100644 index 000000000..35ad4d5c4 --- /dev/null +++ b/testsuite/tests/properties/get_aspect_pragma_convention/test.yaml @@ -0,0 +1,2 @@ +driver: inline-playground +input_sources: [test.adb] diff --git a/user_manual/changes/V713-005.yaml b/user_manual/changes/V713-005.yaml new file mode 100644 index 000000000..81bd065dc --- /dev/null +++ b/user_manual/changes/V713-005.yaml @@ -0,0 +1,21 @@ +type: bugfix +title: Improve ``get_aspect`` for ``pragma Convention`` +description: | + Previously, calling ``get_aspect("Convention")`` on the declaration of + ``X`` in the snippet below would return an ``Aspect`` struct whose + ``value`` field would contain the identifier ``X``: + + ..code:: ada + + X : Integer; + pragma Convention (C, X); + + It will now return ``C``, because that's what would have been returned if + one had used the Ada 2012 aspect notation instead: + + ..code:: ada + + X : Integer + with Convention => C; + +date: 2022-09-12