You can view, comment on, or merge this pull request online at:
https://github.com/geany/geany/pull/3166
-- Commit Summary --
* Add ADA ctags parser
-- File Changes --
M ctags/Makefile.am (1) A ctags/parsers/ada.c (2395) M meson.build (1) M src/filetypes.c (2) M src/tagmanager/tm_parser.c (39) M src/tagmanager/tm_parser.h (1) M src/tagmanager/tm_parsers.h (3) M tests/ctags/Makefile.am (6) A tests/ctags/ada-adb.adb (35) A tests/ctags/ada-adb.adb.tags (8) A tests/ctags/ada-ads.ads (50) A tests/ctags/ada-ads.ads.tags (17) A tests/ctags/ada-expression-function-generic.adb (18) A tests/ctags/ada-expression-function-generic.adb.tags (5) A tests/ctags/ada-expression-function.adb (38) A tests/ctags/ada-expression-function.adb.tags (10) A tests/ctags/ada-overriding.ads (42) A tests/ctags/ada-overriding.ads.tags (4) A tests/ctags/ada-package-generic.ads (14) A tests/ctags/ada-package-generic.ads.tags (6) M tests/meson.build (6)
-- Patch Links --
https://github.com/geany/geany/pull/3166.patch https://github.com/geany/geany/pull/3166.diff
@kugel- approved this pull request.
Seems alright but I also don't know ada at all.
From quicky looking over the wikipedia article, Ada seems to offer a great many ways to declare types (and even subtypes). I haven't seen this in the test files. I hope the parser copes with them.
Its literally, erm ... decades since I did any Ada, and I am not sure how much the language may have changed since then, but IIRC it doesn't have any more complex types than any other modern OO language, C++, Go, Rust etc but it does allow lots of constraints on them. But constraints are not of interest to ctags so (from a quick squiz at ada.c) they are simply skipped. Same with renames etc.
So the actual parser "copes" by ignoring. :smile: Only composite type definitions need their contents parsing.
The underlying Ada syntax is far more consistent than C/C++ so extracting the parts of interest is simpler than for those languages so I am not surprised the parser is simpler than the new C++ parser.
That said @kugel- is probably right that the tests don't cover all the options, but Ada users can always PR more tests upstream.
From quicky looking over the wikipedia article, Ada seems to offer a great many ways to declare types (and even subtypes). I haven't seen this in the test files. I hope the parser copes with them.
Yeah, quite possibly and this is really the impression I got when looking at the examples. But at the same time I just gave up studying it in greater detail because this isn't something one ever wants to learn ;-).
Well, using the wikipedia article as a reference you will notice that the syntax is basically `"type" name "is" something` or `"subtype" name "is" something` and in all cases except `"type" name "is" "record" something` ctags doesn't care about what is in the something, its not a compiler, the only thing it cares about is the one with internal name declarations, records.
Similarly functions and procedures are just `"function" name skip_all_this "is" skip_all_this "end"` where the only caveat is its the properly matching end since things nest.
It can all be parsed from the keywords, Ada is not a context sensitive language.
@elextr Syntax is fine, it's very Pascal-like and not very hard to parse I think. But it's all those language features like "subprograms", "subtasks", "subprogram specifications" etc. which make the language crazy. I mapped them to the TM types somehow but I don't claim it is right. But this can be improved when some real ADA users start complaining.
@elextr commented on this pull request.
I have run out of time to look at the mapping of the more esoteric Ada tag types, need to RTFC to see what they actually mean.
@@ -942,6 +942,43 @@ static TMParserMapGroup group_GDSCRIPT[] = {
{_("Other"), TM_ICON_OTHER, tm_tag_other_t}, };
+static TMParserMapEntry map_ADA[] = { + {'P', tm_tag_package_t}, // packspec + {'p', tm_tag_package_t}, // package + {'T', tm_tag_typedef_t}, // typespec + {'t', tm_tag_typedef_t}, // type + {'U', tm_tag_undef_t}, // subspec
Both `U` and `u` are just another way of defining a type, I would have made them `typedef`
@@ -942,6 +942,43 @@ static TMParserMapGroup group_GDSCRIPT[] = {
{_("Other"), TM_ICON_OTHER, tm_tag_other_t}, };
+static TMParserMapEntry map_ADA[] = { + {'P', tm_tag_package_t}, // packspec + {'p', tm_tag_package_t}, // package + {'T', tm_tag_typedef_t}, // typespec + {'t', tm_tag_typedef_t}, // type + {'U', tm_tag_undef_t}, // subspec + {'u', tm_tag_undef_t}, // subtype + {'c', tm_tag_member_t}, // component + {'l', tm_tag_enumerator_t}, // literal + {'V', tm_tag_variable_t}, // varspec + {'v', tm_tag_variable_t}, // variable + {'f', tm_tag_undef_t}, // formal
Its time tagmanager got to know more kinds, the `z` kind (template parameter) in the new cxx parser is also mapped to undefined. Would be good if parameter names and generic/template parameters were available to autocomplete, although that then needs scope to avoid overloading the autocompletes. But the use of folds as an initial scope as Geany does for the status bar scope would be a good start.
@@ -942,6 +942,43 @@ static TMParserMapGroup group_GDSCRIPT[] = {
{_("Other"), TM_ICON_OTHER, tm_tag_other_t}, };
+static TMParserMapEntry map_ADA[] = { + {'P', tm_tag_package_t}, // packspec + {'p', tm_tag_package_t}, // package + {'T', tm_tag_typedef_t}, // typespec + {'t', tm_tag_typedef_t}, // type + {'U', tm_tag_undef_t}, // subspec + {'u', tm_tag_undef_t}, // subtype + {'c', tm_tag_member_t}, // component + {'l', tm_tag_enumerator_t}, // literal + {'V', tm_tag_variable_t}, // varspec + {'v', tm_tag_variable_t}, // variable + {'f', tm_tag_undef_t}, // formal + {'n', tm_tag_macro_t}, // constant + {'x', tm_tag_undef_t}, // exception + {'R', tm_tag_function_t}, // subprogspec
I would have mapped this to `tm_tag_prototype_t`, thats effectively what it is.
- {'P', tm_tag_package_t}, // packspec
+ {'p', tm_tag_package_t}, // package + {'T', tm_tag_typedef_t}, // typespec + {'t', tm_tag_typedef_t}, // type + {'U', tm_tag_undef_t}, // subspec + {'u', tm_tag_undef_t}, // subtype + {'c', tm_tag_member_t}, // component + {'l', tm_tag_enumerator_t}, // literal + {'V', tm_tag_variable_t}, // varspec + {'v', tm_tag_variable_t}, // variable + {'f', tm_tag_undef_t}, // formal + {'n', tm_tag_macro_t}, // constant + {'x', tm_tag_undef_t}, // exception + {'R', tm_tag_function_t}, // subprogspec + {'r', tm_tag_function_t}, // subprogram + {'K', tm_tag_method_t}, // taskspec
If a task is called a "method" (which is fine its a function running in a new thread) then a taskspec is probably a prototype maybe (unsure sounding tone of voice).
@techee agree, my last two posts were aimed at addressing @kugel- concern "I hope the parser copes with them" and the list of c tags kinds at line 120 indeed suggests that it copes ... by recognising them.
Agree the mapping is difficult, my partial contribution in review comments. As I ranted in one of them, time tagmanager learned some more tag types and static scope limits (and no I'm not offering to do it ;-).
Agree the mapping is difficult, my partial contribution in review comments.
Thanks, will have a look at them.
As I ranted in one of them, time tagmanager learned some more tag types and static scope limits (and no I'm not offering to do it ;-).
Agree. Maybe simply some more of `tm_tag_other_t` like `tm_tag_other2_t`, `tm_tag_other3_t`, `tm_tag_other4_t` for things we don't care about in TM and for which we don't do anything special.
@techee pushed 1 commit.
a16f31fb4ad09d1ef271e1a00cfdda13f0026e51 fixup! Add ADA ctags parser
@elextr I did more or less what you suggested but no matter how I tried (and with ADA no guarantees I "tried correctly") I could't get the 'U' and 'V' tags generated so I disabled them. I also added unit tests for those kinds that were missing.
How do I tell if I'm getting those tags?
I'm not sure what a typespec (as distinct from a type) is meant to be, its not an Ada language thing really. The code in ada.c seems to consider something like `type foo;` as a spec, but only seems to use that for packages and procedures, not types and variables. But its unclear with a simple inspection. Oh well, if someone can find an example where ctags outputs U or V then we will know what to do with them.
How do I tell if I'm getting those tags?
Best to use universal-ctags directly - we now have the same parsers.
I'm not sure what a typespec (as distinct from a type) is meant to be, its not an Ada language thing really. The code in ada.c seems to consider something like type foo; as a spec, but only seems to use that for packages and procedures, not types and variables. But its unclear with a simple inspection. Oh well, if someone can find an example where ctags outputs U or V then we will know what to do with them.
My guess was those were from the `.ads` files (which I assume are those defining interface) instead of `.adb` which seem to be those with implementation. But despite placing some variables there, I didn't get the corresponding tags.
Best to use universal-ctags directly - we now have the same parsers.
Ok, thats what I did, using uctags current git, I just thought you might have some debugging magic.
My guess was those were from the .ads files (which I assume are those defining interface) instead of .adb which seem to be those with implementation. But despite placing some variables there, I didn't get the corresponding tags.
Yes, `.ads` is specification and `.adb` is body, but Ada is not totally prescriptive about it IIRC, and AFAICT uctags just parses them both the same. Package specs and procedure specs tags will get generated as you said, but uctags seems to parse type specs, find there is no `is` clause, set the `isSpec` bool and would generate `U`, but then decide its just a forward (using C terminology) and so doesn't create a tag for it since it will be declared properly later. It doesn't say so for types but has a comment to that effect on something else. I didn't look at the code but probably the same is true for `V`.
Ok, thats what I did, using uctags current git, I just thought you might have some debugging magic.
Oh, and one more thing, you should add `--kinds-all=*` because I think these particular kinds aren't enabled by default (or you could enable just these particular kinds to filter-out those you are not interested in). Another option is to map them to something in Geany, create a sidebar group for them and check if they appear in the sidebar.
Is there anything left to be done here?
Not that I can tell, the U and V tags seem not to be generated, so it doesn't matter what they map to. Otherwise IIRC it was ok.
@techee pushed 1 commit.
2ed8955886b142a44e6bb69dc30f75d4bd02063b Add ADA ctags parser
Merged #3166 into master.
github-comments@lists.geany.org