Skip to content
30 changes: 30 additions & 0 deletions src/services/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1504,13 +1504,20 @@ namespace ts.Completions {
: KeywordCompletionFilters.TypeKeywords;
}

const objectLiteralVariableDeclaration = getVariableDeclarationOfObjectLiteral(location);

filterMutate(symbols, symbol => {
if (!isSourceFile(location)) {
// export = /**/ here we want to get all meanings, so any symbol is ok
if (isExportAssignment(location.parent)) {
return true;
}

// Filter out variables from their own initializers, e.g. `const o = { prop: /* no 'o' here */ }`
if (objectLiteralVariableDeclaration && symbol.valueDeclaration === objectLiteralVariableDeclaration) {
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)
Expand All @@ -1529,6 +1536,29 @@ namespace ts.Completions {
});
}

function getVariableDeclarationOfObjectLiteral(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;
}
}
else {
return undefined;
}
}

return undefined;
}


function isTypeOnlyCompletion(): boolean {
return insideJsDocTagTypeExpression
|| !isContextTokenValueLocation(contextToken) &&
Expand Down
26 changes: 26 additions & 0 deletions tests/cases/fourslash/completionListInObjectLiteral5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// <reference path="fourslash.ts" />

////const o = 'something'
////const obj = {
//// prop: o/*1*/,
//// pro() {
//// const obj1 = {
//// p:{
//// s: {
//// h: {
//// hh: o/*2*/
//// },
//// someFun() {
//// o/*3*/
//// }
//// }
//// }
//// }
//// },
//// 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'] });
verify.completions({ marker: ["4"], includes: ['o'], excludes: ['obj'] });
Original file line number Diff line number Diff line change
Expand Up @@ -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"]),
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

verify.completions({
marker: ["1"],
exact: completion.globalsPlus(["foo", "bar", "obj"])
exact: completion.globalsPlus(["foo", "bar"]),
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

verify.completions({
marker: ["1"],
exact: completion.globalsPlus(["foo", "bar", "obj"])
exact: completion.globalsPlus(["foo", "bar"]),
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//// const obj = { exp/**/

verify.completions({
marker: "",
exact: completion.globalsPlus(["obj"]),
preferences: { includeCompletionsForModuleExports: true }
});
marker: "",
preferences: { includeCompletionsForModuleExports: true },
});