mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Move to language service
This commit is contained in:
@@ -424,6 +424,10 @@ namespace ts.server {
|
||||
return renameInfo;
|
||||
}
|
||||
|
||||
getSelectionRange() {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] {
|
||||
if (!this.lastRenameEntry ||
|
||||
this.lastRenameEntry.inputs.fileName !== fileName ||
|
||||
|
||||
@@ -472,6 +472,9 @@ namespace Harness.LanguageService {
|
||||
getRenameInfo(fileName: string, position: number, options?: ts.RenameInfoOptions): ts.RenameInfo {
|
||||
return unwrapJSONCallResult(this.shim.getRenameInfo(fileName, position, options));
|
||||
}
|
||||
getSelectionRange(fileName: string, position: number): ts.SelectionRange {
|
||||
return unwrapJSONCallResult(this.shim.getSelectionRange(fileName, position));
|
||||
}
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): ts.RenameLocation[] {
|
||||
return unwrapJSONCallResult(this.shim.findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename));
|
||||
}
|
||||
|
||||
@@ -132,6 +132,8 @@ namespace ts.server.protocol {
|
||||
GetEditsForFileRenameFull = "getEditsForFileRename-full",
|
||||
ConfigurePlugin = "configurePlugin",
|
||||
SelectionRange = "selectionRange",
|
||||
/* @internal */
|
||||
SelectionRangeFull = "selectionRange-full",
|
||||
|
||||
// NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`.
|
||||
}
|
||||
|
||||
@@ -1744,14 +1744,6 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
private locationsAreEqual(a: protocol.Location, b: protocol.Location): boolean {
|
||||
return a.line === b.line && a.offset === b.offset;
|
||||
}
|
||||
|
||||
private locationTextSpansAreEqual(a: protocol.TextSpan, b: protocol.TextSpan): boolean {
|
||||
return this.locationsAreEqual(a.start, b.start) && this.locationsAreEqual(a.end, b.end);
|
||||
}
|
||||
|
||||
private getNavigationTree(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationTree | NavigationTree | undefined {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const tree = languageService.getNavigationTree(file);
|
||||
@@ -2067,33 +2059,28 @@ namespace ts.server {
|
||||
this.projectService.configurePlugin(args);
|
||||
}
|
||||
|
||||
private getSelectionRange(args: protocol.SelectionRangeRequestArgs): protocol.SelectionRange[] {
|
||||
private getSelectionRange(args: protocol.SelectionRangeRequestArgs, simplifiedResult: boolean) {
|
||||
const { locations } = args;
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
|
||||
|
||||
const sourceFile = languageService.getNonBoundSourceFile(file);
|
||||
const scriptInfo = Debug.assertDefined(this.projectService.getScriptInfo(file));
|
||||
|
||||
return map(locations, location => {
|
||||
const pos = this.getPosition(location, scriptInfo);
|
||||
let selectionRange: protocol.SelectionRange | undefined;
|
||||
const pushSelectionRange = (start: number, end: number, syntaxKind?: SyntaxKind): void => {
|
||||
// Skip ranges that are identical to the parent
|
||||
const textSpan = this.toLocationTextSpan(createTextSpanFromBounds(start, end), scriptInfo);
|
||||
if (!selectionRange || !this.locationTextSpansAreEqual(textSpan, selectionRange.textSpan)) {
|
||||
selectionRange = { textSpan, ...selectionRange && { parent: selectionRange } };
|
||||
if (syntaxKind) {
|
||||
Object.defineProperty(selectionRange, "__debugKind", { value: formatSyntaxKind(syntaxKind) });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getSelectionRange(pos, sourceFile, pushSelectionRange);
|
||||
return selectionRange!;
|
||||
const selectionRange = languageService.getSelectionRange(file, pos);
|
||||
return simplifiedResult ? this.mapSelectionRange(selectionRange, scriptInfo) : selectionRange;
|
||||
});
|
||||
}
|
||||
|
||||
private mapSelectionRange(selectionRange: SelectionRange, scriptInfo: ScriptInfo): protocol.SelectionRange {
|
||||
const result: protocol.SelectionRange = {
|
||||
textSpan: this.toLocationTextSpan(selectionRange.textSpan, scriptInfo),
|
||||
};
|
||||
if (selectionRange.parent) {
|
||||
result.parent = this.mapSelectionRange(selectionRange.parent, scriptInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
getCanonicalFileName(fileName: string) {
|
||||
const name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
return normalizePath(name);
|
||||
@@ -2451,8 +2438,11 @@ namespace ts.server {
|
||||
return this.notRequired();
|
||||
},
|
||||
[CommandNames.SelectionRange]: (request: protocol.SelectionRangeRequest) => {
|
||||
return this.requiredResponse(this.getSelectionRange(request.arguments));
|
||||
}
|
||||
return this.requiredResponse(this.getSelectionRange(request.arguments, /*simplifiedResult*/ true));
|
||||
},
|
||||
[CommandNames.SelectionRangeFull]: (request: protocol.SelectionRangeRequest) => {
|
||||
return this.requiredResponse(this.getSelectionRange(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
});
|
||||
|
||||
public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) {
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
"typingsCache.ts",
|
||||
"project.ts",
|
||||
"editorServices.ts",
|
||||
"selectionRange.ts",
|
||||
"session.ts",
|
||||
"scriptVersionCache.ts"
|
||||
]
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/* @internal */
|
||||
namespace ts.server {
|
||||
namespace ts.SelectionRange {
|
||||
const isImport = or(isImportDeclaration, isImportEqualsDeclaration);
|
||||
|
||||
export function getSelectionRange(pos: number, sourceFile: SourceFile, pushSelectionRange: (start: number, end: number, kind?: SyntaxKind) => void) {
|
||||
pushSelectionRange(sourceFile.getFullStart(), sourceFile.getEnd(), SyntaxKind.SourceFile);
|
||||
export function getSelectionRange(pos: number, sourceFile: SourceFile): ts.SelectionRange {
|
||||
let selectionRange: SelectionRange = {
|
||||
textSpan: createTextSpanFromBounds(sourceFile.getFullStart(), sourceFile.getEnd())
|
||||
};
|
||||
|
||||
// Skip top-level SyntaxList
|
||||
let parentNode = sourceFile.getChildAt(0);
|
||||
@@ -86,8 +88,31 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return selectionRange;
|
||||
|
||||
function pushSelectionRange(start: number, end: number, syntaxKind?: SyntaxKind): void {
|
||||
// Skip ranges that are identical to the parent
|
||||
const textSpan = createTextSpanFromBounds(start, end);
|
||||
if (!selectionRange || !textSpansEqual(textSpan, selectionRange.textSpan)) {
|
||||
selectionRange = { textSpan, ...selectionRange && { parent: selectionRange } };
|
||||
if (syntaxKind) {
|
||||
Object.defineProperty(selectionRange, "__debugKind", { value: formatSyntaxKind(syntaxKind) });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// function getSiblingExpansionRule<T extends Node>(parentNode: T): (SyntaxKind | SyntaxKind[])[] | undefined {
|
||||
// switch (parentNode.kind) {
|
||||
// case SyntaxKind.BindingElement: return [SyntaxKind.Identifier, SyntaxKind.DotDotDotToken];
|
||||
// case SyntaxKind.Parameter: return [SyntaxKind.Identifier, SyntaxKind.DotDotDotToken, SyntaxKind.QuestionToken];
|
||||
// case SyntaxKind.PropertySignature: return [SyntaxKind.Identifier, SyntaxKind.QuestionToken, SyntaxKind.SyntaxList];
|
||||
// case SyntaxKind.ElementAccessExpression: return [[SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken]];
|
||||
// case SyntaxKind.IndexedAccessType: return [[SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken]];
|
||||
// }
|
||||
// }
|
||||
|
||||
function getGroupBounds<T>(array: ArrayLike<T>, index: number, predicate: (element: T) => boolean): [number, number] {
|
||||
let first = index;
|
||||
let last = index;
|
||||
@@ -2087,6 +2087,10 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function getSelectionRange(fileName: string, position: number): SelectionRange {
|
||||
return SelectionRange.getSelectionRange(position, syntaxTreeCache.getCurrentSourceFile(fileName));
|
||||
}
|
||||
|
||||
function getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences = emptyOptions): ApplicableRefactorInfo[] {
|
||||
synchronizeHostData();
|
||||
const file = getValidSourceFile(fileName);
|
||||
@@ -2134,6 +2138,7 @@ namespace ts {
|
||||
getBreakpointStatementAtPosition,
|
||||
getNavigateToItems,
|
||||
getRenameInfo,
|
||||
getSelectionRange,
|
||||
findRenameLocations,
|
||||
getNavigationBarItems,
|
||||
getNavigationTree,
|
||||
|
||||
@@ -165,6 +165,7 @@ namespace ts {
|
||||
* { canRename: boolean, localizedErrorMessage: string, displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, triggerSpan: { start; length } }
|
||||
*/
|
||||
getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): string;
|
||||
getSelectionRange(fileName: string, position: number): string;
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
@@ -838,6 +839,13 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
public getSelectionRange(fileName: string, position: number): string {
|
||||
return this.forwardJSONCall(
|
||||
`getSelectionRange('${fileName}', ${position})`,
|
||||
() => this.languageService.getSelectionRange(fileName, position)
|
||||
);
|
||||
}
|
||||
|
||||
public findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): string {
|
||||
return this.forwardJSONCall(
|
||||
`findRenameLocations('${fileName}', ${position}, ${findInStrings}, ${findInComments}, ${providePrefixAndSuffixTextForRename})`,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"patternMatcher.ts",
|
||||
"preProcess.ts",
|
||||
"rename.ts",
|
||||
"selectionRange.ts",
|
||||
"signatureHelp.ts",
|
||||
"sourcemaps.ts",
|
||||
"suggestionDiagnostics.ts",
|
||||
|
||||
@@ -297,6 +297,8 @@ namespace ts {
|
||||
getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): RenameInfo;
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): ReadonlyArray<RenameLocation> | undefined;
|
||||
|
||||
getSelectionRange(fileName: string, position: number): SelectionRange;
|
||||
|
||||
getDefinitionAtPosition(fileName: string, position: number): ReadonlyArray<DefinitionInfo> | undefined;
|
||||
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan | undefined;
|
||||
getTypeDefinitionAtPosition(fileName: string, position: number): ReadonlyArray<DefinitionInfo> | undefined;
|
||||
@@ -859,6 +861,11 @@ namespace ts {
|
||||
isOptional: boolean;
|
||||
}
|
||||
|
||||
export interface SelectionRange {
|
||||
textSpan: TextSpan;
|
||||
parent?: SelectionRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a single signature to show in signature help.
|
||||
* The id is used for subsequent calls into the language service to ask questions about the
|
||||
|
||||
Reference in New Issue
Block a user