Skip to content

Commit 63278ca

Browse files
Don't bother with a predicate. It doesn't provide enough of a perf savings.
1 parent 614b106 commit 63278ca

11 files changed

+69
-117
lines changed

src/compiler/checker.ts

+15-41
Original file line numberDiff line numberDiff line change
@@ -10556,7 +10556,7 @@ module ts {
1055610556
return false;
1055710557
}
1055810558

10559-
function getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[] {
10559+
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
1056010560
let symbols: SymbolTable = {};
1056110561
let memberFlags: NodeFlags = 0;
1056210562

@@ -10572,85 +10572,59 @@ module ts {
1057210572
function populateSymbols() {
1057310573
while (location) {
1057410574
if (location.locals && !isGlobalSourceFile(location)) {
10575-
if (copySymbols(location.locals, meaning)) {
10576-
return;
10577-
}
10575+
copySymbols(location.locals, meaning);
1057810576
}
10577+
1057910578
switch (location.kind) {
1058010579
case SyntaxKind.SourceFile:
1058110580
if (!isExternalModule(<SourceFile>location)) {
1058210581
break;
1058310582
}
1058410583
case SyntaxKind.ModuleDeclaration:
10585-
if (copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.ModuleMember)) {
10586-
return;
10587-
}
10584+
copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.ModuleMember);
1058810585
break;
1058910586
case SyntaxKind.EnumDeclaration:
10590-
if (copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.EnumMember)) {
10591-
return;
10592-
}
10587+
copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.EnumMember);
1059310588
break;
1059410589
case SyntaxKind.ClassDeclaration:
1059510590
case SyntaxKind.InterfaceDeclaration:
1059610591
if (!(memberFlags & NodeFlags.Static)) {
10597-
if (copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type)) {
10598-
return;
10599-
}
10592+
copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type);
1060010593
}
1060110594
break;
1060210595
case SyntaxKind.FunctionExpression:
1060310596
if ((<FunctionExpression>location).name) {
10604-
if (copySymbol(location.symbol, meaning)) {
10605-
return;
10606-
}
10597+
copySymbol(location.symbol, meaning);
1060710598
}
1060810599
break;
1060910600
}
10601+
1061010602
memberFlags = location.flags;
1061110603
location = location.parent;
1061210604
}
10613-
if (copySymbols(globals, meaning)) {
10614-
return;
10615-
}
10605+
10606+
copySymbols(globals, meaning);
1061610607
}
1061710608

