-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Use symbol provider from new language server to place code lenses in tests. #2456
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
Use symbol provider from new language server to place code lenses in tests. #2456
Conversation
|
FWIW, I don't see any difference with this PR applied locally. Code lenses are not showing up (whereas they do for Jedi)... |
|
I used the repro case detailed in #1948 (comment). |
|
Looks like the data returned from the language server doesn't work quite right. I'll open an issue (or two) as soon as I can. I'm also going to work around the problem for now. |
|
I've opened Language Server issue for things I've had to work around:
Other than that, I had to flatten the data returned from the language server. :) |
d3r3kk
left a comment
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.
You need a news file, and other than that maybe have a look at the comments made on the recursive routine, I'd love to see us not create new objects with each iteration and copy them (and their members) about. If we can get rid of the call .push(...flattenedChild) and instead push each flattened child into the list as it progresses that might help with perf/memory on larger projects.
| } | ||
|
|
||
| function flattenSymbolTree(tree: ILSSymbolTree, uri: Uri, containerName: string = ''): SymbolInformation[] { | ||
| const flattened: SymbolInformation[] = []; |
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.
If we can somehow pass this in as a reference, it might cheapen up the resource cost of this recursion.
| args, | ||
| token | ||
| ); | ||
| const symbols: SymbolInformation[] = []; |
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.
This might be the value you send into the recursive routine to avoid creating new objects.
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 disagree, the API should return an array rather than us passing a state bag that needs to be populated.
Internally the function can use a single array that is passed by ref.
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.
Returning items is better than passing a state bag, e.g if the cost is very expensive then we can always use generators (with yield), that works perfectly here. But if we passed a state bag there's no way to use yield.
|
Approving the changes after a fun academic conversation with @ericsnowcurrently on the cost/benefit and the true costs of his solution vs. my proposal. We are only ever traversing a single file gathering these symbols. Unless that single file is wonderfully complicated in terrible ways, the perf of this solution is not going to be a problem. 👍 |
cbad124 to
631b69a
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.
.
| * 'x.y' -> ['x', 'y'] | ||
| * 'x' -> ['', 'x'] | ||
| * 'x.y.z' -> ['x.y', 'z'] | ||
| * '' -> ['', ''] |
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.
This is illogical. You can't have a parent if name is empty.
It should return undefined, instead of returning incorrect info. This leads to the assumption that there is a parent when there isn't.
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 see your point in a general sense. However, in this case how is '' different from undefined? Using undefined for this seems like more work for everyone.
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.
however that's poor API design!!
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'd like to discuss this more, perhaps in teams, etc. We're not communicating well about this over github. :)
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.
...and I want to make sure we're on the same page with this sort of stuff.
| * A representation of the symbol data the language server provides. | ||
| */ | ||
| interface ILSSymbolTree { | ||
| name: string; |
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.
Please remember, use interfaces only when implementing them in classes. Else use types
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.
Yep. This was an attempt to get type conversion to work right. I ended up doing it a different way but forgot to remove the interface. :)
| detail?: string; | ||
| } | ||
| interface IRange { | ||
| start: IPosition; |
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.
Surely there must be an existing interface we can use for this? Why can't we use what's in VSC?
I can't see where these are used internally!
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.
Yep. :) This was also left over from trying to use type conversion.
| if (!symbols) { | ||
| return []; | ||
| } | ||
| return symbols! |
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.
No need of !
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.
This is your code, not mine. :) I'll fix it.
| * '' -> ['', ''] | ||
| */ | ||
| export function splitFullName(fullName: string): [string, string] { | ||
| if (fullName.length === 0) { |
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.
Please move this function into a separate file such a languageUtils.js, else this file here annoyed to store everything and it's become a very large bag of tricks!
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'll split up utils.ts in a separate PR.
| args, | ||
| token | ||
| ); | ||
| const symbols: SymbolInformation[] = []; |
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 disagree, the API should return an array rather than us passing a state bag that needs to be populated.
Internally the function can use a single array that is passed by ref.
| args, | ||
| token | ||
| ); | ||
| const symbols: SymbolInformation[] = []; |
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.
Returning items is better than passing a state bag, e.g if the cost is very expensive then we can always use generators (with yield), that works perfectly here. But if we passed a state bag there's no way to use yield.
|
|
||
| suite('Language Server Symbol Provider', () => { | ||
|
|
||
| function newLanguageClient( |
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.
Please rename to use a verb, such as createLanguageClient or get..
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.
fixed
| }); | ||
|
|
||
| function newDoc( | ||
| uri?: Uri, |
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.
Please rename to createDoc or getDoc, or similar.
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.
fixed
| // helpers | ||
|
|
||
| function newSymbols( | ||
| uri: Uri, |
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.
Please rename to use a verb in the function name.
E.g. create, get, parse, etc.
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.
fixed
I'm going to merge this with only a couple of Don's concerns still open. We can address those separately.
This is a follow-up to #2456. I've pulled many of the "util" modules out of src/client/common into a new sibling package to client: utils. This helps us separate the extension-specific code from the generic code we use for the extension.
(fixes #1948)
Any new/changed dependencies inpackage.jsonare pinned (e.g."1.2.3", not"^1.2.3"for the specified version)package-lock.jsonhas been regenerated by runningnpm install(if dependencies have changed)This is a derivative of @DonJayamanne's #2197. Differences:
PythonSymbolProvider->JediSymbolProviderSymbolProvider->LanguageServerSymbolProvider(and moved tosrc/client/providers/symbolProvider.ts)LanguageServerSymbolProvider