diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d753f1b7e4c36..9194f03407ee3 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5628,15 +5628,15 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri * Generate the text for a generated identifier. */ function generateName(name: GeneratedIdentifier | GeneratedPrivateIdentifier) { - if ((name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) === GeneratedIdentifierFlags.Node) { + if ((name.autoGenerate.flags & GeneratedIdentifierFlags.KindMask) === GeneratedIdentifierFlags.Node) { // Node names generate unique names based on their original node // and are cached based on that node's id. - return generateNameCached(getNodeForGeneratedName(name), isPrivateIdentifier(name), name.autoGenerateFlags, name.autoGeneratePrefix, name.autoGenerateSuffix); + return generateNameCached(getNodeForGeneratedName(name), isPrivateIdentifier(name), name.autoGenerate.flags, name.autoGenerate.prefix, name.autoGenerate.suffix); } else { // Auto, Loop, and Unique names are cached based on their unique // autoGenerateId. - const autoGenerateId = name.autoGenerateId!; + const autoGenerateId = name.autoGenerate.id; return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name)); } } @@ -5889,27 +5889,27 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri * Generates a unique identifier for a node. */ function makeName(name: GeneratedIdentifier | GeneratedPrivateIdentifier) { - const prefix = formatGeneratedNamePart(name.autoGeneratePrefix, generateName); - const suffix = formatGeneratedNamePart (name.autoGenerateSuffix); - switch (name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) { + const prefix = formatGeneratedNamePart(name.autoGenerate.prefix, generateName); + const suffix = formatGeneratedNamePart (name.autoGenerate.suffix); + switch (name.autoGenerate.flags & GeneratedIdentifierFlags.KindMask) { case GeneratedIdentifierFlags.Auto: - return makeTempVariableName(TempFlags.Auto, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes), isPrivateIdentifier(name), prefix, suffix); + return makeTempVariableName(TempFlags.Auto, !!(name.autoGenerate.flags & GeneratedIdentifierFlags.ReservedInNestedScopes), isPrivateIdentifier(name), prefix, suffix); case GeneratedIdentifierFlags.Loop: Debug.assertNode(name, isIdentifier); - return makeTempVariableName(TempFlags._i, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes), /*privateName*/ false, prefix, suffix); + return makeTempVariableName(TempFlags._i, !!(name.autoGenerate.flags & GeneratedIdentifierFlags.ReservedInNestedScopes), /*privateName*/ false, prefix, suffix); case GeneratedIdentifierFlags.Unique: return makeUniqueName( idText(name), - (name.autoGenerateFlags & GeneratedIdentifierFlags.FileLevel) ? isFileLevelUniqueName : isUniqueName, - !!(name.autoGenerateFlags & GeneratedIdentifierFlags.Optimistic), - !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes), + (name.autoGenerate.flags & GeneratedIdentifierFlags.FileLevel) ? isFileLevelUniqueName : isUniqueName, + !!(name.autoGenerate.flags & GeneratedIdentifierFlags.Optimistic), + !!(name.autoGenerate.flags & GeneratedIdentifierFlags.ReservedInNestedScopes), isPrivateIdentifier(name), prefix, suffix ); } - return Debug.fail(`Unsupported GeneratedIdentifierKind: ${Debug.formatEnum(name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask, (ts as any).GeneratedIdentifierFlags, /*isFlags*/ true)}.`); + return Debug.fail(`Unsupported GeneratedIdentifierKind: ${Debug.formatEnum(name.autoGenerate.flags & GeneratedIdentifierFlags.KindMask, (ts as any).GeneratedIdentifierFlags, /*isFlags*/ true)}.`); } // Comments diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 7b874d33be848..99811f7a315f1 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1154,16 +1154,24 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode const node = baseFactory.createBaseIdentifierNode(SyntaxKind.Identifier) as Mutable; node.originalKeywordKind = originalKeywordKind; node.escapedText = escapedText; - node.autoGenerateFlags = GeneratedIdentifierFlags.None; + node.autoGenerate = undefined; + node.typeArguments = undefined; + node.hasExtendedUnicodeEscape = undefined; + node.jsDoc = undefined; // initialized by parser (JsDocContainer) + node.jsDocCache = undefined; // initialized by parser (JsDocContainer) + node.flowNode = undefined; // initialized by binder (FlowContainer) + node.symbol = undefined!; // initialized by checker return node; } function createBaseGeneratedIdentifier(text: string, autoGenerateFlags: GeneratedIdentifierFlags, prefix: string | GeneratedNamePart | undefined, suffix: string | undefined) { const node = createBaseIdentifier(escapeLeadingUnderscores(text), /*originalKeywordKind*/ undefined) as Mutable; - node.autoGenerateFlags = autoGenerateFlags; - node.autoGenerateId = nextAutoGenerateId; - node.autoGeneratePrefix = prefix; - node.autoGenerateSuffix = suffix; + node.autoGenerate = { + flags: autoGenerateFlags, + id: nextAutoGenerateId, + prefix, + suffix + }; nextAutoGenerateId++; return node; } @@ -1180,10 +1188,6 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode const node = createBaseIdentifier(escapeLeadingUnderscores(text), originalKeywordKind); node.typeArguments = asNodeArray(typeArguments); node.hasExtendedUnicodeEscape = hasExtendedUnicodeEscape; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.jsDocCache = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) - node.symbol = undefined!; // initialized by checker // NOTE: we do not include transform flags of typeArguments in an identifier as they do not contribute to transformations if (node.originalKeywordKind === SyntaxKind.AwaitKeyword) { @@ -1246,7 +1250,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createBasePrivateIdentifier(escapedText: __String) { const node = baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as Mutable; node.escapedText = escapedText; - node.autoGenerateFlags = GeneratedIdentifierFlags.None; + node.autoGenerate = undefined; node.transformFlags |= TransformFlags.ContainsClassFields; return node; } @@ -1259,10 +1263,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createBaseGeneratedPrivateIdentifier(text: string, autoGenerateFlags: GeneratedIdentifierFlags, prefix: string | GeneratedNamePart | undefined, suffix: string | undefined) { const node = createBasePrivateIdentifier(escapeLeadingUnderscores(text)); - node.autoGenerateFlags = autoGenerateFlags; - node.autoGenerateId = nextAutoGenerateId; - node.autoGeneratePrefix = prefix; - node.autoGenerateSuffix = suffix; + node.autoGenerate = { + flags: autoGenerateFlags, + id: nextAutoGenerateId, + prefix, + suffix, + }; nextAutoGenerateId++; return node; } @@ -6374,10 +6380,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function cloneGeneratedIdentifier(node: GeneratedIdentifier): GeneratedIdentifier { const clone = createBaseIdentifier(node.escapedText, /*originalKeywordKind*/ undefined) as Mutable; clone.flags |= node.flags & ~NodeFlags.Synthesized; - clone.autoGenerateFlags = node.autoGenerateFlags; - clone.autoGenerateId = node.autoGenerateId; - clone.autoGeneratePrefix = node.autoGeneratePrefix; - clone.autoGenerateSuffix = node.autoGenerateSuffix; + clone.autoGenerate = { ...node.autoGenerate }; clone.transformFlags = node.transformFlags; setOriginalNode(clone, node); return clone; @@ -6400,10 +6403,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function cloneGeneratedPrivateIdentifier(node: GeneratedPrivateIdentifier): GeneratedPrivateIdentifier { const clone = createBasePrivateIdentifier(node.escapedText) as Mutable; clone.flags |= node.flags & ~NodeFlags.Synthesized; - clone.autoGenerateFlags = node.autoGenerateFlags; - clone.autoGenerateId = node.autoGenerateId; - clone.autoGeneratePrefix = node.autoGeneratePrefix; - clone.autoGenerateSuffix = node.autoGenerateSuffix; + clone.autoGenerate = { ...node.autoGenerate }; clone.transformFlags = node.transformFlags; setOriginalNode(clone, node); return clone; diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 190bd6e7cb8b0..40075da95e036 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -1489,17 +1489,18 @@ export function elideNodes(factory: NodeFactory, nodes: NodeArra * @internal */ export function getNodeForGeneratedName(name: GeneratedIdentifier | GeneratedPrivateIdentifier) { - if (name.autoGenerateFlags & GeneratedIdentifierFlags.Node) { - const autoGenerateId = name.autoGenerateId; + if (name.autoGenerate.flags & GeneratedIdentifierFlags.Node) { + const autoGenerateId = name.autoGenerate.id; let node = name as Node; let original = node.original; while (original) { node = original; // if "node" is a different generated name (having a different "autoGenerateId"), use it and stop traversing. - if (isMemberName(node) - && !!(node.autoGenerateFlags! & GeneratedIdentifierFlags.Node) - && node.autoGenerateId !== autoGenerateId) { + if (isMemberName(node) && ( + node.autoGenerate === undefined || + !!(node.autoGenerate.flags & GeneratedIdentifierFlags.Node) && + node.autoGenerate.id !== autoGenerateId)) { break; } diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 239a7e125453d..50fb29df0a716 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -1512,7 +1512,7 @@ export function transformClassFields(context: TransformationContext): (x: Source // record an alias as the class name is not in scope for statics. enableSubstitutionForClassAliases(); const alias = factory.cloneNode(temp) as GeneratedIdentifier; - alias.autoGenerateFlags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes; + alias.autoGenerate.flags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes; classAliases[getOriginalNodeId(node)] = alias; } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 67458dd66d37a..0a0a1473ade2a 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -2064,7 +2064,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile } return node; } - else if (!(isGeneratedIdentifier(node) && !(node.autoGenerateFlags & GeneratedIdentifierFlags.AllowNameSubstitution)) && !isLocalName(node)) { + else if (!(isGeneratedIdentifier(node) && !(node.autoGenerate.flags & GeneratedIdentifierFlags.AllowNameSubstitution)) && !isLocalName(node)) { const exportContainer = resolver.getReferencedExportContainer(node, isExportName(node)); if (exportContainer && exportContainer.kind === SyntaxKind.SourceFile) { return setTextRange( diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 22c785897f60c..abff30ba8c0d8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1678,10 +1678,7 @@ export interface Identifier extends PrimaryExpression, Declaration, JSDocContain */ readonly escapedText: __String; readonly originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later - /** @internal */ readonly autoGenerateFlags?: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. - /** @internal */ readonly autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. - /** @internal */ readonly autoGeneratePrefix?: string | GeneratedNamePart; - /** @internal */ readonly autoGenerateSuffix?: string; + /** @internal */ readonly autoGenerate: AutoGenerateInfo | undefined; // Used for auto-generated identifiers. /** @internal */ generatedImportReference?: ImportSpecifier; // Reference to the generated import specifier this identifier refers to isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace /** @internal */ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. @@ -1694,9 +1691,17 @@ export interface TransientIdentifier extends Identifier { resolvedSymbol: Symbol; } +/** @internal */ +export interface AutoGenerateInfo { + flags: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. + readonly id: number; // Ensures unique generated identifiers get unique names, but clones get the same name. + readonly prefix?: string | GeneratedNamePart; + readonly suffix?: string; +} + /** @internal */ export interface GeneratedIdentifier extends Identifier { - autoGenerateFlags: GeneratedIdentifierFlags; + readonly autoGenerate: AutoGenerateInfo; } export interface QualifiedName extends Node, FlowContainer { @@ -1774,15 +1779,12 @@ export interface PrivateIdentifier extends PrimaryExpression { // escaping not strictly necessary // avoids gotchas in transforms and utils readonly escapedText: __String; - /** @internal */ readonly autoGenerateFlags?: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. - /** @internal */ readonly autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. - /** @internal */ readonly autoGeneratePrefix?: string | GeneratedNamePart; - /** @internal */ readonly autoGenerateSuffix?: string; + /** @internal */ readonly autoGenerate: AutoGenerateInfo | undefined; // Used for auto-generated identifiers. } /** @internal */ export interface GeneratedPrivateIdentifier extends PrivateIdentifier { - autoGenerateFlags: GeneratedIdentifierFlags; + readonly autoGenerate: AutoGenerateInfo; } /** @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 826f6e663b2ff..61ac9fe18586b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1651,7 +1651,7 @@ export function tryGetTextOfPropertyName(name: PropertyName | NoSubstitutionTemp switch (name.kind) { case SyntaxKind.Identifier: case SyntaxKind.PrivateIdentifier: - return name.autoGenerateFlags ? undefined : name.escapedText; + return name.autoGenerate ? undefined : name.escapedText; case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: case SyntaxKind.NoSubstitutionTemplateLiteral: diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 131af20521b3e..c2f8f7ac9e1ea 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -66,7 +66,6 @@ import { FunctionLikeDeclaration, FunctionTypeNode, GeneratedIdentifier, - GeneratedIdentifierFlags, GeneratedPrivateIdentifier, GetAccessorDeclaration, getAssignmentDeclarationKind, @@ -1476,12 +1475,12 @@ export function isStringTextContainingNode(node: Node): node is StringLiteral | /** @internal */ export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier { - return isIdentifier(node) && (node.autoGenerateFlags! & GeneratedIdentifierFlags.KindMask) > GeneratedIdentifierFlags.None; + return isIdentifier(node) && node.autoGenerate !== undefined; } /** @internal */ export function isGeneratedPrivateIdentifier(node: Node): node is GeneratedPrivateIdentifier { - return isPrivateIdentifier(node) && (node.autoGenerateFlags! & GeneratedIdentifierFlags.KindMask) > GeneratedIdentifierFlags.None; + return isPrivateIdentifier(node) && node.autoGenerate !== undefined; } // Private Identifiers diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index 0946eaa802c83..718d7de802937 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -201,7 +201,7 @@ export function sourceFileToJSON(file: ts.Node): string { case "symbolCount": case "identifierCount": case "scriptSnapshot": - case "autoGenerateFlags": + case "autoGenerate": // Blocklist of items we never put in the baseline file. break; diff --git a/src/services/services.ts b/src/services/services.ts index d227f3dee213f..cac0cda13fd22 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6,6 +6,7 @@ import { ApplicableRefactorInfo, ApplyCodeActionCommandResult, AssignmentDeclarationKind, + AutoGenerateInfo, BaseType, BinaryExpression, BreakpointResolver, @@ -85,7 +86,6 @@ import { FormatCodeSettings, formatting, FunctionLikeDeclaration, - GeneratedIdentifierFlags, getAdjustedRenameLocation, getAllSuperTypeNodes, getAssignmentDeclarationKind, @@ -732,7 +732,7 @@ class TokenObject extends TokenOrIdentifierObject impl class IdentifierObject extends TokenOrIdentifierObject implements Identifier { public kind: SyntaxKind.Identifier = SyntaxKind.Identifier; public escapedText!: __String; - public autoGenerateFlags!: GeneratedIdentifierFlags; + public autoGenerate: AutoGenerateInfo | undefined; declare _primaryExpressionBrand: any; declare _memberExpressionBrand: any; declare _leftHandSideExpressionBrand: any; @@ -755,7 +755,7 @@ IdentifierObject.prototype.kind = SyntaxKind.Identifier; class PrivateIdentifierObject extends TokenOrIdentifierObject implements PrivateIdentifier { public kind: SyntaxKind.PrivateIdentifier = SyntaxKind.PrivateIdentifier; public escapedText!: __String; - // public symbol!: Symbol; + public autoGenerate: AutoGenerateInfo | undefined; declare _primaryExpressionBrand: any; declare _memberExpressionBrand: any; declare _leftHandSideExpressionBrand: any;