-
Notifications
You must be signed in to change notification settings - Fork 0
Offer semantic services alongside AST #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
parser.js
Outdated
if (shouldProvideParserServices) { | ||
const FILENAME = options.filePath; | ||
const programs = calculateProjectParserOptions(code, options, extra); | ||
for (const program of programs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for multiple programs to own the same file? Do you have to instead filter the project list down and then operate on all projects at once? Disclaimer: I don't know what the right workflow is. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider the following project structure:
- tsconfig.json representing proj1, which includes export1.ts and import.ts
- tsconfig.json representing proj2, which includes export2.ts and the same import.ts
where both export files define a namespace Blah
with members foo
that differ in type.
If foo
is referenced in import.ts, then while find-all-ref points to all three sites, go-to-def and quick info just sorta... pick one.
I feel like this is the most analogous situation to what we have here, where multiple programs own the same file and would give different semantic information for a node in a file being linted. Therefore, I think it's appropriate for us here to just pick one program in their listed order in the eslint config file (and of course doc it as such).
cef5165
to
8a388ad
Compare
8a388ad
to
ea1f7ce
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like we're calling ts.createProgram
once per source file? That would be really bad for performance as createProgram
will follow all imports and parse those too.
/** | ||
* TODO: Remove dependency on private TypeScript method | ||
*/ | ||
return ts.findNextToken(previousToken, parent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should just make this public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the implementation I wrote differs very slightly (but importantly) from our implementation, so we should fix that too. But that's why I had to change it.
* @param {string} code The code being linted | ||
* @param {Object} options Options provided by ESLint core | ||
* @param {string} options.cwd The current working directory for the eslint process | ||
* @param {string} options.filePath The path of the file being parsed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So do we need to redo this for each file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, currently each file iterates through the tsconfigs provided, grabs the corresponding programs from their cached watches, and then finds the right one to pass to the rules.
@Andy-MS Unless I'm missing something, we shouldn't be doing |
@sheetalkamat would know more about performance. |
General organization of changes:
project
, which takes either a single project file path or an array of project file paths (top-levelparser.js
)tsconfig-parser.js
)--fix
or when ESLint is used as a server, as it is in VS) are tracked by the TS watch API.convert.js
, passed up throughast-converter.js
to top-level).convert.js
to avoid having to ensure parent pointers are set in the TS AST (that is to say, for efficiency).parser.js
)Note that the features added by this PR are entirely enabled or disabled (from the consumer's perspective) by the
project
option; the fallback behavior is the existing behavior.I also added test coverage to ensure the two-way mapping is consistent (i.e.
ts2es(es2ts(node)) = node
) and that the exposed checker is usable as a rule might expect.Map approach is based on eslint/typescript-eslint-parser#415