mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-13 09:12:52 -05:00
Don't include completions for current and later parameters (#52690)
This commit is contained in:
@@ -168,6 +168,8 @@ import {
|
||||
isImportKeyword,
|
||||
isImportSpecifier,
|
||||
isInComment,
|
||||
isIndexSignatureDeclaration,
|
||||
isInferTypeNode,
|
||||
isInitializedProperty,
|
||||
isInJSFile,
|
||||
isInRightSideOfInternalImportEqualsDeclaration,
|
||||
@@ -235,6 +237,7 @@ import {
|
||||
isTypeOfExpression,
|
||||
isTypeOnlyImportDeclaration,
|
||||
isTypeOnlyImportOrExportDeclaration,
|
||||
isTypeParameterDeclaration,
|
||||
isTypeReferenceType,
|
||||
isValidTypeOnlyAliasUseSite,
|
||||
isVariableDeclaration,
|
||||
@@ -292,6 +295,7 @@ import {
|
||||
ObjectType,
|
||||
ObjectTypeDeclaration,
|
||||
or,
|
||||
ParameterDeclaration,
|
||||
ParenthesizedTypeNode,
|
||||
positionBelongsToNode,
|
||||
positionIsASICandidate,
|
||||
@@ -360,6 +364,7 @@ import {
|
||||
TypeLiteralNode,
|
||||
TypeNode,
|
||||
TypeOnlyImportDeclaration,
|
||||
TypeParameterDeclaration,
|
||||
TypeQueryNode,
|
||||
TypeReferenceNode,
|
||||
unescapeLeadingUnderscores,
|
||||
@@ -2389,7 +2394,7 @@ export function getCompletionEntriesFromSymbols(
|
||||
includeSymbol = false
|
||||
): UniqueNameSet {
|
||||
const start = timestamp();
|
||||
const variableDeclaration = getVariableDeclaration(location);
|
||||
const variableOrParameterDeclaration = getVariableOrParameterDeclaration(contextToken);
|
||||
const useSemicolons = probablyUsesSemicolons(sourceFile);
|
||||
const typeChecker = program.getTypeChecker();
|
||||
// Tracks unique names.
|
||||
@@ -2463,10 +2468,27 @@ export function getCompletionEntriesFromSymbols(
|
||||
}
|
||||
// Filter out variables from their own initializers
|
||||
// `const a = /* no 'a' here */`
|
||||
if (variableDeclaration && symbol.valueDeclaration === variableDeclaration) {
|
||||
if (tryCast(variableOrParameterDeclaration, isVariableDeclaration) && symbol.valueDeclaration === variableOrParameterDeclaration) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Filter out parameters from their own initializers
|
||||
// `function f(a = /* no 'a' and 'b' here */, b) { }` or
|
||||
// `function f<T = /* no 'T' here */>(a: T) { }`
|
||||
const symbolDeclaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
|
||||
if (variableOrParameterDeclaration && symbolDeclaration && (
|
||||
(isTypeParameterDeclaration(variableOrParameterDeclaration) && isTypeParameterDeclaration(symbolDeclaration)) ||
|
||||
(isParameter(variableOrParameterDeclaration) && isParameter(symbolDeclaration))
|
||||
)) {
|
||||
const symbolDeclarationPos = symbolDeclaration.pos;
|
||||
const parameters = isParameter(variableOrParameterDeclaration) ? variableOrParameterDeclaration.parent.parameters :
|
||||
isInferTypeNode(variableOrParameterDeclaration.parent) ? undefined :
|
||||
variableOrParameterDeclaration.parent.typeParameters;
|
||||
if (symbolDeclarationPos >= variableOrParameterDeclaration.pos && parameters && symbolDeclarationPos < parameters.end) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// External modules can have global export declarations that will be
|
||||
// available as global keywords in all scopes. But if the external module
|
||||
// already has an explicit export and user only wants to user explicit
|
||||
@@ -5442,17 +5464,22 @@ function isModuleSpecifierMissingOrEmpty(specifier: ModuleReference | Expression
|
||||
return !tryCast(isExternalModuleReference(specifier) ? specifier.expression : specifier, isStringLiteralLike)?.text;
|
||||
}
|
||||
|
||||
function getVariableDeclaration(property: Node): VariableDeclaration | undefined {
|
||||
const variableDeclaration = findAncestor(property, node =>
|
||||
function getVariableOrParameterDeclaration(contextToken: Node | undefined) {
|
||||
if (!contextToken) return;
|
||||
|
||||
const declaration = findAncestor(contextToken, node =>
|
||||
isFunctionBlock(node) || isArrowFunctionBody(node) || isBindingPattern(node)
|
||||
? "quit"
|
||||
: isVariableDeclaration(node));
|
||||
|
||||
return variableDeclaration as VariableDeclaration | undefined;
|
||||
: isVariableDeclaration(node) || ((isParameter(node) || isTypeParameterDeclaration(node)) && !isIndexSignatureDeclaration(node.parent)));
|
||||
return declaration as ParameterDeclaration | TypeParameterDeclaration | VariableDeclaration | undefined;
|
||||
}
|
||||
|
||||
function isArrowFunctionBody(node: Node) {
|
||||
return node.parent && isArrowFunction(node.parent) && node.parent.body === node;
|
||||
return node.parent && isArrowFunction(node.parent) &&
|
||||
(node.parent.body === node ||
|
||||
// const a = () => /**/;
|
||||
node.kind === SyntaxKind.EqualsGreaterThanToken
|
||||
);
|
||||
}
|
||||
|
||||
/** True if symbol is a type or a module containing at least one type. */
|
||||
|
||||
@@ -7,6 +7,5 @@
|
||||
|
||||
verify.completions({
|
||||
marker: "1",
|
||||
// Note: `c: typeof c` would be a compile error
|
||||
includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"],
|
||||
includes: ["foo", "x", "y", "z", "bar", "a", "b"],
|
||||
});
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
verify.completions({
|
||||
marker: "1",
|
||||
// Note: `c = c` would be a compile error
|
||||
includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"],
|
||||
includes: ["foo", "x", "y", "z", "bar", "a", "b"],
|
||||
});
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
verify.completions({
|
||||
marker: "1",
|
||||
// Note: `b = b` or `b = c` would be a compile error
|
||||
includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"],
|
||||
includes: ["foo", "x", "y", "z", "bar", "a"],
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
verify.completions({
|
||||
marker: "1",
|
||||
// Note: `v = v` would be a compile error
|
||||
includes: ["foo", "x", "y", "z", "bar", "a", "b", "c", "v"],
|
||||
includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"],
|
||||
isNewIdentifierLocation: true,
|
||||
});
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
////var C4 = class D<T extends /*4*/>{}
|
||||
|
||||
verify.completions({ marker: ["0", "1", "2", "3"], exact: undefined });
|
||||
verify.completions({ marker: "4", exact: completion.globalTypesPlus(["D", "T"]) });
|
||||
verify.completions({ marker: "4", exact: completion.globalTypesPlus(["D"]) });
|
||||
|
||||
@@ -3,5 +3,4 @@
|
||||
////function foo(x: string, y: number, z: boolean) {
|
||||
//// function bar(a: number, b: string, c: typeof /*1*/
|
||||
|
||||
// Note: Ideally `c` wouldn't be included since it hasn't been initialized yet.
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"]})
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b"]})
|
||||
|
||||
@@ -4,5 +4,4 @@
|
||||
//// function bar(a: number, b: string, c: typeof /*1*/
|
||||
////}
|
||||
|
||||
// Note: Ideally `c` wouldn't be included since it hasn't been initialized yet.
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"]})
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b"]})
|
||||
|
||||
@@ -3,5 +3,4 @@
|
||||
////function foo(x: string, y: number, z: boolean) {
|
||||
//// function bar(a: number, b: string, c: typeof x = /*1*/
|
||||
|
||||
// Note: Ideally `c` wouldn't be included since it hasn't been initialized yet.
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"]})
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b"]})
|
||||
|
||||
@@ -4,5 +4,4 @@
|
||||
//// function bar(a: number, b: string, c: typeof x = /*1*/
|
||||
////}
|
||||
|
||||
// Note: Ideally `c` wouldn't be included since it hasn't been initialized yet.
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"]})
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b"]})
|
||||
|
||||
@@ -4,5 +4,4 @@
|
||||
//// function bar(a: number, b: string = /*1*/, c: typeof x = "hello"
|
||||
////
|
||||
|
||||
// Note: Ideally `c` wouldn't be included since it hasn't been initialized yet.
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"]})
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a"]})
|
||||
|
||||
@@ -4,5 +4,4 @@
|
||||
//// function bar(a: number, b: string = /*1*/, c: typeof x = "hello"
|
||||
////}
|
||||
|
||||
// Note: Ideally `c` wouldn't be included since it hasn't been initialized yet.
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"]})
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a"]})
|
||||
|
||||
@@ -4,5 +4,4 @@
|
||||
//// function bar(a: number, b: string = "hello", c: typeof x = "hello") {
|
||||
//// var v = /*1*/
|
||||
|
||||
// Note: "v" questionable since we're in its initializer
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c", "v"], isNewIdentifierLocation: true });
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"], isNewIdentifierLocation: true });
|
||||
|
||||
@@ -5,5 +5,4 @@
|
||||
//// var v = /*1*/
|
||||
////}
|
||||
|
||||
// Note: "v" questionable since we're in its initializer
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c", "v"], isNewIdentifierLocation: true });
|
||||
verify.completions({ marker: "1", includes: ["foo", "x", "y", "z", "bar", "a", "b", "c"], isNewIdentifierLocation: true });
|
||||
|
||||
@@ -46,8 +46,7 @@ verify.completions({
|
||||
|
||||
verify.completions({
|
||||
marker: ["7"],
|
||||
includes: ["a", "b", "c", "d", "e"],
|
||||
excludes: ["fn"],
|
||||
includes: ["a", "b", "c", "d", "e", "fn"],
|
||||
});
|
||||
|
||||
verify.completions({
|
||||
@@ -59,4 +58,3 @@ verify.completions({
|
||||
marker: ["9"],
|
||||
includes: ["a", "b", "c", "d", "e", "fn"],
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// function f1(a = /*1*/, b) { }
|
||||
//// function f2(a = a/*2*/, b) { }
|
||||
//// function f3(a = a + /*3*/, b = a/*4*/, c = /*5*/) { }
|
||||
//// function f3(a) {
|
||||
//// function f4(b = /*6*/, c) { }
|
||||
//// }
|
||||
//// const f5 = (a, b = (c = /*7*/, e) => { }, d = b) => { }
|
||||
////
|
||||
//// type A1<K = /*T1*/, L> = K
|
||||
//// type A2<K extends /*T2*/, L> = K
|
||||
|
||||
verify.completions({
|
||||
marker: ["1", "2"],
|
||||
excludes: ["a", "b"],
|
||||
})
|
||||
verify.completions({
|
||||
marker: ["3"],
|
||||
excludes: ["a", "b"],
|
||||
})
|
||||
|
||||
verify.completions({
|
||||
marker: ["4"],
|
||||
includes: ["a"],
|
||||
})
|
||||
|
||||
verify.completions({
|
||||
marker: ["5"],
|
||||
includes: ["a", "b"],
|
||||
})
|
||||
|
||||
verify.completions({
|
||||
marker: ["6"],
|
||||
excludes: ["b", "c"],
|
||||
includes: ["a"],
|
||||
})
|
||||
|
||||
verify.completions({
|
||||
marker: ["7"],
|
||||
includes: ["a", "b", "d"],
|
||||
})
|
||||
|
||||
verify.completions({
|
||||
marker: ["T1", "T2"],
|
||||
excludes: ["K", "L"],
|
||||
})
|
||||
Reference in New Issue
Block a user