Merge pull request #1362 from Microsoft/contextSensitiveExpressions

Resolve the context sensitive expression containers before resolving node
This commit is contained in:
Sheetal Nandi
2014-12-04 13:02:56 -08:00
7 changed files with 96 additions and 24 deletions

View File

@@ -85,8 +85,7 @@ module ts {
getDiagnostics,
getDeclarationDiagnostics,
getGlobalDiagnostics,
getParentOfSymbol,
getNarrowedTypeOfSymbol,
getTypeOfSymbolAtLocation,
getDeclaredTypeOfSymbol,
getPropertiesOfType,
getPropertyOfType,
@@ -94,9 +93,9 @@ module ts {
getIndexTypeOfType,
getReturnTypeOfSignature,
getSymbolsInScope,
getSymbolInfo,
getSymbolAtLocation,
getShorthandAssignmentValueSymbol,
getTypeOfNode,
getTypeAtLocation,
typeToString,
getSymbolDisplayBuilder,
symbolToString,
@@ -4391,6 +4390,46 @@ module ts {
}
}
function resolveLocation(node: Node) {
// Resolve location from top down towards node if it is a context sensitive expression
// That helps in making sure not assigning types as any when resolved out of order
var containerNodes: Node[] = [];
for (var parent = node.parent; parent; parent = parent.parent) {
if (isExpression(parent) && isContextSensitiveExpression(<Expression>parent)) {
containerNodes.unshift(parent);
}
}
ts.forEach(containerNodes, node => { getTypeOfNode(node); });
}
function getSymbolAtLocation(node: Node): Symbol {
resolveLocation(node);
return getSymbolInfo(node);
}
function getTypeAtLocation(node: Node): Type {
resolveLocation(node);
return getTypeOfNode(node);
}
function getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type {
resolveLocation(node);
// Get the narrowed type of symbol at given location instead of just getting
// the type of the symbol.
// eg.
// function foo(a: string | number) {
// if (typeof a === "string") {
// a/**/
// }
// }
// getTypeOfSymbol for a would return type of parameter symbol string | number
// Unless we provide location /**/, checker wouldn't know how to narrow the type
// By using getNarrowedTypeOfSymbol would return string since it would be able to narrow
// it by typeguard in the if true condition
return getNarrowedTypeOfSymbol(symbol, node);
}
// Get the narrowed type of a given symbol at a given location
function getNarrowedTypeOfSymbol(symbol: Symbol, node: Node) {
var type = getTypeOfSymbol(symbol);

View File

@@ -903,8 +903,7 @@ module ts {
getSymbolCount(): number;
getTypeCount(): number;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
getParentOfSymbol(symbol: Symbol): Symbol;
getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type;
getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type;
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
getPropertiesOfType(type: Type): Symbol[];
getPropertyOfType(type: Type, propertyName: string): Symbol;
@@ -912,9 +911,9 @@ module ts {
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
getReturnTypeOfSignature(signature: Signature): Type;
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
getSymbolInfo(node: Node): Symbol;
getSymbolAtLocation(node: Node): Symbol;
getShorthandAssignmentValueSymbol(location: Node): Symbol;
getTypeOfNode(node: Node): Type;
getTypeAtLocation(node: Node): Type;
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
getSymbolDisplayBuilder(): SymbolDisplayBuilder;