Skip to content

Commit f4253de

Browse files
committed
Give JSDoc-provided modifiers their own entries in ModifierFlags
1 parent 6a48508 commit f4253de

File tree

4 files changed

+88
-86
lines changed

4 files changed

+88
-86
lines changed

src/compiler/types.ts

+39-21
Original file line numberDiff line numberDiff line change
@@ -851,26 +851,45 @@ export const enum NodeFlags {
851851
// dprint-ignore
852852
export const enum ModifierFlags {
853853
None = 0,
854-
Export = 1 << 0, // Declarations
855-
Ambient = 1 << 1, // Declarations
856-
Public = 1 << 2, // Property/Method
857-
Private = 1 << 3, // Property/Method
858-
Protected = 1 << 4, // Property/Method
859-
Static = 1 << 5, // Property/Method
860-
Readonly = 1 << 6, // Property/Method
861-
Accessor = 1 << 7, // Property
862-
Abstract = 1 << 8, // Class/Method/ConstructSignature
863-
Async = 1 << 9, // Property/Method/Function
864-
Default = 1 << 10, // Function/Class (export default declaration)
865-
Const = 1 << 11, // Const enum
866-
Deprecated = 1 << 12, // Deprecated tag.
867-
Override = 1 << 13, // Override method.
868-
In = 1 << 14, // Contravariance modifier
869-
Out = 1 << 15, // Covariance modifier
870-
Decorator = 1 << 16, // Contains a decorator.
871-
872-
HasComputedJSDocModifiers = 1 << 27, // Indicates the computed modifier flags include modifiers from JSDoc.
873-
HasExcessJDocModifiers = 1 << 28, // Indicates that there are JSDoc modifiers that are not in the cache and must be recalculated. For use with nodes in TS files only.
854+
855+
// Syntactic/JSDoc modifiers
856+
Public = 1 << 0, // Property/Method
857+
Private = 1 << 1, // Property/Method
858+
Protected = 1 << 2, // Property/Method
859+
Readonly = 1 << 3, // Property/Method
860+
Override = 1 << 4, // Override method.
861+
862+
// Syntactic-only modifiers
863+
Export = 1 << 5, // Declarations
864+
Abstract = 1 << 6, // Class/Method/ConstructSignature
865+
Ambient = 1 << 7, // Declarations
866+
Static = 1 << 8, // Property/Method
867+
Accessor = 1 << 9, // Property
868+
Async = 1 << 10, // Property/Method/Function
869+
Default = 1 << 11, // Function/Class (export default declaration)
870+
Const = 1 << 12, // Const enum
871+
In = 1 << 13, // Contravariance modifier
872+
Out = 1 << 14, // Covariance modifier
873+
Decorator = 1 << 15, // Contains a decorator.
874+
875+
// JSDoc-only modifiers
876+
Deprecated = 1 << 16, // Deprecated tag.
877+
878+
// Cache-only JSDoc-modifiers. Should match order of Syntactic/JSDoc modifiers, above.
879+
/** @internal */ JSDocPublic = 1 << 23, // if this value changes, `adjustJSDocModifierFlags` must change accordingly
880+
/** @internal */ JSDocPrivate = 1 << 24,
881+
/** @internal */ JSDocProtected = 1 << 25,
882+
/** @internal */ JSDocReadonly = 1 << 26,
883+
/** @internal */ JSDocOverride = 1 << 27,
884+
885+
/** @internal */ SyntacticOrJSDocModifiers = Public | Private | Protected | Readonly | Override,
886+
/** @internal */ SyntacticOnlyModifiers = Export | Ambient | Abstract | Static | Accessor | Async | Default | Const | In | Out | Decorator,
887+
/** @internal */ SyntacticModifiers = SyntacticOrJSDocModifiers | SyntacticOnlyModifiers,
888+
/** @internal */ JSDocCacheOnlyModifiers = JSDocPublic | JSDocPrivate | JSDocProtected | JSDocReadonly | JSDocOverride,
889+
/** @internal */ JSDocOnlyModifiers = Deprecated,
890+
/** @internal */ NonCacheOnlyModifiers = SyntacticOrJSDocModifiers | SyntacticOnlyModifiers | JSDocOnlyModifiers,
891+
892+
HasComputedJSDocModifiers = 1 << 28, // Indicates the computed modifier flags include modifiers from JSDoc.
874893
HasComputedFlags = 1 << 29, // Modifier flags have been computed
875894

876895
AccessibilityModifier = Public | Private | Protected,
@@ -879,7 +898,6 @@ export const enum ModifierFlags {
879898
NonPublicAccessibilityModifier = Private | Protected,
880899

881900
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const | Override | In | Out,
882-
JSDocOnlyModifier = Deprecated,
883901
ExportDefault = Export | Default,
884902
All = Export | Ambient | Public | Private | Protected | Static | Readonly | Abstract | Accessor | Async | Default | Const | Deprecated | Override | In | Out | Decorator,
885903
Modifier = All & ~Decorator,

src/compiler/utilities.ts

+24-38
Original file line numberDiff line numberDiff line change
@@ -6924,45 +6924,18 @@ function getModifierFlagsWorker(node: Node, includeJSDoc: boolean, alwaysInclude
69246924
return ModifierFlags.None;
69256925
}
69266926

6927-
// Calculate the modifier flags for a given node, and cache them based on the file containing the node.
6928-
// For a TypeScript file, the cache will only contain syntactic modifiers and potentially the `Deprecated` JSDoc modifier.
6929-
// For a JavaScript file, the cache will contain both syntactic and JSDoc modifiers.
6930-
69316927
if (!(node.modifierFlagsCache & ModifierFlags.HasComputedFlags)) {
69326928
node.modifierFlagsCache = getSyntacticModifierFlagsNoCache(node) | ModifierFlags.HasComputedFlags;
69336929
}
69346930

6935-
let jsdocModifierFlags: ModifierFlags | undefined;
6936-
if (includeJSDoc && !(node.modifierFlagsCache & ModifierFlags.HasComputedJSDocModifiers) && node.parent) {
6937-
jsdocModifierFlags = getJSDocModifierFlagsNoCache(node);
6938-
if (isInJSFile(node)) {
6939-
node.modifierFlagsCache |= jsdocModifierFlags | ModifierFlags.HasComputedJSDocModifiers;
6940-
}
6941-
else {
6942-
node.modifierFlagsCache |= (jsdocModifierFlags & ModifierFlags.Deprecated) | ModifierFlags.HasComputedJSDocModifiers;
6943-
if (jsdocModifierFlags & ~node.modifierFlagsCache & ~ModifierFlags.Deprecated) {
6944-
// If there are other JSDoc modifiers aside from `@deprecated` that aren't also in the set of syntactic modifiers for the node,
6945-
// we can add a flag indicating we need to recompute JSDoc modifiers when `alwaysIncludeJSDoc` is true.
6946-
node.modifierFlagsCache |= ModifierFlags.HasExcessJDocModifiers;
6947-
}
6931+
if (alwaysIncludeJSDoc || includeJSDoc && isInJSFile(node)) {
6932+
if (!(node.modifierFlagsCache & ModifierFlags.HasComputedJSDocModifiers) && node.parent) {
6933+
node.modifierFlagsCache |= getRawJSDocModifierFlagsNoCache(node) | ModifierFlags.HasComputedJSDocModifiers;
69486934
}
6935+
return selectEffectiveModifierFlags(node.modifierFlagsCache);
69496936
}
69506937

6951-
const modifiers = node.modifierFlagsCache & ~(ModifierFlags.HasComputedFlags | ModifierFlags.HasComputedJSDocModifiers | ModifierFlags.HasExcessJDocModifiers);
6952-
if (includeJSDoc || alwaysIncludeJSDoc) {
6953-
if (!isInJSFile(node) && alwaysIncludeJSDoc && node.modifierFlagsCache & ModifierFlags.HasExcessJDocModifiers) {
6954-
// If we are requesting JSDoc modifiers in a TS file, we only need to recalculate additional JSDoc modifiers if the cache indicates there are any to find.
6955-
// We recalculate the JSDoc modifiers since they may overlap with the syntactic modifiers in the cache. While this isn't as efficient as caching the modifiers,
6956-
// it is rare to use JSDoc for modifiers like `@private` in a TS file.
6957-
jsdocModifierFlags ??= getJSDocModifierFlagsNoCache(node);
6958-
return modifiers | jsdocModifierFlags;
6959-
}
6960-
return modifiers;
6961-
}
6962-
else {
6963-
// We are requesting only syntactic modifiers. filter out any JSDoc modifiers in the cache.
6964-
return (isInJSFile(node) ? modifiers & ~ModifierFlags.TypeScriptModifier : modifiers) & ~ModifierFlags.JSDocOnlyModifier;
6965-
}
6938+
return selectSyntacticModifierFlags(node.modifierFlagsCache);
69666939
}
69676940

69686941
/**
@@ -6992,22 +6965,35 @@ export function getSyntacticModifierFlags(node: Node): ModifierFlags {
69926965
return getModifierFlagsWorker(node, /*includeJSDoc*/ false);
69936966
}
69946967

6995-
function getJSDocModifierFlagsNoCache(node: Node): ModifierFlags {
6968+
function getRawJSDocModifierFlagsNoCache(node: Node): ModifierFlags {
69966969
let flags = ModifierFlags.None;
69976970
if (!!node.parent && !isParameter(node)) {
69986971
if (isInJSFile(node)) {
6999-
if (getJSDocPublicTagNoCache(node)) flags |= ModifierFlags.Public;
7000-
if (getJSDocPrivateTagNoCache(node)) flags |= ModifierFlags.Private;
7001-
if (getJSDocProtectedTagNoCache(node)) flags |= ModifierFlags.Protected;
7002-
if (getJSDocReadonlyTagNoCache(node)) flags |= ModifierFlags.Readonly;
7003-
if (getJSDocOverrideTagNoCache(node)) flags |= ModifierFlags.Override;
6972+
if (getJSDocPublicTagNoCache(node)) flags |= ModifierFlags.JSDocPublic;
6973+
if (getJSDocPrivateTagNoCache(node)) flags |= ModifierFlags.JSDocPrivate;
6974+
if (getJSDocProtectedTagNoCache(node)) flags |= ModifierFlags.JSDocProtected;
6975+
if (getJSDocReadonlyTagNoCache(node)) flags |= ModifierFlags.JSDocReadonly;
6976+
if (getJSDocOverrideTagNoCache(node)) flags |= ModifierFlags.JSDocOverride;
70046977
}
70056978
if (getJSDocDeprecatedTagNoCache(node)) flags |= ModifierFlags.Deprecated;
70066979
}
70076980

70086981
return flags;
70096982
}
70106983

6984+
function selectSyntacticModifierFlags(flags: ModifierFlags) {
6985+
return flags & ModifierFlags.SyntacticModifiers;
6986+
}
6987+
6988+
function selectEffectiveModifierFlags(flags: ModifierFlags) {
6989+
return (flags & ModifierFlags.NonCacheOnlyModifiers) |
6990+
((flags & ModifierFlags.JSDocCacheOnlyModifiers) >>> 23); // shift ModifierFlags.JSDoc* to match ModifierFlags.*
6991+
}
6992+
6993+
function getJSDocModifierFlagsNoCache(node: Node): ModifierFlags {
6994+
return selectEffectiveModifierFlags(getRawJSDocModifierFlagsNoCache(node));
6995+
}
6996+
70116997
/**
70126998
* Gets the effective ModifierFlags for the provided node, including JSDoc modifiers. The modifier flags cache on the node is ignored.
70136999
*

tests/baselines/reference/api/typescript.d.ts

+24-26
Original file line numberDiff line numberDiff line change
@@ -4752,34 +4752,32 @@ declare namespace ts {
47524752
}
47534753
enum ModifierFlags {
47544754
None = 0,
4755-
Export = 1,
4756-
Ambient = 2,
4757-
Public = 4,
4758-
Private = 8,
4759-
Protected = 16,
4760-
Static = 32,
4761-
Readonly = 64,
4762-
Accessor = 128,
4763-
Abstract = 256,
4764-
Async = 512,
4765-
Default = 1024,
4766-
Const = 2048,
4767-
Deprecated = 4096,
4768-
Override = 8192,
4769-
In = 16384,
4770-
Out = 32768,
4771-
Decorator = 65536,
4772-
HasComputedJSDocModifiers = 134217728,
4773-
HasExcessJDocModifiers = 268435456,
4755+
Public = 1,
4756+
Private = 2,
4757+
Protected = 4,
4758+
Readonly = 8,
4759+
Override = 16,
4760+
Export = 32,
4761+
Abstract = 64,
4762+
Ambient = 128,
4763+
Static = 256,
4764+
Accessor = 512,
4765+
Async = 1024,
4766+
Default = 2048,
4767+
Const = 4096,
4768+
In = 8192,
4769+
Out = 16384,
4770+
Decorator = 32768,
4771+
Deprecated = 65536,
4772+
HasComputedJSDocModifiers = 268435456,
47744773
HasComputedFlags = 536870912,
4775-
AccessibilityModifier = 28,
4776-
ParameterPropertyModifier = 8284,
4777-
NonPublicAccessibilityModifier = 24,
4778-
TypeScriptModifier = 59742,
4779-
JSDocOnlyModifier = 4096,
4780-
ExportDefault = 1025,
4774+
AccessibilityModifier = 7,
4775+
ParameterPropertyModifier = 31,
4776+
NonPublicAccessibilityModifier = 6,
4777+
TypeScriptModifier = 28895,
4778+
ExportDefault = 2080,
47814779
All = 131071,
4782-
Modifier = 65535,
4780+
Modifier = 98303,
47834781
}
47844782
enum JsxFlags {
47854783
None = 0,

tests/baselines/reference/jsFileCompilationPublicParameterModifier.symbols

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
=== a.js ===
44
class C { constructor(public x) { }}
55
>C : Symbol(C, Decl(a.js, 0, 0))
6-
>x : Symbol(x, Decl(a.js, 0, 22))
6+
>x : Symbol(C.x, Decl(a.js, 0, 22))
77

0 commit comments

Comments
 (0)