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 1/7] 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 2/7] 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 3/7] 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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 }, +});