Skip to content

Commit de9c459

Browse files
author
Andy
authored
Clean up code in getModifierOccurrences (#18948)
1 parent d03d237 commit de9c459

File tree

2 files changed

+47
-69
lines changed

2 files changed

+47
-69
lines changed

src/compiler/core.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ namespace ts {
247247
}
248248

249249
/** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */
250+
export function find<T, U extends T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => element is U): U | undefined;
251+
export function find<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean): T | undefined;
250252
export function find<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean): T | undefined {
251253
for (let i = 0; i < array.length; i++) {
252254
const value = array[i];

src/services/documentHighlights.ts

Lines changed: 45 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -265,40 +265,23 @@ namespace ts.DocumentHighlights {
265265
}
266266

267267
function getModifierOccurrences(modifier: SyntaxKind, declaration: Node): Node[] {
268-
const container = declaration.parent;
269-
270268
// Make sure we only highlight the keyword when it makes sense to do so.
271-
if (isAccessibilityModifier(modifier)) {
272-
if (!(container.kind === SyntaxKind.ClassDeclaration ||
273-
container.kind === SyntaxKind.ClassExpression ||
274-
(declaration.kind === SyntaxKind.Parameter && hasKind(container, SyntaxKind.Constructor)))) {
275-
return undefined;
276-
}
277-
}
278-
else if (modifier === SyntaxKind.StaticKeyword) {
279-
if (!(container.kind === SyntaxKind.ClassDeclaration || container.kind === SyntaxKind.ClassExpression)) {
280-
return undefined;
281-
}
282-
}
283-
else if (modifier === SyntaxKind.ExportKeyword || modifier === SyntaxKind.DeclareKeyword) {
284-
if (!(container.kind === SyntaxKind.ModuleBlock || container.kind === SyntaxKind.SourceFile)) {
285-
return undefined;
286-
}
287-
}
288-
else if (modifier === SyntaxKind.AbstractKeyword) {
289-
if (!(container.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.ClassDeclaration)) {
290-
return undefined;
291-
}
292-
}
293-
else {
294-
// unsupported modifier
269+
if (!isLegalModifier(modifier, declaration)) {
295270
return undefined;
296271
}
297272

298-
const keywords: Node[] = [];
299-
const modifierFlag: ModifierFlags = getFlagFromModifier(modifier);
273+
const modifierFlag = modifierToFlag(modifier);
274+
return mapDefined(getNodesToSearchForModifier(declaration, modifierFlag), node => {
275+
if (getModifierFlags(node) & modifierFlag) {
276+
const mod = find(node.modifiers, m => m.kind === modifier);
277+
Debug.assert(!!mod);
278+
return mod;
279+
}
280+
});
281+
}
300282

301-
let nodes: ReadonlyArray<Node>;
283+
function getNodesToSearchForModifier(declaration: Node, modifierFlag: ModifierFlags): ReadonlyArray<Node> {
284+
const container = declaration.parent;
302285
switch (container.kind) {
303286
case SyntaxKind.ModuleBlock:
304287
case SyntaxKind.SourceFile:
@@ -307,65 +290,58 @@ namespace ts.DocumentHighlights {
307290
case SyntaxKind.DefaultClause:
308291
// Container is either a class declaration or the declaration is a classDeclaration
309292
if (modifierFlag & ModifierFlags.Abstract) {
310-
nodes = [...(<ClassDeclaration>declaration).members, declaration];
293+
return [...(<ClassDeclaration>declaration).members, declaration];
311294
}
312295
else {
313-
nodes = (<ModuleBlock | SourceFile | Block | CaseClause | DefaultClause>container).statements;
296+
return (<ModuleBlock | SourceFile | Block | CaseClause | DefaultClause>container).statements;
314297
}
315-
break;
316298
case SyntaxKind.Constructor:
317-
nodes = [...(<ConstructorDeclaration>container).parameters, ...(<ClassDeclaration>container.parent).members];
318-
break;
299+
return [...(<ConstructorDeclaration>container).parameters, ...(<ClassDeclaration>container.parent).members];
319300
case SyntaxKind.ClassDeclaration:
320301
case SyntaxKind.ClassExpression:
321-
nodes = (<ClassLikeDeclaration>container).members;
302+
const nodes = (<ClassLikeDeclaration>container).members;
322303

323304
// If we're an accessibility modifier, we're in an instance member and should search
324305
// the constructor's parameter list for instance members as well.
325306
if (modifierFlag & ModifierFlags.AccessibilityModifier) {
326-
const constructor = forEach((<ClassLikeDeclaration>container).members, member => {
327-
return member.kind === SyntaxKind.Constructor && <ConstructorDeclaration>member;
328-
});
329-
307+
const constructor = find((<ClassLikeDeclaration>container).members, isConstructorDeclaration);
330308
if (constructor) {
331-
nodes = [...nodes, ...constructor.parameters];
309+
return [...nodes, ...constructor.parameters];
332310
}
333311
}
334312
else if (modifierFlag & ModifierFlags.Abstract) {
335-
nodes = [...nodes, container];
313+
return [...nodes, container];
336314
}
337-
break;
315+
return nodes;
338316
default:
339317
Debug.fail("Invalid container kind.");
340318
}
319+
}
341320

342-
forEach(nodes, node => {
343-
if (getModifierFlags(node) & modifierFlag) {
344-
forEach(node.modifiers, child => pushKeywordIf(keywords, child, modifier));
345-
}
346-
});
347-
348-
return keywords;
349-
350-
function getFlagFromModifier(modifier: SyntaxKind) {
351-
switch (modifier) {
352-
case SyntaxKind.PublicKeyword:
353-
return ModifierFlags.Public;
354-
case SyntaxKind.PrivateKeyword:
355-
return ModifierFlags.Private;
356-
case SyntaxKind.ProtectedKeyword:
357-
return ModifierFlags.Protected;
358-
case SyntaxKind.StaticKeyword:
359-
return ModifierFlags.Static;
360-
case SyntaxKind.ExportKeyword:
361-
return ModifierFlags.Export;
362-
case SyntaxKind.DeclareKeyword:
363-
return ModifierFlags.Ambient;
364-
case SyntaxKind.AbstractKeyword:
365-
return ModifierFlags.Abstract;
366-
default:
367-
Debug.fail();
368-
}
321+
function isLegalModifier(modifier: SyntaxKind, declaration: Node): boolean {
322+
const container = declaration.parent;
323+
switch (modifier) {
324+
case SyntaxKind.PrivateKeyword:
325+
case SyntaxKind.ProtectedKeyword:
326+
case SyntaxKind.PublicKeyword:
327+
switch (container.kind) {
328+
case SyntaxKind.ClassDeclaration:
329+
case SyntaxKind.ClassExpression:
330+
return true;
331+
case SyntaxKind.Constructor:
332+
return declaration.kind === SyntaxKind.Parameter;
333+
default:
334+
return false;
335+
}
336+
case SyntaxKind.StaticKeyword:
337+
return container.kind === SyntaxKind.ClassDeclaration || container.kind === SyntaxKind.ClassExpression;
338+
case SyntaxKind.ExportKeyword:
339+
case SyntaxKind.DeclareKeyword:
340+
return container.kind === SyntaxKind.ModuleBlock || container.kind === SyntaxKind.SourceFile;
341+
case SyntaxKind.AbstractKeyword:
342+
return container.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.ClassDeclaration;
343+
default:
344+
return false;
369345
}
370346
}
371347

0 commit comments

Comments
 (0)