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.
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.
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.
This might be the value you send into the recursive routine to avoid creating new objects.
There was a problem hiding this comment.
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.
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
| * 'x.y' -> ['x', 'y'] | ||
| * 'x' -> ['', 'x'] | ||
| * 'x.y.z' -> ['x.y', 'z'] | ||
| * '' -> ['', ''] |
There was a problem hiding this comment.
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.
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.
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.
...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.
Please remember, use interfaces only when implementing them in classes. Else use types
There was a problem hiding this comment.
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.
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.
Yep. :) This was also left over from trying to use type conversion.
| if (!symbols) { | ||
| return []; | ||
| } | ||
| return symbols! |
There was a problem hiding this comment.
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.
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.
I'll split up utils.ts in a separate PR.
| args, | ||
| token | ||
| ); | ||
| const symbols: SymbolInformation[] = []; |
There was a problem hiding this comment.
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.
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.
Please rename to use a verb, such as createLanguageClient or get..
| }); | ||
|
|
||
| function newDoc( | ||
| uri?: Uri, |
There was a problem hiding this comment.
Please rename to createDoc or getDoc, or similar.
| // helpers | ||
|
|
||
| function newSymbols( | ||
| uri: Uri, |
There was a problem hiding this comment.
Please rename to use a verb in the function name.
E.g. create, get, parse, etc.
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