diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0e428b4a4e0..63ea9f1ae2b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -85,8 +85,7 @@ module ts { getDiagnostics, getDeclarationDiagnostics, getGlobalDiagnostics, - getParentOfSymbol, - getNarrowedTypeOfSymbol, + getTypeOfSymbolAtLocation, getDeclaredTypeOfSymbol, getPropertiesOfType, getPropertyOfType, @@ -4386,6 +4385,19 @@ module ts { } } + function getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type { + var containerNodes: Node[] = []; + for (var parent = node.parent; parent; parent = parent.parent) { + if (isExpression(parent) && isContextSensitiveExpression(parent)) { + containerNodes.unshift(parent) + }; + } + + ts.forEach(containerNodes, node => { getTypeOfNode(node); }); + + 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); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index edf052a8876..261a6fbfa31 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -883,8 +883,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; diff --git a/src/services/services.ts b/src/services/services.ts index 0a0f98dd4b6..e7c964fb7e3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2697,7 +2697,7 @@ module ts { // which is permissible given that it is backwards compatible; but really we should consider // passing the meaning for the node so that we don't report that a suggestion for a value is an interface. // We COULD also just do what 'getSymbolModifiers' does, which is to use the first declaration. - Debug.assert(session.typeChecker.getNarrowedTypeOfSymbol(symbol, location) !== undefined, "Could not find type for symbol"); + Debug.assert(session.typeChecker.getTypeOfSymbolAtLocation(symbol, location) !== undefined, "Could not find type for symbol"); var displayPartsDocumentationsAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getSourceFile(filename), location, session.typeChecker, location, SemanticMeaning.All); return { name: entryName, @@ -2800,7 +2800,7 @@ module ts { if (!unionPropertyKind) { // If this was union of all methods, //make sure it has call signatures before we can label it as method - var typeOfUnionProperty = typeInfoResolver.getNarrowedTypeOfSymbol(symbol, location); + var typeOfUnionProperty = typeInfoResolver.getTypeOfSymbolAtLocation(symbol, location); if (typeOfUnionProperty.getCallSignatures().length) { return ScriptElementKind.memberFunctionElement; } @@ -2877,7 +2877,7 @@ module ts { symbolKind = ScriptElementKind.memberVariableElement; } - var type = typeResolver.getNarrowedTypeOfSymbol(symbol, location); + var type = typeResolver.getTypeOfSymbolAtLocation(symbol, location); if (type) { if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) { var right = (location.parent).name; diff --git a/tests/cases/fourslash/quickInfoOnVarInArrowExpression.ts b/tests/cases/fourslash/quickInfoOnVarInArrowExpression.ts new file mode 100644 index 00000000000..54287c76952 --- /dev/null +++ b/tests/cases/fourslash/quickInfoOnVarInArrowExpression.ts @@ -0,0 +1,16 @@ +/// + +////interface IMap { +//// [key: string]: T; +////} +////var map: IMap; +////var categories: string[]; +////each(categories, category => { +//// var /*1*/changes = map[category]; +//// return each(changes, change => { +//// }); +////}); +////function each(items: T[], handler: (item: T) => void) { } + +goTo.marker('1'); +verify.quickInfoIs("(local var) changes: string[]", undefined); \ No newline at end of file