1061810609
// Returns 'true' if we should stop processing symbols.
10619-
function copySymbol(symbol: Symbol, meaning: SymbolFlags): boolean {
10610+
function copySymbol(symbol: Symbol, meaning: SymbolFlags): void {
1062010611
if (symbol.flags & meaning) {
1062110612
let id = symbol.name;
1062210613
if (!isReservedMemberName(id) && !hasProperty(symbols, id)) {
10623-
if (predicate) {
10624-
// If we were supplied a predicate function, then check if this symbol
10625-
// matches with it. If so, we're done and can immediately return.
10626-
// Otherwise, just ignore this symbol and keep going.
10627-
if (predicate(symbol)) {
10628-
symbols[id] = symbol;
10629-
return true;
10630-
}
10631-
}
10632-
else {
10633-
// If no predicate was supplied, then just add the symbol as is.
10634-
symbols[id] = symbol;
10635-
}
10614+
// If no predicate was supplied, then just add the symbol as is.
10615+
symbols[id] = symbol;
1063610616
}
1063710617
}
10638-
10639-
return false;
1064010618
}
1064110619

10642-
function copySymbols(source: SymbolTable, meaning: SymbolFlags): boolean {
10620+
function copySymbols(source: SymbolTable, meaning: SymbolFlags): void {
1064310621
if (meaning) {
1064410622
for (let id in source) {
1064510623
if (hasProperty(source, id)) {
10646-
if (copySymbol(source[id], meaning)) {
10647-
return true;
10648-
}
10624+
copySymbol(source[id], meaning);
1064910625
}
1065010626
}
1065110627
}
10652-
10653-
return false;
1065410628
}
1065510629
}
1065610630

src/compiler/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ module ts {
10951095

10961096
// If 'predicate' is supplied, then only the first symbol in scope matching the predicate
10971097
// will be returned. Otherwise, all symbols in scope will be returned.
1098-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
1098+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
10991099
getSymbolAtLocation(node: Node): Symbol;
11001100
getShorthandAssignmentValueSymbol(location: Node): Symbol;
11011101
getTypeAtLocation(node: Node): Type;

src/services/services.ts

+41-51
Original file line numberDiff line numberDiff line change
@@ -2398,42 +2398,51 @@ module ts {
23982398
}
23992399

24002400
/// Completion
2401-
function getValidCompletionEntryDisplayName(symbol: Symbol, target: ScriptTarget): string {
2401+
function getCompletionEntryDisplayName(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean): string {
24022402
let displayName = symbol.getName();
2403-
if (displayName && displayName.length > 0) {
2404-
let firstCharCode = displayName.charCodeAt(0);
2405-
// First check of the displayName is not external module; if it is an external module, it is not valid entry
2406-
if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
2407-
// If the symbol is external module, don't show it in the completion list
2408-
// (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there)
2409-
return undefined;
2410-
}
2403+
if (!displayName) {
2404+
return undefined;
2405+
}
24112406

2412-
if (displayName && displayName.length >= 2 && firstCharCode === displayName.charCodeAt(displayName.length - 1) &&
2413-
(firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
2414-
// If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
2415-
// invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
2416-
displayName = displayName.substring(1, displayName.length - 1);
2417-
}
2407+
let firstCharCode = displayName.charCodeAt(0);
2408+
// First check of the displayName is not external module; if it is an external module, it is not valid entry
2409+
if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
2410+
// If the symbol is external module, don't show it in the completion list
2411+
// (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there)
2412+
return undefined;
2413+
}
24182414

2419-
let isValid = isIdentifierStart(displayName.charCodeAt(0), target);
2420-
for (let i = 1, n = displayName.length; isValid && i < n; i++) {
2421-
isValid = isIdentifierPart(displayName.charCodeAt(i), target);
2415+
if (displayName && displayName.length >= 2 && firstCharCode === displayName.charCodeAt(displayName.length - 1) &&
2416+
(firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
2417+
// If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
2418+
// invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
2419+
displayName = displayName.substring(1, displayName.length - 1);
2420+
}
2421+
2422+
if (!displayName) {
2423+
return undefined;
2424+
}
2425+
2426+
if (performCharacterChecks) {
2427+
if (!isIdentifierStart(displayName.charCodeAt(0), target)) {
2428+
return undefined;
24222429
}
24232430

2424-
if (isValid) {
2425-
return unescapeIdentifier(displayName);
2431+
for (let i = 1, n = displayName.length; i < n; i++) {
2432+
if (!isIdentifierPart(displayName.charCodeAt(i), target)) {
2433+
return undefined;
2434+
}
24262435
}
24272436
}
24282437

2429-
return undefined;
2438+
return unescapeIdentifier(displayName);
24302439
}
24312440

24322441
function createCompletionEntry(symbol: Symbol, typeChecker: TypeChecker, location: Node): CompletionEntry {
24332442
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
24342443
// We would like to only show things that can be added after a dot, so for instance numeric properties can
24352444
// not be accessed with a dot (a.1 <- invalid)
2436-
let displayName = getValidCompletionEntryDisplayName(symbol, program.getCompilerOptions().target);
2445+
let displayName = getCompletionEntryDisplayName(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true);
24372446
if (!displayName) {
24382447
return undefined;
24392448
}
@@ -2449,26 +2458,7 @@ module ts {
24492458
};
24502459
}
24512460

2452-
// If symbolName is undefined, all symbols at the specified are returned. If symbolName
2453-
// is not undefined, then the first symbol with that name at the specified position
2454-
// will be returned. Calling without symbolName is useful when you want the entire
2455-
// list of symbols (like for getCompletionsAtPosition). Calling with a symbolName is
2456-
// useful when you want information about a single symbol (like for getCompletionEntryDetails).
2457-
function getCompletionData(fileName: string, position: number, symbolName?: string) {
2458-
let result = getCompletionDataWorker(fileName, position, symbolName);
2459-
if (!result) {
2460-
return undefined;
2461-
}
2462-
2463-
if (result.symbols && symbolName) {
2464-
var target = program.getCompilerOptions().target;
2465-
result.symbols = filter(result.symbols, s => getValidCompletionEntryDisplayName(s, target) === symbolName);
2466-
}
2467-
2468-
return result;
2469-
}
2470-
2471-
function getCompletionDataWorker(fileName: string, position: number, symbolName: string) {
2461+
function getCompletionData(fileName: string, position: number) {
24722462
let syntacticStart = new Date().getTime();
24732463
let sourceFile = getValidSourceFile(fileName);
24742464

@@ -2600,11 +2590,7 @@ module ts {
26002590
let scopeNode = getScopeNode(previousToken, position, sourceFile);
26012591
let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
26022592

2603-
// Filter down to the symbol that matches the symbolName if we were given one.
2604-
let predicate = symbolName !== undefined
2605-
? (s: Symbol) => getValidCompletionEntryDisplayName(s, target) === symbolName
2606-
: undefined;
2607-
symbols = typeInfoResolver.getSymbolsInScope(scopeNode, symbolMeanings, predicate);
2593+
symbols = typeInfoResolver.getSymbolsInScope(scopeNode, symbolMeanings);
26082594
}
26092595
}
26102596

@@ -2955,12 +2941,16 @@ module ts {
29552941
function getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails {
29562942
synchronizeHostData();
29572943

2958-
// Look up a completion symbol with this name.
2959-
let completionData = getCompletionData(fileName, position, entryName);
2944+
// Compute all the completion symbols again.
2945+
let completionData = getCompletionData(fileName, position);
29602946
if (completionData) {
29612947
let { symbols, location } = completionData;
2962-
if (symbols && symbols.length > 0) {
2963-
let symbol = symbols[0];
2948+
2949+
// Find the symbol with the matching entry name.
2950+
let target = program.getCompilerOptions().target;
2951+
let symbol = forEach(symbols, s => getCompletionEntryDisplayName(s, target, /*performCharacterChecks:*/ false) === entryName ? s : undefined);
2952+
2953+
if (symbol) {
29642954
let displayPartsDocumentationsAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, typeInfoResolver, location, SemanticMeaning.All);
29652955
return {
29662956
name: entryName,

tests/baselines/reference/APISample_compile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,7 @@ declare module "typescript" {
860860
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
861861
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
862862
getReturnTypeOfSignature(signature: Signature): Type;
863-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
863+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
864864
getSymbolAtLocation(node: Node): Symbol;
865865
getShorthandAssignmentValueSymbol(location: Node): Symbol;
866866
getTypeAtLocation(node: Node): Type;

tests/baselines/reference/APISample_compile.types

+2-5
Original file line numberDiff line numberDiff line change
@@ -2632,15 +2632,12 @@ declare module "typescript" {
26322632
>Signature : Signature
26332633
>Type : Type
26342634

2635-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
2636-
>getSymbolsInScope : (location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean) => Symbol[]
2635+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
2636+
>getSymbolsInScope : (location: Node, meaning: SymbolFlags) => Symbol[]
26372637
>location : Node
26382638
>Node : Node
26392639
>meaning : SymbolFlags
26402640
>SymbolFlags : SymbolFlags
2641-
>predicate : (symbol: Symbol) => boolean
2642-
>symbol : Symbol
2643-
>Symbol : Symbol
26442641
>Symbol : Symbol
26452642

26462643
getSymbolAtLocation(node: Node): Symbol;

tests/baselines/reference/APISample_linter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ declare module "typescript" {
891891
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
892892
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
893893
getReturnTypeOfSignature(signature: Signature): Type;
894-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
894+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
895895
getSymbolAtLocation(node: Node): Symbol;
896896
getShorthandAssignmentValueSymbol(location: Node): Symbol;
897897
getTypeAtLocation(node: Node): Type;

tests/baselines/reference/APISample_linter.types

+2-5
Original file line numberDiff line numberDiff line change
@@ -2778,15 +2778,12 @@ declare module "typescript" {
27782778
>Signature : Signature
27792779
>Type : Type
27802780

2781-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
2782-
>getSymbolsInScope : (location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean) => Symbol[]
2781+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
2782+
>getSymbolsInScope : (location: Node, meaning: SymbolFlags) => Symbol[]
27832783
>location : Node
27842784
>Node : Node
27852785
>meaning : SymbolFlags
27862786
>SymbolFlags : SymbolFlags
2787-
>predicate : (symbol: Symbol) => boolean
2788-
>symbol : Symbol
2789-
>Symbol : Symbol
27902787
>Symbol : Symbol
27912788

27922789
getSymbolAtLocation(node: Node): Symbol;

tests/baselines/reference/APISample_transform.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ declare module "typescript" {
892892
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
893893
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
894894
getReturnTypeOfSignature(signature: Signature): Type;
895-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
895+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
896896
getSymbolAtLocation(node: Node): Symbol;
897897
getShorthandAssignmentValueSymbol(location: Node): Symbol;
898898
getTypeAtLocation(node: Node): Type;

tests/baselines/reference/APISample_transform.types

+2-5
Original file line numberDiff line numberDiff line change
@@ -2728,15 +2728,12 @@ declare module "typescript" {
27282728
>Signature : Signature
27292729
>Type : Type
27302730

2731-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
2732-
>getSymbolsInScope : (location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean) => Symbol[]
2731+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
2732+
>getSymbolsInScope : (location: Node, meaning: SymbolFlags) => Symbol[]
27332733
>location : Node
27342734
>Node : Node
27352735
>meaning : SymbolFlags
27362736
>SymbolFlags : SymbolFlags
2737-
>predicate : (symbol: Symbol) => boolean
2738-
>symbol : Symbol
2739-
>Symbol : Symbol
27402737
>Symbol : Symbol
27412738

27422739
getSymbolAtLocation(node: Node): Symbol;

tests/baselines/reference/APISample_watcher.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ declare module "typescript" {
929929
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
930930
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
931931
getReturnTypeOfSignature(signature: Signature): Type;
932-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
932+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
933933
getSymbolAtLocation(node: Node): Symbol;
934934
getShorthandAssignmentValueSymbol(location: Node): Symbol;
935935
getTypeAtLocation(node: Node): Type;

tests/baselines/reference/APISample_watcher.types

+2-5
Original file line numberDiff line numberDiff line change
@@ -2901,15 +2901,12 @@ declare module "typescript" {
29012901
>Signature : Signature
29022902
>Type : Type
29032903

2904-
getSymbolsInScope(location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean): Symbol[];
2905-
>getSymbolsInScope : (location: Node, meaning: SymbolFlags, predicate?: (symbol: Symbol) => boolean) => Symbol[]
2904+
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
2905+
>getSymbolsInScope : (location: Node, meaning: SymbolFlags) => Symbol[]
29062906
>location : Node
29072907
>Node : Node
29082908
>meaning : SymbolFlags
29092909
>SymbolFlags : SymbolFlags
2910-
>predicate : (symbol: Symbol) => boolean
2911-
>symbol : Symbol
2912-
>Symbol : Symbol
29132910
>Symbol : Symbol
29142911

29152912
getSymbolAtLocation(node: Node): Symbol;

0 commit comments

Comments
 (0)