add supports of completion label list (#20362)
This commit is contained in:
parent
3a3bb8e3f0
commit
ae25d09761
2 changed files with 87 additions and 0 deletions
|
@ -39,6 +39,11 @@ namespace ts.Completions {
|
||||||
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
|
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contextToken = findPrecedingToken(position, sourceFile);
|
||||||
|
if (isInBreakOrContinue(contextToken)) {
|
||||||
|
return getLabelCompletionAtPosition(contextToken);
|
||||||
|
}
|
||||||
|
|
||||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, compilerOptions.target);
|
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, compilerOptions.target);
|
||||||
if (!completionData) {
|
if (!completionData) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -223,6 +228,18 @@ namespace ts.Completions {
|
||||||
return uniques;
|
return uniques;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isInBreakOrContinue(contextToken: Node): boolean {
|
||||||
|
return contextToken && isBreakOrContinueStatement(contextToken.parent) &&
|
||||||
|
(contextToken.kind === SyntaxKind.BreakKeyword || contextToken.kind === SyntaxKind.ContinueKeyword || contextToken.kind === SyntaxKind.Identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLabelCompletionAtPosition(contextToken: Node): CompletionInfo | undefined {
|
||||||
|
const entries = getLabelStatementCompletions(contextToken.parent);
|
||||||
|
if (entries.length) {
|
||||||
|
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined {
|
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined {
|
||||||
const node = findPrecedingToken(position, sourceFile);
|
const node = findPrecedingToken(position, sourceFile);
|
||||||
if (!node || node.kind !== SyntaxKind.StringLiteral) {
|
if (!node || node.kind !== SyntaxKind.StringLiteral) {
|
||||||
|
@ -358,6 +375,32 @@ namespace ts.Completions {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLabelStatementCompletions(node: Node): CompletionEntry[] {
|
||||||
|
const entries: CompletionEntry[] = [];
|
||||||
|
const uniques = createMap<true>();
|
||||||
|
let current = node;
|
||||||
|
|
||||||
|
while (current) {
|
||||||
|
if (isFunctionLike(current)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isLabeledStatement(current)) {
|
||||||
|
const name = current.label.text;
|
||||||
|
if (!uniques.has(name)) {
|
||||||
|
uniques.set(name, true);
|
||||||
|
entries.push({
|
||||||
|
name,
|
||||||
|
kindModifiers: ScriptElementKindModifier.none,
|
||||||
|
kind: ScriptElementKind.label,
|
||||||
|
sortText: "0"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current = current.parent;
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>, typeChecker: TypeChecker, uniques = createMap<true>()): void {
|
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>, typeChecker: TypeChecker, uniques = createMap<true>()): void {
|
||||||
if (type && type.flags & TypeFlags.TypeParameter) {
|
if (type && type.flags & TypeFlags.TypeParameter) {
|
||||||
type = typeChecker.getBaseConstraintOfType(type);
|
type = typeChecker.getBaseConstraintOfType(type);
|
||||||
|
|
44
tests/cases/fourslash/completionListWithLabel.ts
Normal file
44
tests/cases/fourslash/completionListWithLabel.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/// <reference path="fourslash.ts"/>
|
||||||
|
|
||||||
|
//// label: while (true) {
|
||||||
|
//// break /*1*/
|
||||||
|
//// continue /*2*/
|
||||||
|
//// testlabel: while (true) {
|
||||||
|
//// break /*3*/
|
||||||
|
//// continue /*4*/
|
||||||
|
//// break tes/*5*/
|
||||||
|
//// continue tes/*6*/
|
||||||
|
//// }
|
||||||
|
//// break /*7*/
|
||||||
|
//// break; /*8*/
|
||||||
|
////}
|
||||||
|
|
||||||
|
goTo.marker("1");
|
||||||
|
verify.completionListContains("label");
|
||||||
|
|
||||||
|
goTo.marker("2");
|
||||||
|
verify.completionListContains("label");
|
||||||
|
verify.not.completionListContains("testlabel");
|
||||||
|
|
||||||
|
goTo.marker("3");
|
||||||
|
verify.completionListContains("label");
|
||||||
|
verify.completionListContains("testlabel");
|
||||||
|
|
||||||
|
goTo.marker("4");
|
||||||
|
verify.completionListContains("label");
|
||||||
|
verify.completionListContains("testlabel");
|
||||||
|
|
||||||
|
goTo.marker("5");
|
||||||
|
verify.completionListContains("testlabel");
|
||||||
|
verify.completionListContains("label");
|
||||||
|
|
||||||
|
goTo.marker("6");
|
||||||
|
verify.completionListContains("testlabel");
|
||||||
|
verify.completionListContains("label");
|
||||||
|
|
||||||
|
goTo.marker("7");
|
||||||
|
verify.completionListContains("label");
|
||||||
|
verify.not.completionListContains("testlabel");
|
||||||
|
|
||||||
|
goTo.marker("8");
|
||||||
|
verify.not.completionListContains("label");
|
Loading…
Reference in a new issue