feat(language-service): Implement definitionAndBoundSpan
(#30125)
This PR adds the implementation for `definitionAndBoundSpan` because it's now preferred over `definition`. vscode would send this new request for `Go to definition`. As part of this PR the implementation for `definition` is refactored and simplified. Goldens for both methods are checked in. PR Close #30125
This commit is contained in:

committed by
Andrew Kushnir

parent
67012509a8
commit
f4916730b5
@ -10,7 +10,7 @@ import * as ts from 'typescript'; // used as value, passed in by tsserver at run
|
||||
import * as tss from 'typescript/lib/tsserverlibrary'; // used as type only
|
||||
|
||||
import {createLanguageService} from './language_service';
|
||||
import {Completion, Diagnostic, DiagnosticMessageChain} from './types';
|
||||
import {Completion, Diagnostic, DiagnosticMessageChain, Location} from './types';
|
||||
import {TypeScriptServiceHost} from './typescript_host';
|
||||
|
||||
const projectHostMap = new WeakMap<tss.server.Project, TypeScriptServiceHost>();
|
||||
@ -156,36 +156,61 @@ export function create(info: tss.server.PluginCreateInfo): ts.LanguageService {
|
||||
return base;
|
||||
};
|
||||
|
||||
proxy.getDefinitionAtPosition = function(
|
||||
fileName: string, position: number): ReadonlyArray<ts.DefinitionInfo> {
|
||||
let base = oldLS.getDefinitionAtPosition(fileName, position);
|
||||
if (base && base.length) {
|
||||
return base;
|
||||
}
|
||||
proxy.getDefinitionAtPosition = function(fileName: string, position: number):
|
||||
ReadonlyArray<ts.DefinitionInfo>|
|
||||
undefined {
|
||||
const base = oldLS.getDefinitionAtPosition(fileName, position);
|
||||
if (base && base.length) {
|
||||
return base;
|
||||
}
|
||||
const ours = ls.getDefinitionAt(fileName, position);
|
||||
if (ours && ours.length) {
|
||||
return ours.map((loc: Location) => {
|
||||
return {
|
||||
fileName: loc.fileName,
|
||||
textSpan: {
|
||||
start: loc.span.start,
|
||||
length: loc.span.end - loc.span.start,
|
||||
},
|
||||
name: '',
|
||||
kind: ts.ScriptElementKind.unknown,
|
||||
containerName: loc.fileName,
|
||||
containerKind: ts.ScriptElementKind.unknown,
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return tryOperation('get definition', () => {
|
||||
const ours = ls.getDefinitionAt(fileName, position);
|
||||
let combined;
|
||||
|
||||
if (ours && ours.length) {
|
||||
combined = base && base.concat([]) || [];
|
||||
for (const loc of ours) {
|
||||
combined.push({
|
||||
fileName: loc.fileName,
|
||||
textSpan: {start: loc.span.start, length: loc.span.end - loc.span.start},
|
||||
name: '',
|
||||
// TODO: remove any and fix type error.
|
||||
kind: 'definition' as any,
|
||||
containerName: loc.fileName,
|
||||
containerKind: 'file' as any,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
combined = base;
|
||||
}
|
||||
return combined;
|
||||
}) || [];
|
||||
};
|
||||
proxy.getDefinitionAndBoundSpan = function(fileName: string, position: number):
|
||||
ts.DefinitionInfoAndBoundSpan |
|
||||
undefined {
|
||||
const base = oldLS.getDefinitionAndBoundSpan(fileName, position);
|
||||
if (base && base.definitions && base.definitions.length) {
|
||||
return base;
|
||||
}
|
||||
const ours = ls.getDefinitionAt(fileName, position);
|
||||
if (ours && ours.length) {
|
||||
return {
|
||||
definitions: ours.map((loc: Location) => {
|
||||
return {
|
||||
fileName: loc.fileName,
|
||||
textSpan: {
|
||||
start: loc.span.start,
|
||||
length: loc.span.end - loc.span.start,
|
||||
},
|
||||
name: '',
|
||||
kind: ts.ScriptElementKind.unknown,
|
||||
containerName: loc.fileName,
|
||||
containerKind: ts.ScriptElementKind.unknown,
|
||||
};
|
||||
}),
|
||||
textSpan: {
|
||||
start: ours[0].span.start,
|
||||
length: ours[0].span.end - ours[0].span.start,
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return proxy;
|
||||
}
|
||||
|
Reference in New Issue
Block a user