ctags
ctags copied to clipboard
JavaScript: Support import bar from "./bar.js"
The name of the parser:
JavaScript
The command line you used to run ctags:
$ ctags --options=NONE foo.js bar.js
The content of input file:
foo.js
import create from "./bar.js"
bar.js
export default function() {}
The tags output you are not satisfied with:
!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/
!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/
!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/
!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/
!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/
!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/
!_TAG_FIELD_DESCRIPTION input /input file/
!_TAG_FIELD_DESCRIPTION name /tag name/
!_TAG_FIELD_DESCRIPTION pattern /pattern/
!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_KIND_DESCRIPTION!JavaScript C,constant /constants/
!_TAG_KIND_DESCRIPTION!JavaScript G,getter /getters/
!_TAG_KIND_DESCRIPTION!JavaScript M,field /fields/
!_TAG_KIND_DESCRIPTION!JavaScript S,setter /setters/
!_TAG_KIND_DESCRIPTION!JavaScript c,class /classes/
!_TAG_KIND_DESCRIPTION!JavaScript f,function /functions/
!_TAG_KIND_DESCRIPTION!JavaScript g,generator /generators/
!_TAG_KIND_DESCRIPTION!JavaScript m,method /methods/
!_TAG_KIND_DESCRIPTION!JavaScript p,property /properties/
!_TAG_KIND_DESCRIPTION!JavaScript v,variable /global variables/
!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/
!_TAG_OUTPUT_FILESEP slash /slash or backslash/
!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
!_TAG_OUTPUT_VERSION 0.0 /current.age/
!_TAG_PARSER_VERSION!JavaScript 1.1 /current.age/
!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
!_TAG_PROC_CWD /tmp/ctags/ //
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
!_TAG_PROGRAM_VERSION 6.1.0 /v6.1.0/
!_TAG_ROLE_DESCRIPTION!JavaScript!function foreigndecl /declared in foreign languages/
anonymousFunctionf39330450100 bar.js /^export default function() {}$/;" f
The tags output you expect:
I am not sure about the expected output.
The version of ctags:
$ ctags --version
Universal Ctags 6.1.0(v6.1.0), Copyright (C) 2015-2023 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
Compiled: Mar 17 2024, 12:18:39
URL: https://ctags.io/
Output version: 0.0
Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath, +json, +interactive, +sandbox, +yaml, +packcc, +optscript, +pcre2
How do you get ctags binary:
pacman -S ctags
Please note that the anonymousFunctionf39330450100 is not linked to the import statement in foo.js which means that you can't jump tags from foo to bar.
I would like to be able to jump to the anonymousFunctionf39330450100 from foo.js using the create identifier of the import statement.
EDIT: I'm not sure if this is backend or client side (ctags-client-tools).
(I renamed the title Subject to associate the issue and the parser name.)
For languages for programming, the primary task of ctags is to extract names defining language objects.
import create from "./bar.js"
create is not defined in foo.js. Instead, foo.js references to create defined in somewhere.
So, ctags doesn't extract create from foo.js.
create may be defined in bar.js (or js files imported in bar.js).
export default function() {}
In bar.js, create is not defined. So, ctags doesn't make a tag for create.
If I understand ECMAScript correctly, function() {} defines a language object. However, it has no name. In such a case, ctags makes an anonymous tag, as you saw as anonymousFunctionf39330450100.
If you don't want to make tags for the anonymous language objects, use --extras=-{anonymous} option.
These are my understanding. However, I don't know ECMAScript well.
If import create from "./bar.js" binds create to the anonymous function, let me know.
If import create from "./bar.js" binds create to the anonymous function, let me know.
I tried:
$ tree
.
├── bar.js
├── foo.js
└── package.json
1 directory, 3 files
$ for x in *; do echo '#' $x; ; cat $x; echo; done
# bar.js
export default function() { console.log("Hello World!\n"); }
# foo.js
import create from "./bar.js"
create();
# package.json
{
"type": "module",
"main": "./foo.js"
}
$ node foo.js
Hello World!
With import ..., create is bound to the anonymous function.
create should be extracted as a definition tag.
create introduces a new name. However, ctags cannot know its kind when just parsing foo.js.
We must extract create as unknown/Y kind.
We must add a field to anonymousFunctionf39330450100 to know it is exported as part of default.
Related issues and pull requests: #1577 #1581 #3994
I must study the syntax and semantics of import and export. Then, I will write down the specifications for how the JavaScript parser handles import and export, as I defined in ctags-lang-pyohon(7). https://github.com/universal-ctags/ctags/blob/master/docs/man/ctags-lang-python.7.rst
I recongnize again that we need unknown/Y to solve some issues about the JavaScript parser.