@@ -10547,62 +10547,102 @@ module ts {
1054710547 return false;
1054810548 }
1054910549
10550- function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
10550+ function getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean ): Symbol[] {
1055110551 let symbols: SymbolTable = {};
1055210552 let memberFlags: NodeFlags = 0;
10553- function copySymbol(symbol: Symbol, meaning: SymbolFlags) {
10553+
10554+ if (isInsideWithStatementBody(location)) {
10555+ // We cannot answer semantic questions within a with block, do not proceed any further
10556+ return [];
10557+ }
10558+
10559+ populateSymbols();
10560+
10561+ return mapToArray(symbols);
10562+
10563+ function populateSymbols() {
10564+ while (location) {
10565+ if (location.locals && !isGlobalSourceFile(location)) {
10566+ if (copySymbols(location.locals, meaning)) {
10567+ return;
10568+ }
10569+ }
10570+ switch (location.kind) {
10571+ case SyntaxKind.SourceFile:
10572+ if (!isExternalModule(<SourceFile>location)) {
10573+ break;
10574+ }
10575+ case SyntaxKind.ModuleDeclaration:
10576+ if (copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.ModuleMember)) {
10577+ return;
10578+ }
10579+ break;
10580+ case SyntaxKind.EnumDeclaration:
10581+ if (copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.EnumMember)) {
10582+ return;
10583+ }
10584+ break;
10585+ case SyntaxKind.ClassDeclaration:
10586+ case SyntaxKind.InterfaceDeclaration:
10587+ if (!(memberFlags & NodeFlags.Static)) {
10588+ if (copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type)) {
10589+ return;
10590+ }
10591+ }
10592+ break;
10593+ case SyntaxKind.FunctionExpression:
10594+ if ((<FunctionExpression>location).name) {
10595+ if (copySymbol(location.symbol, meaning)) {
10596+ return;
10597+ }
10598+ }
10599+ break;
10600+ }
10601+ memberFlags = location.flags;
10602+ location = location.parent;
10603+ }
10604+ if (copySymbols(globals, meaning)) {
10605+ return;
10606+ }
10607+ }
10608+
10609+ // Returns 'true' if we should stop processing symbols.
10610+ function copySymbol(symbol: Symbol, meaning: SymbolFlags): boolean {
1055410611 if (symbol.flags & meaning) {
1055510612 let id = symbol.name;
1055610613 if (!isReservedMemberName(id) && !hasProperty(symbols, id)) {
10557- symbols[id] = symbol;
10614+ if (predicate) {
10615+ // If we were supplied a predicate function, then check if this symbol
10616+ // matches with it. If so, we're done and can immediately return.
10617+ // Otherwise, just ignore this symbol and keep going.
10618+ if (predicate(symbol)) {
10619+ symbols[id] = symbol;
10620+ return true;
10621+ }
10622+ }
10623+ else {
10624+ // If no predicate was supplied, then just add the symbol as is.
10625+ symbols[id] = symbol;
10626+ }
1055810627 }
1055910628 }
10629+
10630+ return false;
1056010631 }
10561- function copySymbols(source: SymbolTable, meaning: SymbolFlags) {
10632+
10633+ function copySymbols(source: SymbolTable, meaning: SymbolFlags): boolean {
1056210634 if (meaning) {
1056310635 for (let id in source) {
1056410636 if (hasProperty(source, id)) {
10565- copySymbol(source[id], meaning);
10637+ if (copySymbol(source[id], meaning)) {
10638+ return true;
10639+ }
1056610640 }
1056710641 }
1056810642 }
10569- }
1057010643
10571- if (isInsideWithStatementBody(location)) {
10572- // We cannot answer semantic questions within a with block, do not proceed any further
10573- return [];
10574- }
10575-
10576- while (location) {
10577- if (location.locals && !isGlobalSourceFile(location)) {
10578- copySymbols(location.locals, meaning);
10579- }
10580- switch (location.kind) {
10581- case SyntaxKind.SourceFile:
10582- if (!isExternalModule(<SourceFile>location)) break;
10583- case SyntaxKind.ModuleDeclaration:
10584- copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.ModuleMember);
10585- break;
10586- case SyntaxKind.EnumDeclaration:
10587- copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.EnumMember);
10588- break;
10589- case SyntaxKind.ClassDeclaration:
10590- case SyntaxKind.InterfaceDeclaration:
10591- if (!(memberFlags & NodeFlags.Static)) {
10592- copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type);
10593- }
10594- break;
10595- case SyntaxKind.FunctionExpression:
10596- if ((<FunctionExpression>location).name) {
10597- copySymbol(location.symbol, meaning);
10598- }
10599- break;
10600- }
10601- memberFlags = location.flags;
10602- location = location.parent;
10644+ return false;
1060310645 }
10604- copySymbols(globals, meaning);
10605- return mapToArray(symbols);
1060610646 }
1060710647
1060810648 function isTypeDeclarationName(name: Node): boolean {
0 commit comments