diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 809857db2c6..f83c1c9a01c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3815,6 +3815,11 @@ module ts { // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. function getContextualType(node: Expression): Type { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return undefined; + } + if (node.contextualType) { return node.contextualType; } @@ -6681,7 +6686,20 @@ module ts { return findChildAtPosition(sourceFile); } - function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] { + function isInsideWithStatementBody(node: Node): boolean { + if (node) { + while (node.parent) { + if (node.parent.kind === SyntaxKind.WithStatement && (node.parent).statement === node) { + return true; + } + node = node.parent; + } + } + + return false; + } + + function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]{ var symbols: SymbolTable = {}; var memberFlags: NodeFlags = 0; function copySymbol(symbol: Symbol, meaning: SymbolFlags) { @@ -6701,6 +6719,12 @@ module ts { } } } + + if (isInsideWithStatementBody(location)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return []; + } + while (location) { if (location.locals && !isGlobalSourceFile(location)) { copySymbols(location.locals, meaning); @@ -6973,6 +6997,11 @@ module ts { } function getSymbolInfo(node: Node) { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return undefined; + } + if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) { // This is a declaration, call getSymbolOfNode return getSymbolOfNode(node.parent); @@ -7027,9 +7056,15 @@ module ts { } function getTypeOfNode(node: Node): Type { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return unknownType; + } + if (isExpression(node)) { return getTypeOfExpression(node); } + if (isTypeNode(node)) { return getTypeFromTypeNode(node); } diff --git a/tests/cases/fourslash/findAllRefsInsideWithBlock.ts b/tests/cases/fourslash/findAllRefsInsideWithBlock.ts new file mode 100644 index 00000000000..394d30d89d3 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInsideWithBlock.ts @@ -0,0 +1,16 @@ +/// + +////var x = 0; +//// +////with ({}) { +//// var y = x; // Reference of x here should not be picked +//// /*2*/y++; // also reference for y should be ignored +////} +//// +////x = /*1*/x + 1; + +goTo.marker('1'); +verify.referencesCountIs(3); + +goTo.marker('2'); +verify.referencesCountIs(1); \ No newline at end of file diff --git a/tests/cases/fourslash/memberListInWithBlock.ts b/tests/cases/fourslash/memberListInWithBlock.ts index 973f4612cdd..a37c20dadfa 100644 --- a/tests/cases/fourslash/memberListInWithBlock.ts +++ b/tests/cases/fourslash/memberListInWithBlock.ts @@ -15,8 +15,10 @@ goTo.marker('1'); verify.memberListIsEmpty(); goTo.marker('2'); +// Only keywords should show in completion, no members or types verify.not.completionListContains("foo"); verify.not.completionListContains("f"); verify.not.completionListContains("c"); verify.not.completionListContains("d"); verify.not.completionListContains("x"); +verify.not.completionListContains("Object"); diff --git a/tests/cases/fourslash/memberListInWithBlock2.ts b/tests/cases/fourslash/memberListInWithBlock2.ts new file mode 100644 index 00000000000..72bccb6926c --- /dev/null +++ b/tests/cases/fourslash/memberListInWithBlock2.ts @@ -0,0 +1,12 @@ +/// + +////interface IFoo { +//// a: number; +////} +//// +////with (x) { +//// var y: IFoo = { /*1*/ }; +////} + +goTo.marker('1'); +verify.memberListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash/memberListInWithBlock3.ts b/tests/cases/fourslash/memberListInWithBlock3.ts new file mode 100644 index 00000000000..a007b08cd02 --- /dev/null +++ b/tests/cases/fourslash/memberListInWithBlock3.ts @@ -0,0 +1,7 @@ +/// + +////var x = { a: 0 }; +////with(x./*1*/ + +goTo.marker('1'); +verify.memberListContains("a"); diff --git a/tests/cases/fourslash_old/quickInfoInWithBlock.ts b/tests/cases/fourslash/quickInfoInWithBlock.ts similarity index 100% rename from tests/cases/fourslash_old/quickInfoInWithBlock.ts rename to tests/cases/fourslash/quickInfoInWithBlock.ts