Short-circuit semantic operations within with blocks

This commit is contained in:
Mohamed Hegazy 2014-09-12 15:31:47 -07:00
parent 85c6d34047
commit aa571ff088
6 changed files with 73 additions and 1 deletions

View File

@ -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 && (<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(<Expression>node);
}
if (isTypeNode(node)) {
return getTypeFromTypeNode(<TypeNode>node);
}

View File

@ -0,0 +1,16 @@
/// <reference path='fourslash.ts'/>
////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);

View File

@ -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");

View File

@ -0,0 +1,12 @@
/// <reference path='fourslash.ts'/>
////interface IFoo {
//// a: number;
////}
////
////with (x) {
//// var y: IFoo = { /*1*/ };
////}
goTo.marker('1');
verify.memberListIsEmpty();

View File

@ -0,0 +1,7 @@
/// <reference path='fourslash.ts'/>
////var x = { a: 0 };
////with(x./*1*/
goTo.marker('1');
verify.memberListContains("a");