Skip to content

Commit f58a503

Browse files
author
Andy Hanson
committed
Fix bug: getSymbolAtLocation should work for local symbol too
1 parent 126a46c commit f58a503

File tree

5 files changed

+41
-1
lines changed

5 files changed

+41
-1
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11870,6 +11870,8 @@ namespace ts {
1187011870
}
1187111871

1187211872
function getTypeOfSymbolAtLocation(symbol: Symbol, location: Node) {
11873+
symbol = symbol.exportSymbol || symbol;
11874+
1187311875
// If we have an identifier or a property access at the given location, if the location is
1187411876
// an dotted name expression, and if the location is not an assignment target, obtain the type
1187511877
// of the expression (which will reflect control flow analysis). If the expression indeed

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3552,7 +3552,7 @@ namespace ts {
35523552

35533553
/** See comment on `declareModuleMember` in `binder.ts`. */
35543554
export function getCombinedLocalAndExportSymbolFlags(symbol: Symbol): SymbolFlags {
3555-
return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
3555+
return symbol.flags & SymbolFlags.Export ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
35563556
}
35573557
}
35583558

src/harness/fourslash.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,22 @@ namespace FourSlash {
949949
this.verifySymbol(symbol, declarationRanges);
950950
}
951951

952+
public symbolsInScope(range: Range): ts.Symbol[] {
953+
const node = this.goToAndGetNode(range);
954+
return this.getChecker().getSymbolsInScope(node, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace);
955+
}
956+
957+
public verifyTypeOfSymbolAtLocation(range: Range, symbol: ts.Symbol, expected: string): void {
958+
const node = this.goToAndGetNode(range);
959+
const checker = this.getChecker();
960+
const type = checker.getTypeOfSymbolAtLocation(symbol, node);
961+
962+
const actual = checker.typeToString(type);
963+
if (actual !== expected) {
964+
this.raiseError(`Expected: '${expected}', actual: '${actual}'`);
965+
}
966+
}
967+
952968
private verifyReferencesAre(expectedReferences: Range[]) {
953969
const actualReferences = this.getReferencesAtCaret() || [];
954970

@@ -3452,6 +3468,10 @@ namespace FourSlashInterface {
34523468
public markerByName(s: string): FourSlash.Marker {
34533469
return this.state.getMarkerByName(s);
34543470
}
3471+
3472+
public symbolsInScope(range: FourSlash.Range): ts.Symbol[] {
3473+
return this.state.symbolsInScope(range);
3474+
}
34553475
}
34563476

34573477
export class GoTo {
@@ -3720,6 +3740,10 @@ namespace FourSlashInterface {
37203740
this.state.verifySymbolAtLocation(startRange, declarationRanges);
37213741
}
37223742

3743+
public typeOfSymbolAtLocation(range: FourSlash.Range, symbol: ts.Symbol, expected: string) {
3744+
this.state.verifyTypeOfSymbolAtLocation(range, symbol, expected);
3745+
}
3746+
37233747
public referencesOf(start: FourSlash.Range, references: FourSlash.Range[]) {
37243748
this.state.verifyReferencesOf(start, references);
37253749
}

tests/cases/fourslash/fourslash.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ declare namespace FourSlashInterface {
116116
ranges(): Range[];
117117
rangesByText(): ts.Map<Range[]>;
118118
markerByName(s: string): Marker;
119+
symbolsInScope(range: Range): any[];
119120
}
120121
class goTo {
121122
marker(name?: string | Marker): void;
@@ -192,6 +193,7 @@ declare namespace FourSlashInterface {
192193
verifyGetEmitOutputContentsForCurrentFile(expected: ts.OutputFile[]): void;
193194
noReferences(markerNameOrRange?: string | Range): void;
194195
symbolAtLocation(startRange: Range, ...declarationRanges: Range[]): void;
196+
typeOfSymbolAtLocation(range: Range, symbol: any, expected: string): void;
195197
/**
196198
* @deprecated, prefer 'referenceGroups'
197199
* Like `referencesAre`, but goes to `start` first.
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+
////export function f() {}
4+
////[|1|];
5+
6+
const ranges = test.ranges();
7+
const symbolsInScope = test.symbolsInScope(ranges[0]);
8+
const f = symbolsInScope.find(s => s.name === "f");
9+
if (f === undefined) throw new Error("'f' not in scope");
10+
if (f.exportSymbol === undefined) throw new Error("Expected to get the local symbol");
11+
12+
verify.typeOfSymbolAtLocation(ranges[0], f, "() => void");

0 commit comments

Comments
 (0)