From 1bcbd8fa9dff2a9b398b32a8d4dc8f6f5de8e27b Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Sun, 20 Dec 2020 19:40:04 +0800
Subject: [PATCH 01/22] feat: exclude declared variable when Object literal
completions
---
src/services/completions.ts | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 01584d6a5e16b..8e1c399117451 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1508,6 +1508,10 @@ namespace ts.Completions {
return true;
}
+ if (isAncestor(location, symbol)) {
+ return false;
+ }
+
symbol = skipAlias(symbol, typeChecker);
// import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
@@ -1526,6 +1530,12 @@ namespace ts.Completions {
});
}
+ function isAncestor(node: Node, symbol: Symbol): boolean {
+ return !!findAncestor(node, (n) => {
+ return Array.isArray(symbol.declarations) && symbol.declarations.some(declaration => n === declaration)
+ })
+ }
+
function isTypeOnlyCompletion(): boolean {
return insideJsDocTagTypeExpression
|| !isContextTokenValueLocation(contextToken) &&
From 505b1b63491bb737dc5a37f8f83d843f07d19f63 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Mon, 21 Dec 2020 00:03:44 +0800
Subject: [PATCH 02/22] feat: check undeclareVariable when completion
---
src/services/completions.ts | 46 ++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 6 deletions(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 8e1c399117451..a93f0ca0a3baf 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1501,6 +1501,8 @@ namespace ts.Completions {
: KeywordCompletionFilters.TypeKeywords;
}
+ const undeclaredVariable = findUndeclaredVariableIfExist(location);
+
filterMutate(symbols, symbol => {
if (!isSourceFile(location)) {
// export = /**/ here we want to get all meanings, so any symbol is ok
@@ -1508,10 +1510,10 @@ namespace ts.Completions {
return true;
}
- if (isAncestor(location, symbol)) {
+ if (isUndeclaredSymbol(undeclaredVariable, symbol)) {
return false;
}
-
+
symbol = skipAlias(symbol, typeChecker);
// import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
@@ -1530,10 +1532,42 @@ namespace ts.Completions {
});
}
- function isAncestor(node: Node, symbol: Symbol): boolean {
- return !!findAncestor(node, (n) => {
- return Array.isArray(symbol.declarations) && symbol.declarations.some(declaration => n === declaration)
- })
+ function findUndeclaredVariableIfExist(node: Node): VariableDeclaration | undefined {
+ if (!isIdentifier(node)) {
+ return undefined;
+ }
+
+ let curNode: Node = node.parent;
+ while (curNode && curNode.parent) {
+ if (isPropertyAssignment(curNode) && isObjectLiteralExpression(curNode.parent)) {
+ curNode = curNode.parent.parent;
+
+ if (isVariableDeclaration(curNode)) {
+ return curNode;
+ }
+ }
+ else {
+ return undefined;
+ }
+ }
+
+ return undefined;
+ }
+
+ function isUndeclaredSymbol(undeclaredVariable: VariableDeclaration | undefined, symbol: Symbol): boolean {
+ if (!undeclaredVariable) {
+ return false;
+ }
+
+ if (!symbol.declarations || symbol.declarations.length === 0) {
+ return false;
+ }
+
+ if (symbol.declarations.indexOf(undeclaredVariable) > -1) {
+ return true;
+ }
+
+ return false;
}
function isTypeOnlyCompletion(): boolean {
From c8079a40c31103f309c4828dfe6b4e35eb9b7164 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Tue, 22 Dec 2020 10:16:08 +0800
Subject: [PATCH 03/22] feat: add completion test case
---
.../completionListInObjectLiteral5.ts | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 tests/cases/fourslash/completionListInObjectLiteral5.ts
diff --git a/tests/cases/fourslash/completionListInObjectLiteral5.ts b/tests/cases/fourslash/completionListInObjectLiteral5.ts
new file mode 100644
index 0000000000000..0bbe23fe97e0b
--- /dev/null
+++ b/tests/cases/fourslash/completionListInObjectLiteral5.ts
@@ -0,0 +1,24 @@
+///
+
+////const o = 'something'
+////const obj = {
+//// prop: o/*1*/,
+//// pro() {
+//// const obj1 = {
+//// p:{
+//// s: {
+//// h: {
+//// hh: o/*2*/
+//// },
+//// someFun() {
+//// o/*3*/
+//// }
+//// }
+//// }
+//// }
+//// }
+////}
+
+verify.completions({ marker: ["1"], excludes: ['obj'], includes: ['o'] });
+verify.completions({ marker: ["2"], excludes: ['obj1'], includes: ['o', 'obj'] });
+verify.completions({ marker: ["3"], includes: ['o', 'obj', 'obj1'] });
\ No newline at end of file
From 7f2434d35602bedee251c91d50ded9fb1c803ff1 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 23 Dec 2020 09:55:13 +0800
Subject: [PATCH 04/22] feat: code optimization
---
src/services/completions.ts | 26 ++++++--------------------
1 file changed, 6 insertions(+), 20 deletions(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index a93f0ca0a3baf..1676b5c5400ff 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1501,7 +1501,7 @@ namespace ts.Completions {
: KeywordCompletionFilters.TypeKeywords;
}
- const undeclaredVariable = findUndeclaredVariableIfExist(location);
+ const objectLiteralVariableDeclaration = getVariableDeclarationOfObjectLiteral(location);
filterMutate(symbols, symbol => {
if (!isSourceFile(location)) {
@@ -1510,7 +1510,8 @@ namespace ts.Completions {
return true;
}
- if (isUndeclaredSymbol(undeclaredVariable, symbol)) {
+ // Filter out variables from their own initializers, e.g. `const o = { prop: /* no 'o' here */ }`
+ if (objectLiteralVariableDeclaration && symbol.valueDeclaration === objectLiteralVariableDeclaration) {
return false;
}
@@ -1532,12 +1533,12 @@ namespace ts.Completions {
});
}
- function findUndeclaredVariableIfExist(node: Node): VariableDeclaration | undefined {
- if (!isIdentifier(node)) {
+ function getVariableDeclarationOfObjectLiteral(property: Node): VariableDeclaration | undefined {
+ if (!isIdentifier(property)) {
return undefined;
}
- let curNode: Node = node.parent;
+ let curNode: Node = property.parent;
while (curNode && curNode.parent) {
if (isPropertyAssignment(curNode) && isObjectLiteralExpression(curNode.parent)) {
curNode = curNode.parent.parent;
@@ -1554,21 +1555,6 @@ namespace ts.Completions {
return undefined;
}
- function isUndeclaredSymbol(undeclaredVariable: VariableDeclaration | undefined, symbol: Symbol): boolean {
- if (!undeclaredVariable) {
- return false;
- }
-
- if (!symbol.declarations || symbol.declarations.length === 0) {
- return false;
- }
-
- if (symbol.declarations.indexOf(undeclaredVariable) > -1) {
- return true;
- }
-
- return false;
- }
function isTypeOnlyCompletion(): boolean {
return insideJsDocTagTypeExpression
From fe0f9232516c9f134eb38912b264d4e206bb9618 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 23 Dec 2020 10:11:57 +0800
Subject: [PATCH 05/22] feat: support shorthand property assignment
---
src/services/completions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index e3dea1037aff3..c5680ba9c4686 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1543,7 +1543,7 @@ namespace ts.Completions {
let curNode: Node = property.parent;
while (curNode && curNode.parent) {
- if (isPropertyAssignment(curNode) && isObjectLiteralExpression(curNode.parent)) {
+ if ((isPropertyAssignment(curNode) || isShorthandPropertyAssignment(curNode)) && isObjectLiteralExpression(curNode.parent)) {
curNode = curNode.parent.parent;
if (isVariableDeclaration(curNode)) {
From 71c0db9bda67ba0c71b5e5a5ebde5352347187c7 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 23 Dec 2020 10:12:25 +0800
Subject: [PATCH 06/22] feat: add shorthand property assignment test case
---
tests/cases/fourslash/completionListInObjectLiteral5.ts | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tests/cases/fourslash/completionListInObjectLiteral5.ts b/tests/cases/fourslash/completionListInObjectLiteral5.ts
index 0bbe23fe97e0b..eb245d748bf41 100644
--- a/tests/cases/fourslash/completionListInObjectLiteral5.ts
+++ b/tests/cases/fourslash/completionListInObjectLiteral5.ts
@@ -16,9 +16,11 @@
//// }
//// }
//// }
-//// }
+//// },
+//// o/*4*/
////}
verify.completions({ marker: ["1"], excludes: ['obj'], includes: ['o'] });
verify.completions({ marker: ["2"], excludes: ['obj1'], includes: ['o', 'obj'] });
-verify.completions({ marker: ["3"], includes: ['o', 'obj', 'obj1'] });
\ No newline at end of file
+verify.completions({ marker: ["3"], includes: ['o', 'obj', 'obj1'] });
+verify.completions({ marker: ["4"], includes: ['o'], excludes: ['obj'] });
\ No newline at end of file
From 43a8234b5bce3d725d1a89e364e9e65bf2cca049 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 23 Dec 2020 11:03:23 +0800
Subject: [PATCH 07/22] feat: update
completionPropertyShorthandForObjectLiteral test cases
---
.../completionPropertyShorthandForObjectLiteral2.ts | 9 +++++++--
.../completionPropertyShorthandForObjectLiteral3.ts | 2 +-
.../completionPropertyShorthandForObjectLiteral4.ts | 2 +-
.../completionPropertyShorthandForObjectLiteral5.ts | 7 +++----
4 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral2.ts b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral2.ts
index ec54418c77935..40aa223b7eced 100644
--- a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral2.ts
+++ b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral2.ts
@@ -12,6 +12,11 @@
//// };
verify.completions({
- marker: test.markers(),
- exact: completion.globalsPlus(["foo", "bar", "obj1", "obj2"]),
+ marker: ["1"],
+ exact: completion.globalsPlus(["foo", "bar", "obj2"]),
+});
+
+verify.completions({
+ marker: ["2"],
+ exact: completion.globalsPlus(["foo", "bar", "obj1"]),
});
diff --git a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral3.ts b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral3.ts
index 0a6fad60b293e..70c1f60055425 100644
--- a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral3.ts
+++ b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral3.ts
@@ -7,5 +7,5 @@
verify.completions({
marker: ["1"],
- exact: completion.globalsPlus(["foo", "bar", "obj"])
+ exact: completion.globalsPlus(["foo", "bar"]),
});
diff --git a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral4.ts b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral4.ts
index 35daa6185a3f1..a720bcc1dc6b2 100644
--- a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral4.ts
+++ b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral4.ts
@@ -7,5 +7,5 @@
verify.completions({
marker: ["1"],
- exact: completion.globalsPlus(["foo", "bar", "obj"])
+ exact: completion.globalsPlus(["foo", "bar"]),
});
diff --git a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral5.ts b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral5.ts
index 74ded23477463..47aeeb83677a7 100644
--- a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral5.ts
+++ b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral5.ts
@@ -7,7 +7,6 @@
//// const obj = { exp/**/
verify.completions({
- marker: "",
- exact: completion.globalsPlus(["obj"]),
- preferences: { includeCompletionsForModuleExports: true }
-});
\ No newline at end of file
+ marker: "",
+ preferences: { includeCompletionsForModuleExports: true },
+});
From c4cd16e18730acccb8b6e1d0b5f14ca76029d776 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 23 Dec 2020 15:43:47 +0800
Subject: [PATCH 08/22] feat: exclude completions of variable initializers
---
src/services/completions.ts | 35 ++++++++++++++++++-----------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index c5680ba9c4686..a5e2d79ed6b12 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1504,7 +1504,7 @@ namespace ts.Completions {
: KeywordCompletionFilters.TypeKeywords;
}
- const objectLiteralVariableDeclaration = getVariableDeclarationOfObjectLiteral(location);
+ const variableDeclaration = getVariableDeclaration(location);
filterMutate(symbols, symbol => {
if (!isSourceFile(location)) {
@@ -1513,8 +1513,13 @@ namespace ts.Completions {
return true;
}
- // Filter out variables from their own initializers, e.g. `const o = { prop: /* no 'o' here */ }`
- if (objectLiteralVariableDeclaration && symbol.valueDeclaration === objectLiteralVariableDeclaration) {
+ // Filter out variables from their own initializers
+ // e.g.
+ // 1. `const o = { prop: /* no 'o' here */ }`
+ // 2. `const a = /* no 'a' here */`
+ // 3. `const b = a && /* no 'b' here */`
+ // 4. `const c = [{ prop: [/* no 'c' here */] }]`
+ if (variableDeclaration && symbol.valueDeclaration === variableDeclaration) {
return false;
}
@@ -1536,29 +1541,25 @@ namespace ts.Completions {
});
}
- function getVariableDeclarationOfObjectLiteral(property: Node): VariableDeclaration | undefined {
+ function getVariableDeclaration(property: Node): VariableDeclaration | undefined {
if (!isIdentifier(property)) {
return undefined;
}
- let curNode: Node = property.parent;
- while (curNode && curNode.parent) {
- if ((isPropertyAssignment(curNode) || isShorthandPropertyAssignment(curNode)) && isObjectLiteralExpression(curNode.parent)) {
- curNode = curNode.parent.parent;
-
- if (isVariableDeclaration(curNode)) {
- return curNode;
- }
+ const variableDeclaration = findAncestor(property, (node) => {
+ if (isFunctionLikeDeclaration(node)) {
+ return "quit";
}
- else {
- return undefined;
+
+ if (isVariableDeclaration(node)) {
+ return true;
}
- }
+ return false;
+ });
- return undefined;
+ return variableDeclaration as VariableDeclaration;
}
-
function isTypeOnlyCompletion(): boolean {
return insideJsDocTagTypeExpression
|| !isContextTokenValueLocation(contextToken) &&
From 6f0f2045508f954bcc28970072c4ad84a8395b0f Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 23 Dec 2020 15:44:45 +0800
Subject: [PATCH 09/22] feat: update test cases
---
tests/cases/fourslash/commentsClassMembers.ts | 3 ++-
...ionListBuilderLocations_VariableDeclarations.ts | 9 ++++++++-
.../fourslash/completionListIsGlobalCompletion.ts | 5 +++--
.../cases/fourslash/completionListWithMeanings.ts | 14 ++++++++++++--
4 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/tests/cases/fourslash/commentsClassMembers.ts b/tests/cases/fourslash/commentsClassMembers.ts
index 1e17f0327fe7e..3cc9b27172958 100644
--- a/tests/cases/fourslash/commentsClassMembers.ts
+++ b/tests/cases/fourslash/commentsClassMembers.ts
@@ -201,7 +201,8 @@ verify.completions(
],
},
{ marker: ["29", "33", "38", "109"], includes: locals },
- { marker: ["35", "40", "87"], includes: locals, isNewIdentifierLocation: true },
+ { marker: ["35", "40"], includes: locals, isNewIdentifierLocation: true },
+ { marker: ["87"], includes: locals.filter(local => local === 'i1_s_p') , isNewIdentifierLocation: true },
{ marker: "31", includes: { name: "b", text: "(parameter) b: number", documentation: "number to add" } },
{ marker: "42", includes: { name: "value", text: "(parameter) value: number", documentation: "this is value" }, isNewIdentifierLocation: true },
{ marker: ["45", "52", "59"], includes: { name: "b", text: "(parameter) b: number" } },
diff --git a/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts b/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts
index af119f40be57f..eaad02afcc52f 100644
--- a/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts
+++ b/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts
@@ -26,8 +26,15 @@
////var y = 10; y=/*var12*/
+// first declaration
verify.completions({
- marker: test.markers(),
+ marker: ["var1"],
+ exact: completion.globalsPlus(["y", "C"]),
+ isNewIdentifierLocation: true
+});
+
+verify.completions({
+ marker: ["var2", "var3", "var4", "var5", "var6", "var7", "var8", "var9", "var10", "var11", "var12"],
exact: completion.globalsPlus(["x", "y", "C"]),
isNewIdentifierLocation: true
});
diff --git a/tests/cases/fourslash/completionListIsGlobalCompletion.ts b/tests/cases/fourslash/completionListIsGlobalCompletion.ts
index 91cd1a0f9c7e5..eaf83fa526b07 100644
--- a/tests/cases/fourslash/completionListIsGlobalCompletion.ts
+++ b/tests/cases/fourslash/completionListIsGlobalCompletion.ts
@@ -41,12 +41,13 @@ verify.completions(
{ marker: ["1", "3", "6", "8", "12", "14"], exact: undefined, isGlobalCompletion: false },
{ marker: "2", exact: ["a.ts", "file.ts"], isGlobalCompletion: false, isNewIdentifierLocation: true },
{ marker: ["4", "19"], exact: [], isGlobalCompletion: false },
- { marker: ["5", "11", "18"], exact: globals, isGlobalCompletion: true },
+ { marker: ["5", "11"], exact: globals, isGlobalCompletion: true },
+ { marker: ["18"], exact: globals.filter(name => name !== 'user'), isGlobalCompletion: true },
{ marker: "7", exact: completion.globalsInsideFunction(x), isGlobalCompletion: true },
{ marker: "9", exact: ["x", "y"], isGlobalCompletion: false },
{ marker: "10", exact: completion.classElementKeywords, isGlobalCompletion: false, isNewIdentifierLocation: true },
{ marker: "13", exact: globals, isGlobalCompletion: false },
- { marker: "15", exact: globals, isGlobalCompletion: true, isNewIdentifierLocation: true },
+ { marker: "15", exact: globals.filter(name => name !== 'x'), isGlobalCompletion: true, isNewIdentifierLocation: true },
{ marker: "16", exact: [...x, completion.globalThisEntry, ...completion.globalsVars, completion.undefinedVarEntry], isGlobalCompletion: false },
{ marker: "17", exact: completion.globalKeywords, isGlobalCompletion: false },
);
diff --git a/tests/cases/fourslash/completionListWithMeanings.ts b/tests/cases/fourslash/completionListWithMeanings.ts
index 034607d08c021..82c69d43a48de 100644
--- a/tests/cases/fourslash/completionListWithMeanings.ts
+++ b/tests/cases/fourslash/completionListWithMeanings.ts
@@ -36,10 +36,20 @@ const types: ReadonlyArray = [
...completion.typeKeywords,
];
+const filterValuesByName = (name: string) => {
+ return values.filter(entry => {
+ if (typeof entry === 'string') {
+ return entry !== name;
+ }
+
+ return entry.name !== name;
+ })
+}
+
verify.completions(
- { marker: "valueExpr", exact: values, isNewIdentifierLocation: true },
+ { marker: "valueExpr", exact: filterValuesByName('tt'), isNewIdentifierLocation: true },
{ marker: "typeExpr", exact: types, },
- { marker: "valueExprInObjectLiteral", exact: values },
+ { marker: "valueExprInObjectLiteral", exact: filterValuesByName('yy') },
{ marker: "membertypeExpr", exact: [{ name: "point3", text: "interface m3.point3" }] },
{ marker: "membervalueExpr", exact: [{ name: "zz2", text: "var m3.zz2: number" }] },
);
From a3d428251ca6a0318c02e513cc1c2eeec81df1fc Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 23 Dec 2020 15:45:25 +0800
Subject: [PATCH 10/22] feat: add completionListWithoutVariableinitializer test
case
---
...ompletionListWithoutVariableinitializer.ts | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 tests/cases/fourslash/completionListWithoutVariableinitializer.ts
diff --git a/tests/cases/fourslash/completionListWithoutVariableinitializer.ts b/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
new file mode 100644
index 0000000000000..96151138c581d
--- /dev/null
+++ b/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
@@ -0,0 +1,25 @@
+///
+
+//// const a = a/*1*/;
+//// const b = a && b/*2*/;
+//// const c = [{ prop: [c/*3*/] }];
+
+verify.completions({
+ marker: ["1"],
+ excludes: ["a"],
+ isNewIdentifierLocation: true,
+});
+
+verify.completions({
+ marker: ["2"],
+ excludes: ["b"],
+ includes: ["a"],
+ isNewIdentifierLocation: false,
+});
+
+verify.completions({
+ marker: ["3"],
+ excludes: ["c"],
+ includes: ["a", "b"],
+ isNewIdentifierLocation: true,
+});
From ab3be8245508f6c3a2247d323d90c9d928084465 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 23 Dec 2020 16:20:42 +0800
Subject: [PATCH 11/22] feat: perfect the
completionListWithoutVariableinitializer test case
---
.../completionListWithoutVariableinitializer.ts | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/tests/cases/fourslash/completionListWithoutVariableinitializer.ts b/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
index 96151138c581d..c3b8b726f0e91 100644
--- a/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
+++ b/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
@@ -3,6 +3,8 @@
//// const a = a/*1*/;
//// const b = a && b/*2*/;
//// const c = [{ prop: [c/*3*/] }];
+//// const d = () => { d/*4*/ };
+//// const e = { prop() { e/*5*/ } };
verify.completions({
marker: ["1"],
@@ -14,7 +16,6 @@ verify.completions({
marker: ["2"],
excludes: ["b"],
includes: ["a"],
- isNewIdentifierLocation: false,
});
verify.completions({
@@ -23,3 +24,13 @@ verify.completions({
includes: ["a", "b"],
isNewIdentifierLocation: true,
});
+
+verify.completions({
+ marker: ["4"],
+ includes: ["a", "b", "c", "d"],
+});
+
+verify.completions({
+ marker: ["5"],
+ includes: ["a", "b", "c", "d", "e"],
+});
From b4dc72cab304017cb5da45d70a3177f7d7f81042 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Thu, 24 Dec 2020 09:57:22 +0800
Subject: [PATCH 12/22] feat: remove isIdentifier limit
---
src/services/completions.ts | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index a5e2d79ed6b12..8ef809d655da7 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1542,10 +1542,6 @@ namespace ts.Completions {
}
function getVariableDeclaration(property: Node): VariableDeclaration | undefined {
- if (!isIdentifier(property)) {
- return undefined;
- }
-
const variableDeclaration = findAncestor(property, (node) => {
if (isFunctionLikeDeclaration(node)) {
return "quit";
From 019bbfb358cd5aa84dd6ccffc0c4ff90a2891009 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Thu, 24 Dec 2020 10:03:06 +0800
Subject: [PATCH 13/22] feat: update test cases
---
tests/cases/fourslash/completionListIsGlobalCompletion.ts | 4 ++--
tests/cases/fourslash/completionTypeAssertion.ts | 2 +-
.../fourslash/globalCompletionListInsideObjectLiterals.ts | 6 ++++--
.../cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts | 2 +-
4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/tests/cases/fourslash/completionListIsGlobalCompletion.ts b/tests/cases/fourslash/completionListIsGlobalCompletion.ts
index eaf83fa526b07..7184e50499e00 100644
--- a/tests/cases/fourslash/completionListIsGlobalCompletion.ts
+++ b/tests/cases/fourslash/completionListIsGlobalCompletion.ts
@@ -46,8 +46,8 @@ verify.completions(
{ marker: "7", exact: completion.globalsInsideFunction(x), isGlobalCompletion: true },
{ marker: "9", exact: ["x", "y"], isGlobalCompletion: false },
{ marker: "10", exact: completion.classElementKeywords, isGlobalCompletion: false, isNewIdentifierLocation: true },
- { marker: "13", exact: globals, isGlobalCompletion: false },
+ { marker: "13", exact: globals.filter(name => name !== 'z'), isGlobalCompletion: false },
{ marker: "15", exact: globals.filter(name => name !== 'x'), isGlobalCompletion: true, isNewIdentifierLocation: true },
- { marker: "16", exact: [...x, completion.globalThisEntry, ...completion.globalsVars, completion.undefinedVarEntry], isGlobalCompletion: false },
+ { marker: "16", exact: [...x, completion.globalThisEntry, ...completion.globalsVars, completion.undefinedVarEntry].filter(name => name !== 'user'), isGlobalCompletion: false },
{ marker: "17", exact: completion.globalKeywords, isGlobalCompletion: false },
);
diff --git a/tests/cases/fourslash/completionTypeAssertion.ts b/tests/cases/fourslash/completionTypeAssertion.ts
index bb5c6f8abda29..bb6b626216916 100644
--- a/tests/cases/fourslash/completionTypeAssertion.ts
+++ b/tests/cases/fourslash/completionTypeAssertion.ts
@@ -2,4 +2,4 @@
//// var x = this as/*1*/
-verify.completions({marker: "1", exact: completion.globalsPlus(["x"]) })
+verify.completions({marker: "1", exact: completion.globals })
diff --git a/tests/cases/fourslash/globalCompletionListInsideObjectLiterals.ts b/tests/cases/fourslash/globalCompletionListInsideObjectLiterals.ts
index 503758461489b..00d5ef2c6e0d6 100644
--- a/tests/cases/fourslash/globalCompletionListInsideObjectLiterals.ts
+++ b/tests/cases/fourslash/globalCompletionListInsideObjectLiterals.ts
@@ -28,6 +28,8 @@
// 5, 6: Literal member completion after member name with empty member expression.
const exact = ["p1", "p2", "p3", "p4", ...completion.globalsPlus(["ObjectLiterals"])];
verify.completions(
- { marker: ["1",], exact, isNewIdentifierLocation: true },
- { marker: ["2", "3", "4", "5", "6"], exact }
+ { marker: ["1",], exact: exact.filter(name => name !== 'p1'), isNewIdentifierLocation: true },
+ { marker: ["2", "3"], exact: exact.filter(name => name !== 'p2') },
+ { marker: ["4"], exact: exact.filter(name => name !== 'p3' ) },
+ { marker: ["5", "6"], exact: exact.filter(name => name !== 'p4') },
);
diff --git a/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts b/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts
index c7f3b3f26bebb..e48a6368627ba 100644
--- a/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts
+++ b/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts
@@ -3,4 +3,4 @@
//@Filename: file.tsx
//// var x = **/;
-verify.completions({ marker: "", exact: [completion.globalThisEntry, ...completion.globalsVars, "x", completion.undefinedVarEntry] });
+verify.completions({ marker: "", exact: [completion.globalThisEntry, ...completion.globalsVars, completion.undefinedVarEntry] });
From 5695b34e404bd3a269dba971e576b23e395a523d Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Thu, 24 Dec 2020 17:17:07 +0800
Subject: [PATCH 14/22] feat: code optimization and filter out some binding
cases
---
src/services/completions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 8ef809d655da7..81fc721e7ffb7 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1543,7 +1543,7 @@ namespace ts.Completions {
function getVariableDeclaration(property: Node): VariableDeclaration | undefined {
const variableDeclaration = findAncestor(property, (node) => {
- if (isFunctionLikeDeclaration(node)) {
+ if (isFunctionBlock(node) || isBindingPattern(node)) {
return "quit";
}
From f6542e57e3ee41e630087f115c2b7d2af28f71ac Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Thu, 24 Dec 2020 17:17:40 +0800
Subject: [PATCH 15/22] feat: update test case
---
...ompletionListWithoutVariableinitializer.ts | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/tests/cases/fourslash/completionListWithoutVariableinitializer.ts b/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
index c3b8b726f0e91..d444aaba8dffa 100644
--- a/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
+++ b/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
@@ -5,6 +5,9 @@
//// const c = [{ prop: [c/*3*/] }];
//// const d = () => { d/*4*/ };
//// const e = { prop() { e/*5*/ } };
+//// const fn = (p = /*6*/) => {}
+//// const { f, g = /*7*/ } = { ... }
+//// const [ f1, g1 = /*8*/ ] = [ ... ]
verify.completions({
marker: ["1"],
@@ -34,3 +37,19 @@ verify.completions({
marker: ["5"],
includes: ["a", "b", "c", "d", "e"],
});
+
+verify.completions({
+ marker: ["6"],
+ includes: ["a", "b", "c", "d", "e"],
+ excludes: ["fn"],
+});
+
+verify.completions({
+ marker: ["7"],
+ includes: ["a", "b", "c", "d", "e", "fn"],
+});
+
+verify.completions({
+ marker: ["8"],
+ includes: ["a", "b", "c", "d", "e", "fn"],
+});
From cc6212f51967c8b8e566e9ba9564395131625b2a Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Tue, 29 Dec 2020 10:01:29 +0800
Subject: [PATCH 16/22] feat: handle arrow function expressions without braces
---
src/services/completions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 81fc721e7ffb7..62a034af92914 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1543,7 +1543,7 @@ namespace ts.Completions {
function getVariableDeclaration(property: Node): VariableDeclaration | undefined {
const variableDeclaration = findAncestor(property, (node) => {
- if (isFunctionBlock(node) || isBindingPattern(node)) {
+ if (isFunctionBlock(node) || isBindingPattern(node) || (isArrowFunction(node.parent) && node.parent.body === node)) {
return "quit";
}
From 5c2e314da186db26c36e28fadfee86426796c7fb Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Tue, 29 Dec 2020 10:01:55 +0800
Subject: [PATCH 17/22] feat: add arrow function expressions without braces
test case
---
...ompletionListWithoutVariableinitializer.ts | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/tests/cases/fourslash/completionListWithoutVariableinitializer.ts b/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
index d444aaba8dffa..7ef57ca66e196 100644
--- a/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
+++ b/tests/cases/fourslash/completionListWithoutVariableinitializer.ts
@@ -4,10 +4,11 @@
//// const b = a && b/*2*/;
//// const c = [{ prop: [c/*3*/] }];
//// const d = () => { d/*4*/ };
-//// const e = { prop() { e/*5*/ } };
-//// const fn = (p = /*6*/) => {}
-//// const { f, g = /*7*/ } = { ... }
-//// const [ f1, g1 = /*8*/ ] = [ ... ]
+//// const e = () => expression/*5*/
+//// const f = { prop() { e/*6*/ } };
+//// const fn = (p = /*7*/) => {}
+//// const { g, h = /*8*/ } = { ... }
+//// const [ g1, h1 = /*9*/ ] = [ ... ]
verify.completions({
marker: ["1"],
@@ -41,15 +42,21 @@ verify.completions({
verify.completions({
marker: ["6"],
includes: ["a", "b", "c", "d", "e"],
- excludes: ["fn"],
});
verify.completions({
marker: ["7"],
- includes: ["a", "b", "c", "d", "e", "fn"],
+ includes: ["a", "b", "c", "d", "e"],
+ excludes: ["fn"],
});
verify.completions({
marker: ["8"],
includes: ["a", "b", "c", "d", "e", "fn"],
});
+
+verify.completions({
+ marker: ["9"],
+ includes: ["a", "b", "c", "d", "e", "fn"],
+});
+
From 7b7cc249088818a30fcc833c8bd2fe18c73df647 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Tue, 29 Dec 2020 10:29:09 +0800
Subject: [PATCH 18/22] feat: check node.parent exist first
---
src/services/completions.ts | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 62a034af92914..91fbe838c4c0d 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1542,8 +1542,13 @@ namespace ts.Completions {
}
function getVariableDeclaration(property: Node): VariableDeclaration | undefined {
+
+ const isArrowFunctionExpressionWithoutArrow = (node: Node) => {
+ return node.parent && isArrowFunction(node.parent) && node.parent.body === node;
+ };
+
const variableDeclaration = findAncestor(property, (node) => {
- if (isFunctionBlock(node) || isBindingPattern(node) || (isArrowFunction(node.parent) && node.parent.body === node)) {
+ if (isFunctionBlock(node) || isArrowFunctionExpressionWithoutArrow(node) || isBindingPattern(node)) {
return "quit";
}
From 0630cfef19faa45dbab883b9c02c0886982dc9be Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 30 Dec 2020 08:27:04 +0800
Subject: [PATCH 19/22] feat: optimization name
---
src/services/completions.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 91fbe838c4c0d..cfcd1a8bf7c69 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1543,12 +1543,12 @@ namespace ts.Completions {
function getVariableDeclaration(property: Node): VariableDeclaration | undefined {
- const isArrowFunctionExpressionWithoutArrow = (node: Node) => {
+ const isArrowFunctionBody = (node: Node) => {
return node.parent && isArrowFunction(node.parent) && node.parent.body === node;
};
const variableDeclaration = findAncestor(property, (node) => {
- if (isFunctionBlock(node) || isArrowFunctionExpressionWithoutArrow(node) || isBindingPattern(node)) {
+ if (isFunctionBlock(node) || isArrowFunctionBody(node) || isBindingPattern(node)) {
return "quit";
}
From 578a1ceacbd7ffa8ce744fab3ad21f8c6c842505 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 30 Dec 2020 08:27:47 +0800
Subject: [PATCH 20/22] feat: optimize test cases
---
.../completionPropertyShorthandForObjectLiteral5.ts | 2 ++
tests/cases/fourslash/completionTypeAssertion.ts | 5 +++--
.../cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts | 5 +++--
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral5.ts b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral5.ts
index 47aeeb83677a7..979b0b2afe767 100644
--- a/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral5.ts
+++ b/tests/cases/fourslash/completionPropertyShorthandForObjectLiteral5.ts
@@ -4,9 +4,11 @@
//// export const exportedConstant = 0;
// @Filename: /b.ts
+//// const foo = 'foo'
//// const obj = { exp/**/
verify.completions({
marker: "",
+ exact: completion.globalsPlus(["foo"]),
preferences: { includeCompletionsForModuleExports: true },
});
diff --git a/tests/cases/fourslash/completionTypeAssertion.ts b/tests/cases/fourslash/completionTypeAssertion.ts
index bb6b626216916..fbfe72ac455cc 100644
--- a/tests/cases/fourslash/completionTypeAssertion.ts
+++ b/tests/cases/fourslash/completionTypeAssertion.ts
@@ -1,5 +1,6 @@
///
-//// var x = this as/*1*/
+//// var x = 'something'
+//// var y = this as/*1*/
-verify.completions({marker: "1", exact: completion.globals })
+verify.completions({marker: "1", exact: completion.globalsPlus(["x"]) })
diff --git a/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts b/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts
index e48a6368627ba..256c4280f856d 100644
--- a/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts
+++ b/tests/cases/fourslash/tsxCompletionOnOpeningTagWithoutJSX1.ts
@@ -1,6 +1,7 @@
///
//@Filename: file.tsx
-//// var x = **/;
+//// var x = 'something'
+//// var y = **/;
-verify.completions({ marker: "", exact: [completion.globalThisEntry, ...completion.globalsVars, completion.undefinedVarEntry] });
+verify.completions({ marker: "", exact: [completion.globalThisEntry, ...completion.globalsVars, "x", completion.undefinedVarEntry] });
From 52ee16acbb23b283370bfb81f9b66ed45f50a613 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Wed, 13 Jan 2021 10:53:44 +0800
Subject: [PATCH 21/22] chore: code formatting
---
src/services/completions.ts | 29 +++++++++--------------------
1 file changed, 9 insertions(+), 20 deletions(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index cfcd1a8bf7c69..00a64d8cab79d 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1514,11 +1514,7 @@ namespace ts.Completions {
}
// Filter out variables from their own initializers
- // e.g.
- // 1. `const o = { prop: /* no 'o' here */ }`
- // 2. `const a = /* no 'a' here */`
- // 3. `const b = a && /* no 'b' here */`
- // 4. `const c = [{ prop: [/* no 'c' here */] }]`
+ // `const a = /* no 'a' here */`
if (variableDeclaration && symbol.valueDeclaration === variableDeclaration) {
return false;
}
@@ -1542,25 +1538,18 @@ namespace ts.Completions {
}
function getVariableDeclaration(property: Node): VariableDeclaration | undefined {
-
- const isArrowFunctionBody = (node: Node) => {
- return node.parent && isArrowFunction(node.parent) && node.parent.body === node;
- };
-
- const variableDeclaration = findAncestor(property, (node) => {
- if (isFunctionBlock(node) || isArrowFunctionBody(node) || isBindingPattern(node)) {
- return "quit";
- }
-
- if (isVariableDeclaration(node)) {
- return true;
- }
- return false;
- });
+ const variableDeclaration = findAncestor(property, node =>
+ isFunctionBlock(node) || isArrowFunctionBody(node) || isBindingPattern(node)
+ ? "quit"
+ : isVariableDeclaration(node));
return variableDeclaration as VariableDeclaration;
}
+ function isArrowFunctionBody(node: Node) {
+ return node.parent && isArrowFunction(node.parent) && node.parent.body === node;
+ };
+
function isTypeOnlyCompletion(): boolean {
return insideJsDocTagTypeExpression
|| !isContextTokenValueLocation(contextToken) &&
From 86c30d094be5ad88e439790201bab7c842889d22 Mon Sep 17 00:00:00 2001
From: chenjigeng <178854407@qq.com>
Date: Fri, 15 Jan 2021 09:13:48 +0800
Subject: [PATCH 22/22] feat: perfect type
---
src/services/completions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 00a64d8cab79d..f0ad156956d82 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1543,7 +1543,7 @@ namespace ts.Completions {
? "quit"
: isVariableDeclaration(node));
- return variableDeclaration as VariableDeclaration;
+ return variableDeclaration as VariableDeclaration | undefined;
}
function isArrowFunctionBody(node: Node) {