Skip to content

Commit aa571ff

Browse files
committed
Short-circuit semantic operations within with blocks
1 parent 85c6d34 commit aa571ff

File tree

6 files changed

+73
-1
lines changed

6 files changed

+73
-1
lines changed

src/compiler/checker.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3815,6 +3815,11 @@ module ts {
38153815
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
38163816
// be "pushed" onto a node using the contextualType property.
38173817
function getContextualType(node: Expression): Type {
3818+
if (isInsideWithStatementBody(node)) {
3819+
// We cannot answer semantic questions within a with block, do not proceed any further
3820+
return undefined;
3821+
}
3822+
38183823
if (node.contextualType) {
38193824
return node.contextualType;
38203825
}
@@ -6681,7 +6686,20 @@ module ts {
66816686
return findChildAtPosition(sourceFile);
66826687
}
66836688

6684-
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
6689+
function isInsideWithStatementBody(node: Node): boolean {
6690+
if (node) {
6691+
while (node.parent) {
6692+
if (node.parent.kind === SyntaxKind.WithStatement && (<WithStatement>node.parent).statement === node) {
6693+
return true;
6694+
}
6695+
node = node.parent;
6696+
}
6697+
}
6698+
6699+
return false;
6700+
}
6701+
6702+
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]{
66856703
var symbols: SymbolTable = {};
66866704
var memberFlags: NodeFlags = 0;
66876705
function copySymbol(symbol: Symbol, meaning: SymbolFlags) {
@@ -6701,6 +6719,12 @@ module ts {
67016719
}
67026720
}
67036721
}
6722+
6723+
if (isInsideWithStatementBody(location)) {
6724+
// We cannot answer semantic questions within a with block, do not proceed any further
6725+
return [];
6726+
}
6727+
67046728
while (location) {
67056729
if (location.locals && !isGlobalSourceFile(location)) {
67066730
copySymbols(location.locals, meaning);
@@ -6973,6 +6997,11 @@ module ts {
69736997
}
69746998

69756999
function getSymbolInfo(node: Node) {
7000+
if (isInsideWithStatementBody(node)) {
7001+
// We cannot answer semantic questions within a with block, do not proceed any further
7002+
return undefined;
7003+
}
7004+
69767005
if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
69777006
// This is a declaration, call getSymbolOfNode
69787007
return getSymbolOfNode(node.parent);
@@ -7027,9 +7056,15 @@ module ts {
70277056
}
70287057

70297058
function getTypeOfNode(node: Node): Type {
7059+
if (isInsideWithStatementBody(node)) {
7060+
// We cannot answer semantic questions within a with block, do not proceed any further
7061+
return unknownType;
7062+
}
7063+
70307064
if (isExpression(node)) {
70317065
return getTypeOfExpression(<Expression>node);
70327066
}
7067+
70337068
if (isTypeNode(node)) {
70347069
return getTypeFromTypeNode(<TypeNode>node);
70357070
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////var x = 0;
4+
////
5+
////with ({}) {
6+
//// var y = x; // Reference of x here should not be picked
7+
//// /*2*/y++; // also reference for y should be ignored
8+
////}
9+
////
10+
////x = /*1*/x + 1;
11+
12+
goTo.marker('1');
13+
verify.referencesCountIs(3);
14+
15+
goTo.marker('2');
16+
verify.referencesCountIs(1);

tests/cases/fourslash/memberListInWithBlock.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ goTo.marker('1');
1515
verify.memberListIsEmpty();
1616

1717
goTo.marker('2');
18+
// Only keywords should show in completion, no members or types
1819
verify.not.completionListContains("foo");
1920
verify.not.completionListContains("f");
2021
verify.not.completionListContains("c");
2122
verify.not.completionListContains("d");
2223
verify.not.completionListContains("x");
24+
verify.not.completionListContains("Object");
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////interface IFoo {
4+
//// a: number;
5+
////}
6+
////
7+
////with (x) {
8+
//// var y: IFoo = { /*1*/ };
9+
////}
10+
11+
goTo.marker('1');
12+
verify.memberListIsEmpty();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////var x = { a: 0 };
4+
////with(x./*1*/
5+
6+
goTo.marker('1');
7+
verify.memberListContains("a");

0 commit comments

Comments
 (0)