Skip to content

Commit f30f399

Browse files
committed
Parser: don't call hasModifier(s) anymore.
Then move jsdoc modifier tag checks into getModifierFlagsNoCache where they should be. The jsdoc checks are skipped when the parent is undefined. There are 3 cases when this can happen: 1. The code is in the parser (or a few places in the binder, notably declareSymbol of module.exports assignments). 2. The node is a source file. 3. The node is synthetic, which I assume to be from the transforms. It is fine to call getModifierFlags in cases (2) and (3). It is not fine for (1), so I removed these calls and replaced them with simple iteration over the modifiers. Worth noting: Ron's uniform node construction PR removes these calls anyway; this PR just does it early.
1 parent 62a568d commit f30f399

File tree

5 files changed

+29
-28
lines changed

5 files changed

+29
-28
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5322,7 +5322,7 @@ namespace ts {
53225322
newModifierFlags |= ModifierFlags.Default;
53235323
}
53245324
if (newModifierFlags) {
5325-
node.modifiers = createNodeArray(createModifiersFromModifierFlags(newModifierFlags | getEffectiveModifierFlags(node)));
5325+
node.modifiers = createNodeArray(createModifiersFromModifierFlags(newModifierFlags | getModifierFlags(node)));
53265326
node.modifierFlagsCache = 0; // Reset computed flags cache
53275327
}
53285328
results.push(node);
@@ -6102,7 +6102,7 @@ namespace ts {
61026102
}
61036103
}
61046104
}
6105-
if (signatures.some(s => s.declaration && getEffectiveModifierFlags(s.declaration) & ModifierFlags.Private)) {
6105+
if (signatures.some(s => s.declaration && getModifierFlags(s.declaration) & ModifierFlags.Private)) {
61066106
return [setTextRange(createProperty(
61076107
/*decorators*/ undefined,
61086108
createModifiersFromModifierFlags(ModifierFlags.Private),
@@ -28360,8 +28360,8 @@ namespace ts {
2836028360
const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
2836128361
const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfNode(node), otherKind);
2836228362
if (otherAccessor) {
28363-
const nodeFlags = getEffectiveModifierFlags(node);
28364-
const otherFlags = getEffectiveModifierFlags(otherAccessor);
28363+
const nodeFlags = getModifierFlags(node);
28364+
const otherFlags = getModifierFlags(otherAccessor);
2836528365
if ((nodeFlags & ModifierFlags.AccessibilityModifier) !== (otherFlags & ModifierFlags.AccessibilityModifier)) {
2836628366
error(node.name, Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
2836728367
}

src/compiler/parser.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,7 +2584,7 @@ namespace ts {
25842584
// FormalParameter [Yield,Await]:
25852585
// BindingElement[?Yield,?Await]
25862586
node.name = parseIdentifierOrPattern();
2587-
if (getFullWidth(node.name) === 0 && !hasModifiers(node) && isModifierKind(token())) {
2587+
if (getFullWidth(node.name) === 0 && !node.modifiers && isModifierKind(token())) {
25882588
// in cases like
25892589
// 'use strict'
25902590
// function foo(static)
@@ -3603,7 +3603,7 @@ namespace ts {
36033603
return undefined;
36043604
}
36053605

3606-
const isAsync = hasModifier(arrowFunction, ModifierFlags.Async);
3606+
const isAsync = hasModifierOfKind(arrowFunction, SyntaxKind.AsyncKeyword);
36073607

36083608
// If we have an arrow, then try to parse the body. Even if not, try to parse if we
36093609
// have an opening brace, just in case we're in an error state.
@@ -3809,7 +3809,7 @@ namespace ts {
38093809
function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction | undefined {
38103810
const node = <ArrowFunction>createNodeWithJSDoc(SyntaxKind.ArrowFunction);
38113811
node.modifiers = parseModifiersForArrowFunction();
3812-
const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None;
3812+
const isAsync = hasModifierOfKind(node, SyntaxKind.AsyncKeyword) ? SignatureFlags.Await : SignatureFlags.None;
38133813
// Arrow functions are never generators.
38143814
//
38153815
// If we're speculatively parsing a signature for a parenthesized arrow function, then
@@ -5005,7 +5005,7 @@ namespace ts {
50055005
node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
50065006

50075007
const isGenerator = node.asteriskToken ? SignatureFlags.Yield : SignatureFlags.None;
5008-
const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None;
5008+
const isAsync = hasModifierOfKind(node, SyntaxKind.AsyncKeyword) ? SignatureFlags.Await : SignatureFlags.None;
50095009
node.name =
50105010
isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
50115011
isGenerator ? doInYieldContext(parseOptionalIdentifier) :
@@ -5834,9 +5834,9 @@ namespace ts {
58345834
node.kind = SyntaxKind.FunctionDeclaration;
58355835
parseExpected(SyntaxKind.FunctionKeyword);
58365836
node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
5837-
node.name = hasModifier(node, ModifierFlags.Default) ? parseOptionalIdentifier() : parseIdentifier();
5837+
node.name = hasModifierOfKind(node, SyntaxKind.DefaultKeyword) ? parseOptionalIdentifier() : parseIdentifier();
58385838
const isGenerator = node.asteriskToken ? SignatureFlags.Yield : SignatureFlags.None;
5839-
const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None;
5839+
const isAsync = hasModifierOfKind(node, SyntaxKind.AsyncKeyword) ? SignatureFlags.Await : SignatureFlags.None;
58405840
fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node);
58415841
node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, Diagnostics.or_expected);
58425842
return finishNode(node);
@@ -5869,7 +5869,7 @@ namespace ts {
58695869
node.kind = SyntaxKind.MethodDeclaration;
58705870
node.asteriskToken = asteriskToken;
58715871
const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None;
5872-
const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None;
5872+
const isAsync = hasModifierOfKind(node, SyntaxKind.AsyncKeyword) ? SignatureFlags.Await : SignatureFlags.None;
58735873
fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node);
58745874
node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage);
58755875
return finishNode(node);
@@ -6511,7 +6511,7 @@ namespace ts {
65116511
}
65126512

65136513
function isAnExternalModuleIndicatorNode(node: Node) {
6514-
return hasModifier(node, ModifierFlags.Export)
6514+
return hasModifierOfKind(node, SyntaxKind.ExportKeyword)
65156515
|| node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
65166516
|| node.kind === SyntaxKind.ImportDeclaration
65176517
|| node.kind === SyntaxKind.ExportAssignment
@@ -6528,6 +6528,11 @@ namespace ts {
65286528
return isImportMeta(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
65296529
}
65306530

6531+
/** Do not use hasModifier inside the parser; it relies on parent pointers. Use this instead. */
6532+
function hasModifierOfKind(node: Node, kind: SyntaxKind) {
6533+
return some(node.modifiers, m => m.kind === kind);
6534+
}
6535+
65316536
function isImportMeta(node: Node): boolean {
65326537
return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta";
65336538
}

src/compiler/transformers/declarations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ namespace ts {
14731473
}
14741474

14751475
function maskModifierFlags(node: Node, modifierMask: ModifierFlags = ModifierFlags.All ^ ModifierFlags.Public, modifierAdditions: ModifierFlags = ModifierFlags.None): ModifierFlags {
1476-
let flags = (getEffectiveModifierFlags(node) & modifierMask) | modifierAdditions;
1476+
let flags = (getModifierFlags(node) & modifierMask) | modifierAdditions;
14771477
if (flags & ModifierFlags.Default && !(flags & ModifierFlags.Export)) {
14781478
// A non-exported default is a nonsequitor - we usually try to remove all export modifiers
14791479
// from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid

src/compiler/utilities.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4100,7 +4100,7 @@ namespace ts {
41004100
}
41014101

41024102
export function getSelectedModifierFlags(node: Node, flags: ModifierFlags): ModifierFlags {
4103-
return getEffectiveModifierFlags(node) & flags;
4103+
return getModifierFlags(node) & flags;
41044104
}
41054105

41064106
export function getModifierFlags(node: Node): ModifierFlags {
@@ -4121,23 +4121,19 @@ namespace ts {
41214121
}
41224122
}
41234123

4124-
if (node.flags & NodeFlags.NestedNamespace || (node.kind === SyntaxKind.Identifier && (<Identifier>node).isInJSDocNamespace)) {
4125-
flags |= ModifierFlags.Export;
4126-
}
4127-
4128-
return flags;
4129-
}
4130-
4131-
export function getEffectiveModifierFlags(node: Node) {
4132-
const flags = getModifierFlags(node);
4133-
if (!!node.parent && isInJSFile(node)) {
4134-
// Do not try to look for tags during parsing, because parent pointers aren't set and
4135-
// non-local tags will incorrectly be missed; this wrong answer will be cached.
4124+
if (isInJSFile(node) && !!node.parent) {
4125+
// getModifierFlagsNoCache should only be called when parent pointers are set,
4126+
// or when !(node.flags & NodeFlags.Synthesized) && node.kind !== SyntaxKind.SourceFile)
41364127
const tags = (getJSDocPublicTag(node) ? ModifierFlags.Public : ModifierFlags.None)
41374128
| (getJSDocPrivateTag(node) ? ModifierFlags.Private : ModifierFlags.None)
41384129
| (getJSDocProtectedTag(node) ? ModifierFlags.Protected : ModifierFlags.None);
4139-
return flags | tags;
4130+
flags |= tags;
4131+
}
4132+
4133+
if (node.flags & NodeFlags.NestedNamespace || (node.kind === SyntaxKind.Identifier && (<Identifier>node).isInJSDocNamespace)) {
4134+
flags |= ModifierFlags.Export;
41404135
}
4136+
41414137
return flags;
41424138
}
41434139

src/compiler/utilitiesPublic.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ namespace ts {
299299
}
300300

301301
export function getCombinedModifierFlags(node: Declaration): ModifierFlags {
302-
return getCombinedFlags(node, getEffectiveModifierFlags);
302+
return getCombinedFlags(node, getModifierFlags);
303303
}
304304

305305
// Returns the node flags for this node and all relevant parent nodes. This is done so that

0 commit comments

Comments
 (0)