-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
FAR cleanup and isDefinition definition #48211
Conversation
The test updates were accepted uncritically as the change is very simple and the updates aren't final. TODO: restore semantic functionality in code merging results from multiple projects to un-break VS Code's CodeLens.
This change had two goals: 1. Make the code easier to understand, primarily by simplifying the callback structure and minimizing side-effects 2. Improve performance by reducing repeated work, both FAR searches of individual projects and default tsconfig searches This implementation attempts to preserve the merging order found in the original code (someone less relevant in the present state of using syntactic isDefinition).
...in preparation for implementing isDefinition explicitly.
There are some extra tsconfig searches, but the lookups are cached, so the cost is negligible. I suspect the change is because we now drop redundant searches when dequeuing from the work queue, rather than enqueuing.
...to allow use of the checker when computing isDefinition across projects.
Is this ready to review? It's still marked draft. |
@sandersn Sorry, I should have been clearer about what the status meant. Yes, I would like feedback on the approach now, so I can skip the remaining work if we decide to kill it. |
Before I read the code, re step (4) of isDefinition: is there a separate symbol for each project? I'll see if reading the code clears things up. |
I looked over the first big test and the results seem better for the reference count CodeLens: imports are now definitions and no longer count toward the reference count. However, the definition is isDefinition was so tricky, this apparent improvement might not be desired. You should probably double-check the comment history of previous PRs if you haven't already. |
Also
When you find-all-refs on a declaration of a symbol that has only 1 non-declaration reference, both VS Code and emacs jump to that lone non-declaration. I think that code must rely on isDefinition too—at least the emacs code did when I first wrote it in 2016. In this case, making imports have |
I could be wrong, but I don’t think this is true for VS Code. |
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.
I didn't review the session.ts changes too closely. The findAllReferences changes look OK as far as I understood them but they didn't clear up my original questions.
I like the test changes, so it's likely that this is the right direction.
@@ -1842,8 +1911,7 @@ namespace ts { | |||
|
|||
function getFileReferences(fileName: string): ReferenceEntry[] { | |||
synchronizeHostData(); | |||
const moduleSymbol = program.getSourceFile(fileName)?.symbol; | |||
return FindAllReferences.Core.getReferencesForFileName(fileName, program, program.getSourceFiles()).map(r => FindAllReferences.toReferenceEntry(r, moduleSymbol)); | |||
return FindAllReferences.Core.getReferencesForFileName(fileName, program, program.getSourceFiles()).map(r => FindAllReferences.toReferenceEntry(r)); |
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.
return FindAllReferences.Core.getReferencesForFileName(fileName, program, program.getSourceFiles()).map(r => FindAllReferences.toReferenceEntry(r)); | |
return FindAllReferences.Core.getReferencesForFileName(fileName, program, program.getSourceFiles()).map(FindAllReferences.toReferenceEntry); |
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.
JS this-binding scares me, so I err on the side of using a lambda. If you tell me it does the right thing without it, I'll take your word for it.
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.
can't have undefined this
if you never use this
-tap-tap-
findAllReferences.ts only uses classes in class State
, so only its methods need to be bound to an instance.
Yes, each project has its own symbol IDs and I don't believe there's a way to map between them. |
It does. It has a fallback where it makes a second FAR request, filtered to definitions, if the first returns exactly two results. If exactly one is a definition, it jumps between them. The current (and, I believe, preserved) behavior is that an import counts as a declaration of a separate, alias symbol, so an exported symbol that is exported in exactly one place will cause GTD to hop between the two (since neither is a definition from the other's perspective). |
Overall, I think this is a good direction. Let me know when you mark it Ready for Review and I'll take a harder look at the session.ts changes. |
@sandersn So you believe in this enough that it seems worthwhile to polish it (and probably update a lot of fourslash tests)? I still have some concerns around the costs and the open questions. @andrewbranch Your thoughts? It feels risky to me, so I'd want to get it into the beta if we ship it at all. |
I liked the improvement in semantics quite a bit. Let me look again at the new cost of computing isDefinition. |
Benefits:
Costs:
Open Questions:
Rough explanation of the new isDefinition: