diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 6c277479a509c..34fcb235a7042 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -120,7 +120,6 @@ import { HasDecorators, hasInvalidEscape, HasModifiers, - hasProperty, hasSyntacticModifier, HeritageClause, Identifier, @@ -186,7 +185,6 @@ import { isModuleDeclaration, isNamedDeclaration, isNodeArray, - isNodeKind, isNonNullChain, isNotEmittedStatement, isObjectLiteralExpression, @@ -475,7 +473,12 @@ export const enum NodeFactoryFlags { } const nodeFactoryPatchers: ((factory: NodeFactory) => void)[] = []; - +type NodeData = + & Readonly> + & Mutable>> + & { + data: Partial | Exclude>>> | undefined; + }; /** @internal @knipignore */ export function addNodeFactoryPatcher(fn: (factory: NodeFactory) => void) { nodeFactoryPatchers.push(fn); @@ -1205,20 +1208,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } function createBaseNode(kind: T["kind"]) { - return baseFactory.createBaseNode(kind) as Mutable; + return baseFactory.createBaseNode(kind) as any as NodeData; } function createBaseDeclaration(kind: T["kind"]) { const node = createBaseNode(kind); - node.symbol = undefined!; // initialized by binder - node.localSymbol = undefined; // initialized by binder return node; } - function finishUpdateBaseSignatureDeclaration(updated: Mutable, original: T) { + function finishUpdateBaseSignatureDeclaration(updated: T, original: T) { if (updated !== original) { // copy children used for quick info - updated.typeArguments = original.typeArguments; + (updated as unknown as NodeData).data!.typeArguments = original.typeArguments!; } return update(updated, original); } @@ -1232,8 +1233,13 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode const text = typeof value === "number" ? value + "" : value; Debug.assert(text.charCodeAt(0) !== CharacterCodes.minus, "Negative numbers should be created in combination with createPrefixUnaryExpression"); const node = createBaseDeclaration(SyntaxKind.NumericLiteral); - node.text = text; - node.numericLiteralFlags = numericLiteralFlags; + node.data = { + numericLiteralFlags, + hasExtendedUnicodeEscape: false, + isUnterminated: false, + text, + localSymbol: undefined, + }; if (numericLiteralFlags & TokenFlags.BinaryOrOctalSpecifier) node.transformFlags |= TransformFlags.ContainsES2015; return node; } @@ -1241,37 +1247,45 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral { const node = createBaseToken(SyntaxKind.BigIntLiteral); - node.text = typeof value === "string" ? value : pseudoBigIntToString(value) + "n"; + node.data = { + hasExtendedUnicodeEscape: false, + isUnterminated: false, + text: typeof value === "string" ? value : pseudoBigIntToString(value) + "n", + }; node.transformFlags |= TransformFlags.ContainsES2020; return node; } - function createBaseStringLiteral(text: string, isSingleQuote?: boolean) { - const node = createBaseDeclaration(SyntaxKind.StringLiteral); - node.text = text; - node.singleQuote = isSingleQuote; - return node; - } - // @api function createStringLiteral(text: string, isSingleQuote?: boolean, hasExtendedUnicodeEscape?: boolean): StringLiteral { - const node = createBaseStringLiteral(text, isSingleQuote); - node.hasExtendedUnicodeEscape = hasExtendedUnicodeEscape; + const node = createBaseNode(SyntaxKind.StringLiteral); + node.data = { + hasExtendedUnicodeEscape, + singleQuote: isSingleQuote, + // isUnterminated: false, + text, + // textSourceNode: undefined!, + localSymbol: undefined, + }; if (hasExtendedUnicodeEscape) node.transformFlags |= TransformFlags.ContainsES2015; return node; } // @api function createStringLiteralFromNode(sourceNode: PropertyNameLiteral | PrivateIdentifier): StringLiteral { - const node = createBaseStringLiteral(getTextOfIdentifierOrLiteral(sourceNode), /*isSingleQuote*/ undefined); - node.textSourceNode = sourceNode; + const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode), /*isSingleQuote*/ undefined, /*hasExtendedUnicodeEscape*/ undefined) as NodeData; + node.data!.textSourceNode = sourceNode; return node; } // @api function createRegularExpressionLiteral(text: string): RegularExpressionLiteral { const node = createBaseToken(SyntaxKind.RegularExpressionLiteral); - node.text = text; + node.data = { + hasExtendedUnicodeEscape: false, + isUnterminated: false, + text, + }; return node; } @@ -1291,7 +1305,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode case SyntaxKind.RegularExpressionLiteral: return createRegularExpressionLiteral(text); case SyntaxKind.NoSubstitutionTemplateLiteral: - return createTemplateLiteralLikeNode(kind, text, /*rawText*/ undefined, /*templateFlags*/ 0) as NoSubstitutionTemplateLiteral; + return createTemplateLiteralLikeNode(kind, text, /*rawText*/ undefined, /*templateFlags*/ 0) as TemplateLiteralLikeNode as NoSubstitutionTemplateLiteral; } } @@ -1302,14 +1316,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createBaseIdentifier(escapedText: __String) { const node = baseFactory.createBaseIdentifierNode(SyntaxKind.Identifier) as Mutable; node.escapedText = escapedText; - node.jsDoc = 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)) as Mutable; + const node = createBaseIdentifier(escapeLeadingUnderscores(text)) as NodeData; setIdentifierAutoGenerate(node, { flags: autoGenerateFlags, id: nextAutoGenerateId, @@ -1351,7 +1362,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode if (recordTempVariable) { recordTempVariable(name); } - return name; + return name as GeneratedIdentifier; } /** Create a unique temporary variable for use in a loop. */ @@ -1384,7 +1395,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } function createBasePrivateIdentifier(escapedText: __String) { - const node = baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as Mutable; + const node = baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as NodeData; node.escapedText = escapedText; node.transformFlags |= TransformFlags.ContainsClassFields; return node; @@ -1432,7 +1443,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // function createBaseToken(kind: T["kind"]) { - return baseFactory.createBaseTokenNode(kind) as Mutable; + return baseFactory.createBaseTokenNode(kind) as any as NodeData; } // @api @@ -1491,7 +1502,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode break; case SyntaxKind.SuperKeyword: transformFlags = TransformFlags.ContainsES2015 | TransformFlags.ContainsLexicalSuper; - (node as Mutable> as Mutable).flowNode = undefined; // initialized by binder (FlowContainer) + (node as NodeData> as NodeData).flowNode = undefined; // initialized by binder (FlowContainer) break; case SyntaxKind.StaticKeyword: transformFlags = TransformFlags.ContainsES2015; @@ -1502,13 +1513,13 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode case SyntaxKind.ThisKeyword: // 'this' indicates a lexical 'this' transformFlags = TransformFlags.ContainsLexicalThis; - (node as Mutable> as Mutable).flowNode = undefined; // initialized by binder (FlowContainer) + (node as NodeData> as NodeData).flowNode = undefined; // initialized by binder (FlowContainer) break; } if (transformFlags) { node.transformFlags |= transformFlags; } - return node; + return node as Token; } // @@ -1577,10 +1588,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createQualifiedName(left: EntityName, right: string | Identifier) { const node = createBaseNode(SyntaxKind.QualifiedName); - node.left = left; - node.right = asName(right); - node.transformFlags |= propagateChildFlags(node.left) | - propagateIdentifierNameFlags(node.right); + const nodeData = node.data = { + left, + right: asName(right), + }; + node.transformFlags |= propagateChildFlags(nodeData.left) | + propagateIdentifierNameFlags(nodeData.right); node.flowNode = undefined; // initialized by binder (FlowContainer) return node; @@ -1597,7 +1610,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createComputedPropertyName(expression: Expression) { const node = createBaseNode(SyntaxKind.ComputedPropertyName); - node.expression = parenthesizerRules().parenthesizeExpressionOfComputedPropertyName(expression); + node.data = { + expression: parenthesizerRules().parenthesizeExpressionOfComputedPropertyName(expression), + }; node.transformFlags |= propagateChildFlags(node.expression) | TransformFlags.ContainsES2015 | TransformFlags.ContainsComputedPropertyName; @@ -1618,14 +1633,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTypeParameterDeclaration(modifiers: readonly Modifier[] | undefined, name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration { const node = createBaseDeclaration(SyntaxKind.TypeParameter); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.constraint = constraint; - node.default = defaultType; + node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + constraint, + default: defaultType, + expression: undefined, // initialized by parser to report grammar errors + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - - node.expression = undefined; // initialized by parser to report grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -1649,28 +1666,31 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode initializer?: Expression, ) { const node = createBaseDeclaration(SyntaxKind.Parameter); - node.modifiers = asNodeArray(modifiers); - node.dotDotDotToken = dotDotDotToken; - node.name = asName(name); - node.questionToken = questionToken; - node.type = type; - node.initializer = asInitializer(initializer); - - if (isThisIdentifier(node.name)) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + dotDotDotToken, + name: asName(name), + questionToken, + type, + initializer: asInitializer(initializer), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + if (isThisIdentifier(nodeData.name)) { node.transformFlags = TransformFlags.ContainsTypeScript; } else { - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateChildFlags(node.dotDotDotToken) | - propagateNameFlags(node.name) | - propagateChildFlags(node.questionToken) | - propagateChildFlags(node.initializer) | - (node.questionToken ?? node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | - (node.dotDotDotToken ?? node.initializer ? TransformFlags.ContainsES2015 : TransformFlags.None) | - (modifiersToFlags(node.modifiers) & ModifierFlags.ParameterPropertyModifier ? TransformFlags.ContainsTypeScriptClassSyntax : TransformFlags.None); + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateChildFlags(nodeData.dotDotDotToken) | + propagateNameFlags(nodeData.name) | + propagateChildFlags(nodeData.questionToken) | + propagateChildFlags(nodeData.initializer) | + (nodeData.questionToken ?? nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | + (nodeData.dotDotDotToken ?? nodeData.initializer ? TransformFlags.ContainsES2015 : TransformFlags.None) | + (modifiersToFlags(nodeData.modifiers) & ModifierFlags.ParameterPropertyModifier ? TransformFlags.ContainsTypeScriptClassSyntax : TransformFlags.None); } - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -1697,7 +1717,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createDecorator(expression: Expression) { const node = createBaseNode(SyntaxKind.Decorator); - node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); + node.data = { + expression: parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false), + }; node.transformFlags |= propagateChildFlags(node.expression) | TransformFlags.ContainsTypeScript | TransformFlags.ContainsTypeScriptClassSyntax | @@ -1722,16 +1744,19 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, - ): PropertySignature { + ) { const node = createBaseDeclaration(SyntaxKind.PropertySignature); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.type = type; - node.questionToken = questionToken; + node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + type, + questionToken, + initializer: undefined, // initialized by parser to report grammar errors + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - node.initializer = undefined; // initialized by parser to report grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -1751,10 +1776,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdatePropertySignature(updated: Mutable, original: PropertySignature) { + function finishUpdatePropertySignature(updated: NodeData, original: PropertySignature) { if (updated !== original) { // copy children used only for error reporting - updated.initializer = original.initializer; + updated.data!.initializer = original.initializer; } return update(updated, original); } @@ -1768,23 +1793,25 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode initializer: Expression | undefined, ) { const node = createBaseDeclaration(SyntaxKind.PropertyDeclaration); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.questionToken = questionOrExclamationToken && isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; - node.exclamationToken = questionOrExclamationToken && isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; - node.type = type; - node.initializer = asInitializer(initializer); - - const isAmbient = node.flags & NodeFlags.Ambient || modifiersToFlags(node.modifiers) & ModifierFlags.Ambient; - - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateNameFlags(node.name) | - propagateChildFlags(node.initializer) | - (isAmbient || node.questionToken || node.exclamationToken || node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | - (isComputedPropertyName(node.name) || modifiersToFlags(node.modifiers) & ModifierFlags.Static && node.initializer ? TransformFlags.ContainsTypeScriptClassSyntax : TransformFlags.None) | + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + questionToken: questionOrExclamationToken && isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined, + exclamationToken: questionOrExclamationToken && isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined, + type, + initializer: asInitializer(initializer), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + const isAmbient = node.flags & NodeFlags.Ambient || modifiersToFlags(nodeData.modifiers) & ModifierFlags.Ambient; + + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateNameFlags(nodeData.name) | + propagateChildFlags(nodeData.initializer) | + (isAmbient || nodeData.questionToken || nodeData.exclamationToken || nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | + (isComputedPropertyName(nodeData.name) || modifiersToFlags(nodeData.modifiers) & ModifierFlags.Static && nodeData.initializer ? TransformFlags.ContainsTypeScriptClassSyntax : TransformFlags.None) | TransformFlags.ContainsClassFields; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -1817,18 +1844,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode type: TypeNode | undefined, ) { const node = createBaseDeclaration(SyntaxKind.MethodSignature); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.questionToken = questionToken; - node.typeParameters = asNodeArray(typeParameters); - node.parameters = asNodeArray(parameters); - node.type = type; + node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + questionToken, + typeParameters: asNodeArray(typeParameters), + parameters: asNodeArray(parameters), + type, + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + typeArguments: undefined, // used in quick info + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.typeArguments = undefined; // used in quick info return node; } @@ -1864,47 +1893,49 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode body: Block | undefined, ) { const node = createBaseDeclaration(SyntaxKind.MethodDeclaration); - node.modifiers = asNodeArray(modifiers); - node.asteriskToken = asteriskToken; - node.name = asName(name); - node.questionToken = questionToken; - node.exclamationToken = undefined; // initialized by parser for grammar errors - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - - if (!node.body) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + asteriskToken, + name: asName(name), + questionToken, + exclamationToken: undefined, // initialized by parser for grammar errors + typeParameters: asNodeArray(typeParameters), + parameters: createNodeArray(parameters), + type, + body, + typeArguments: undefined, // used in quick inf, + locals: undefined, // initialized by binder (LocalsContainer, + nextContainer: undefined, // initialized by binder (LocalsContainer) + endFlowNode: undefined, + returnFlowNode: undefined, + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + if (!nodeData.body) { node.transformFlags = TransformFlags.ContainsTypeScript; } else { - const isAsync = modifiersToFlags(node.modifiers) & ModifierFlags.Async; - const isGenerator = !!node.asteriskToken; + const isAsync = modifiersToFlags(nodeData.modifiers) & ModifierFlags.Async; + const isGenerator = !!nodeData.asteriskToken; const isAsyncGenerator = isAsync && isGenerator; - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateChildFlags(node.asteriskToken) | - propagateNameFlags(node.name) | - propagateChildFlags(node.questionToken) | - propagateChildrenFlags(node.typeParameters) | - propagateChildrenFlags(node.parameters) | - propagateChildFlags(node.type) | - (propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateChildFlags(nodeData.asteriskToken) | + propagateNameFlags(nodeData.name) | + propagateChildFlags(nodeData.questionToken) | + propagateChildrenFlags(nodeData.typeParameters) | + propagateChildrenFlags(nodeData.parameters) | + propagateChildFlags(nodeData.type) | + (propagateChildFlags(nodeData.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | (isAsyncGenerator ? TransformFlags.ContainsES2018 : isAsync ? TransformFlags.ContainsES2017 : isGenerator ? TransformFlags.ContainsGenerator : TransformFlags.None) | - (node.questionToken || node.typeParameters || node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | + (nodeData.questionToken || nodeData.typeParameters || nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | TransformFlags.ContainsES2015; } - node.typeArguments = undefined; // used in quick info - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) - node.endFlowNode = undefined; - node.returnFlowNode = undefined; return node; } @@ -1932,10 +1963,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateMethodDeclaration(updated: Mutable, original: MethodDeclaration) { + function finishUpdateMethodDeclaration(updated: NodeData, original: MethodDeclaration) { if (updated !== original) { // copy children used only for error reporting - updated.exclamationToken = original.exclamationToken; + updated.data!.exclamationToken = original.exclamationToken; } return update(updated, original); } @@ -1943,17 +1974,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createClassStaticBlockDeclaration( body: Block, - ): ClassStaticBlockDeclaration { + ) { const node = createBaseDeclaration(SyntaxKind.ClassStaticBlockDeclaration); - node.body = body; + node.data = { + body, + modifiers: undefined, // initialized by parser for grammar errors + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + endFlowNode: undefined, + returnFlowNode: undefined, + name: undefined, + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = propagateChildFlags(body) | TransformFlags.ContainsClassFields; - - node.modifiers = undefined; // initialized by parser for grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.endFlowNode = undefined; - node.returnFlowNode = undefined; return node; } @@ -1967,10 +2001,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateClassStaticBlockDeclaration(updated: Mutable, original: ClassStaticBlockDeclaration) { + function finishUpdateClassStaticBlockDeclaration(updated: NodeData, original: ClassStaticBlockDeclaration) { if (updated !== original) { // copy children used only for error reporting - updated.modifiers = original.modifiers; + updated.data!.modifiers = original.modifiers; } return update(updated, original); } @@ -1982,23 +2016,30 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode body: Block | undefined, ) { const node = createBaseDeclaration(SyntaxKind.Constructor); - node.modifiers = asNodeArray(modifiers); - node.parameters = createNodeArray(parameters); - node.body = body; - - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateChildrenFlags(node.parameters) | - (propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + parameters: createNodeArray(parameters), + body, + typeParameters: undefined, // initialized by parser for grammar errors + type: undefined, // initialized by parser for grammar errors + typeArguments: undefined, // used in quick info + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + endFlowNode: undefined, + returnFlowNode: undefined, + localSymbol: undefined, + // asteriskToken: undefined, + // exclamationToken: undefined, + // name: undefined, + // questionToken: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateChildrenFlags(nodeData.parameters) | + (propagateChildFlags(nodeData.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | TransformFlags.ContainsES2015; - node.typeParameters = undefined; // initialized by parser for grammar errors - node.type = undefined; // initialized by parser for grammar errors - node.typeArguments = undefined; // used in quick info - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.endFlowNode = undefined; - node.returnFlowNode = undefined; return node; } @@ -2016,10 +2057,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateConstructorDeclaration(updated: Mutable, original: ConstructorDeclaration) { + function finishUpdateConstructorDeclaration(updated: NodeData, original: ConstructorDeclaration) { if (updated !== original) { - updated.typeParameters = original.typeParameters; - updated.type = original.type; + updated.data!.typeParameters = original.typeParameters; + updated.data!.type = original.type; } return finishUpdateBaseSignatureDeclaration(updated, original); } @@ -2033,32 +2074,38 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode body: Block | undefined, ) { const node = createBaseDeclaration(SyntaxKind.GetAccessor); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - - if (!node.body) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + parameters: createNodeArray(parameters), + type, + body, + typeArguments: undefined, // used in quick info, + typeParameters: undefined, // initialized by parser for grammar errors, + locals: undefined, // initialized by binder (LocalsContainer), + nextContainer: undefined, // initialized by binder (LocalsContainer), + endFlowNode: undefined, + returnFlowNode: undefined, + // asteriskToken: undefined, + // exclamationToken: undefined, + localSymbol: undefined, + // questionToken: undefined + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + + if (!nodeData.body) { node.transformFlags = TransformFlags.ContainsTypeScript; } else { - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateNameFlags(node.name) | - propagateChildrenFlags(node.parameters) | - propagateChildFlags(node.type) | - (propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | - (node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None); + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateNameFlags(nodeData.name) | + propagateChildrenFlags(nodeData.parameters) | + propagateChildFlags(nodeData.type) | + (propagateChildFlags(nodeData.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | + (nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None); } - node.typeArguments = undefined; // used in quick info - node.typeParameters = undefined; // initialized by parser for grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) - node.endFlowNode = undefined; - node.returnFlowNode = undefined; return node; } @@ -2080,10 +2127,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateGetAccessorDeclaration(updated: Mutable, original: GetAccessorDeclaration) { + function finishUpdateGetAccessorDeclaration(updated: NodeData, original: GetAccessorDeclaration) { if (updated !== original) { // copy children used only for error reporting - updated.typeParameters = original.typeParameters; + updated.data!.typeParameters = original.typeParameters; } return finishUpdateBaseSignatureDeclaration(updated, original); } @@ -2096,31 +2143,37 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode body: Block | undefined, ) { const node = createBaseDeclaration(SyntaxKind.SetAccessor); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.parameters = createNodeArray(parameters); - node.body = body; - - if (!node.body) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + parameters: createNodeArray(parameters), + body, + typeArguments: undefined, // used in quick info + typeParameters: undefined, // initialized by parser for grammar errors + type: undefined, // initialized by parser for grammar errors + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + endFlowNode: undefined, + returnFlowNode: undefined, + // asteriskToken: undefined, + // exclamationToken: undefined, + localSymbol: undefined, + // questionToken: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + if (!nodeData.body) { node.transformFlags = TransformFlags.ContainsTypeScript; } else { - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateNameFlags(node.name) | - propagateChildrenFlags(node.parameters) | - (propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | - (node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None); + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateNameFlags(nodeData.name) | + propagateChildrenFlags(nodeData.parameters) | + (propagateChildFlags(nodeData.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | + (nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None); } - node.typeArguments = undefined; // used in quick info - node.typeParameters = undefined; // initialized by parser for grammar errors - node.type = undefined; // initialized by parser for grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) - node.endFlowNode = undefined; - node.returnFlowNode = undefined; return node; } @@ -2140,11 +2193,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateSetAccessorDeclaration(updated: Mutable, original: SetAccessorDeclaration) { + function finishUpdateSetAccessorDeclaration(updated: NodeData, original: SetAccessorDeclaration) { if (updated !== original) { // copy children used only for error reporting - updated.typeParameters = original.typeParameters; - updated.type = original.type; + updated.data!.typeParameters = original.typeParameters; + updated.data!.type = original.type; } return finishUpdateBaseSignatureDeclaration(updated, original); } @@ -2156,15 +2209,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode type: TypeNode | undefined, ): CallSignatureDeclaration { const node = createBaseDeclaration(SyntaxKind.CallSignature); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = asNodeArray(parameters); - node.type = type; + node.data = { + typeParameters: asNodeArray(typeParameters), + parameters: asNodeArray(parameters), + type, + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + typeArguments: undefined, // used in quick info + localSymbol: undefined, + // name: undefined, + // questionToken: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.typeArguments = undefined; // used in quick info return node; } @@ -2189,15 +2247,19 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode type: TypeNode | undefined, ): ConstructSignatureDeclaration { const node = createBaseDeclaration(SyntaxKind.ConstructSignature); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = asNodeArray(parameters); - node.type = type; + node.data = { + typeParameters: asNodeArray(typeParameters), + parameters: asNodeArray(parameters), + type, + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + typeArguments: undefined, // used in quick info + localSymbol: undefined, + // name: undefined, + // questionToken: undefined + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.typeArguments = undefined; // used in quick info return node; } @@ -2222,15 +2284,21 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode type: TypeNode | undefined, ): IndexSignatureDeclaration { const node = createBaseDeclaration(SyntaxKind.IndexSignature); - node.modifiers = asNodeArray(modifiers); - node.parameters = asNodeArray(parameters); - node.type = type!; // TODO(rbuckton): We mark this as required in IndexSignatureDeclaration, but it looks like the parser allows it to be elided. + node.data = { + modifiers: asNodeArray(modifiers), + parameters: asNodeArray(parameters), + type: type!, // TODO(rbuckton): We mark this as required in IndexSignatureDeclaration, but it looks like the parser allows it to be elided. + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + typeArguments: undefined, // used in quick info + localSymbol: undefined, + // name: undefined, + // questionToken: undefined, + // typeParameters: undefined + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.typeArguments = undefined; // used in quick info return node; } @@ -2251,8 +2319,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle | TemplateTail) { const node = createBaseNode(SyntaxKind.TemplateLiteralTypeSpan); - node.type = type; - node.literal = literal; + node.data = { + type, + literal, + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2277,9 +2347,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { const node = createBaseNode(SyntaxKind.TypePredicate); - node.assertsModifier = assertsModifier; - node.parameterName = asName(parameterName); - node.type = type; + node.data = { + assertsModifier, + parameterName: asName(parameterName), + type, + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2296,8 +2368,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined) { const node = createBaseNode(SyntaxKind.TypeReference); - node.typeName = asName(typeName); - node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(createNodeArray(typeArguments)); + node.data = { + typeName: asName(typeName), + typeArguments: typeArguments && parenthesizerRules().parenthesizeTypeArguments(createNodeArray(typeArguments)), + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2315,18 +2389,23 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode, - ): FunctionTypeNode { + ) { const node = createBaseDeclaration(SyntaxKind.FunctionType); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = asNodeArray(parameters); - node.type = type; + node.data = { + typeParameters: asNodeArray(typeParameters), + parameters: asNodeArray(parameters), + type, + + modifiers: undefined, // initialized by parser for grammar errors + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + typeArguments: undefined, // used in quick info + localSymbol: undefined, + // name: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - node.modifiers = undefined; // initialized by parser for grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.typeArguments = undefined; // used in quick info return node; } @@ -2344,10 +2423,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateFunctionTypeNode(updated: Mutable, original: FunctionTypeNode) { + function finishUpdateFunctionTypeNode(updated: NodeData, original: FunctionTypeNode) { if (updated !== original) { // copy children used only for error reporting - updated.modifiers = original.modifiers; + updated.data!.modifiers = original.modifiers; } return finishUpdateBaseSignatureDeclaration(updated, original); } @@ -2366,16 +2445,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode type: TypeNode, ): ConstructorTypeNode { const node = createBaseDeclaration(SyntaxKind.ConstructorType); - node.modifiers = asNodeArray(modifiers); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = asNodeArray(parameters); - node.type = type; + node.data = { + modifiers: asNodeArray(modifiers), + typeParameters: asNodeArray(typeParameters), + parameters: asNodeArray(parameters), + type, + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + typeArguments: undefined, // used in quick info + localSymbol: undefined, + // name: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.typeArguments = undefined; // used in quick info return node; } @@ -2423,8 +2506,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTypeQueryNode(exprName: EntityName, typeArguments?: readonly TypeNode[]) { const node = createBaseNode(SyntaxKind.TypeQuery); - node.exprName = exprName; - node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); + node.data = { + exprName, + typeArguments: typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments), + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2440,7 +2525,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTypeLiteralNode(members: readonly TypeElement[] | undefined) { const node = createBaseDeclaration(SyntaxKind.TypeLiteral); - node.members = createNodeArray(members); + node.data = { + members: createNodeArray(members), + localSymbol: undefined, + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2455,7 +2543,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createArrayTypeNode(elementType: TypeNode) { const node = createBaseNode(SyntaxKind.ArrayType); - node.elementType = parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(elementType); + node.data = { + elementType: parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(elementType), + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2470,7 +2560,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]) { const node = createBaseNode(SyntaxKind.TupleType); - node.elements = createNodeArray(parenthesizerRules().parenthesizeElementTypesOfTupleType(elements)); + node.data = { + elements: createNodeArray(parenthesizerRules().parenthesizeElementTypesOfTupleType(elements)), + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2485,13 +2577,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNamedTupleMember(dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode) { const node = createBaseDeclaration(SyntaxKind.NamedTupleMember); - node.dotDotDotToken = dotDotDotToken; - node.name = name; - node.questionToken = questionToken; - node.type = type; + node.data = { + dotDotDotToken, + name, + questionToken, + type, + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -2508,7 +2603,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createOptionalTypeNode(type: TypeNode) { const node = createBaseNode(SyntaxKind.OptionalType); - node.type = parenthesizerRules().parenthesizeTypeOfOptionalType(type); + node.data = { + type: parenthesizerRules().parenthesizeTypeOfOptionalType(type), + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2523,7 +2620,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createRestTypeNode(type: TypeNode) { const node = createBaseNode(SyntaxKind.RestType); - node.type = type; + node.data = { type }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2537,7 +2634,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: readonly TypeNode[], parenthesize: (nodes: readonly TypeNode[]) => readonly TypeNode[]) { const node = createBaseNode(kind); - node.types = factory.createNodeArray(parenthesize(types)); + node.data = { + types: factory.createNodeArray(parenthesize(types)), + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2571,14 +2670,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { const node = createBaseNode(SyntaxKind.ConditionalType); - node.checkType = parenthesizerRules().parenthesizeCheckTypeOfConditionalType(checkType); - node.extendsType = parenthesizerRules().parenthesizeExtendsTypeOfConditionalType(extendsType); - node.trueType = trueType; - node.falseType = falseType; + node.data = { + checkType: parenthesizerRules().parenthesizeCheckTypeOfConditionalType(checkType), + extendsType: parenthesizerRules().parenthesizeExtendsTypeOfConditionalType(extendsType), + trueType, + falseType, + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) return node; } @@ -2595,7 +2696,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createInferTypeNode(typeParameter: TypeParameterDeclaration) { const node = createBaseNode(SyntaxKind.InferType); - node.typeParameter = typeParameter; + node.data = { typeParameter }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2610,8 +2711,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]) { const node = createBaseNode(SyntaxKind.TemplateLiteralType); - node.head = head; - node.templateSpans = createNodeArray(templateSpans); + node.data = { + head, + templateSpans: createNodeArray(templateSpans), + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2633,15 +2736,19 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode isTypeOf = false, ): ImportTypeNode { const node = createBaseNode(SyntaxKind.ImportType); - node.argument = argument; - node.attributes = attributes; - if (node.assertions && node.assertions.assertClause && node.attributes) { - (node.assertions as Mutable).assertClause = node.attributes; - } - node.qualifier = qualifier; - node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); - node.isTypeOf = isTypeOf; + node.data = { + argument, + attributes, + qualifier, + typeArguments: typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments), + isTypeOf, + }; node.transformFlags = TransformFlags.ContainsTypeScript; + + // dragomirtitian: Seems unused + // if (nodeData.assertions && nodeData.assertions.assertClause && nodeData.attributes) { + // (nodeData.assertions as NodeData).data.assertClause = nodeData.attributes; + // } return node; } @@ -2666,7 +2773,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createParenthesizedType(type: TypeNode) { const node = createBaseNode(SyntaxKind.ParenthesizedType); - node.type = type; + node.data = { type }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2688,10 +2795,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode { const node = createBaseNode(SyntaxKind.TypeOperator); - node.operator = operator; - node.type = operator === SyntaxKind.ReadonlyKeyword ? - parenthesizerRules().parenthesizeOperandOfReadonlyTypeOperator(type) : - parenthesizerRules().parenthesizeOperandOfTypeOperator(type); + node.data = { + operator, + type: operator === SyntaxKind.ReadonlyKeyword ? + parenthesizerRules().parenthesizeOperandOfReadonlyTypeOperator(type) : + parenthesizerRules().parenthesizeOperandOfTypeOperator(type), + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2706,8 +2815,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) { const node = createBaseNode(SyntaxKind.IndexedAccessType); - node.objectType = parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(objectType); - node.indexType = indexType; + node.data = { + objectType: parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(objectType), + indexType, + }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2723,16 +2834,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: readonly TypeElement[] | undefined): MappedTypeNode { const node = createBaseDeclaration(SyntaxKind.MappedType); - node.readonlyToken = readonlyToken; - node.typeParameter = typeParameter; - node.nameType = nameType; - node.questionToken = questionToken; - node.type = type; - node.members = members && createNodeArray(members); - node.transformFlags = TransformFlags.ContainsTypeScript; - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) + node.data = { + readonlyToken, + typeParameter, + nameType, + questionToken, + type, + members: members && createNodeArray(members), + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + localSymbol: undefined, + }; + node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2751,7 +2866,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createLiteralTypeNode(literal: LiteralTypeNode["literal"]) { const node = createBaseNode(SyntaxKind.LiteralType); - node.literal = literal; + node.data = { literal }; node.transformFlags = TransformFlags.ContainsTypeScript; return node; } @@ -2770,7 +2885,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createObjectBindingPattern(elements: readonly BindingElement[]) { const node = createBaseNode(SyntaxKind.ObjectBindingPattern); - node.elements = createNodeArray(elements); + node.data = { elements: createNodeArray(elements) }; node.transformFlags |= propagateChildrenFlags(node.elements) | TransformFlags.ContainsES2015 | TransformFlags.ContainsBindingPattern; @@ -2791,7 +2906,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createArrayBindingPattern(elements: readonly ArrayBindingElement[]) { const node = createBaseNode(SyntaxKind.ArrayBindingPattern); - node.elements = createNodeArray(elements); + node.data = { elements: createNodeArray(elements) }; node.transformFlags |= propagateChildrenFlags(node.elements) | TransformFlags.ContainsES2015 | TransformFlags.ContainsBindingPattern; @@ -2808,18 +2923,21 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression) { const node = createBaseDeclaration(SyntaxKind.BindingElement); - node.dotDotDotToken = dotDotDotToken; - node.propertyName = asName(propertyName); - node.name = asName(name); - node.initializer = asInitializer(initializer); - node.transformFlags |= propagateChildFlags(node.dotDotDotToken) | - propagateNameFlags(node.propertyName) | - propagateNameFlags(node.name) | - propagateChildFlags(node.initializer) | - (node.dotDotDotToken ? TransformFlags.ContainsRestOrSpread : TransformFlags.None) | + const nodeData = node.data = { + dotDotDotToken, + propertyName: asName(propertyName), + name: asName(name), + initializer: asInitializer(initializer), + localSymbol: undefined, + }; + node.transformFlags |= propagateChildFlags(nodeData.dotDotDotToken) | + propagateNameFlags(nodeData.propertyName) | + propagateNameFlags(nodeData.name) | + propagateChildFlags(nodeData.initializer) | + (nodeData.dotDotDotToken ? TransformFlags.ContainsRestOrSpread : TransformFlags.None) | TransformFlags.ContainsES2015; - node.flowNode = undefined; // initialized by binder (FlowContainer) + // // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -2845,8 +2963,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // a trailing comma. const lastElement = elements && lastOrUndefined(elements); const elementsArray = createNodeArray(elements, lastElement && isOmittedExpression(lastElement) ? true : undefined); - node.elements = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(elementsArray); - node.multiLine = multiLine; + node.data = { + elements: parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(elementsArray), + multiLine, + }; node.transformFlags |= propagateChildrenFlags(node.elements); return node; } @@ -2861,11 +2981,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean) { const node = createBaseDeclaration(SyntaxKind.ObjectLiteralExpression); - node.properties = createNodeArray(properties); - node.multiLine = multiLine; + node.data = { + properties: createNodeArray(properties), + multiLine, + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags |= propagateChildrenFlags(node.properties); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -2878,17 +3001,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createBasePropertyAccessExpression(expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, name: MemberName) { const node = createBaseDeclaration(SyntaxKind.PropertyAccessExpression); - node.expression = expression; - node.questionDotToken = questionDotToken; - node.name = name; - node.transformFlags = propagateChildFlags(node.expression) | - propagateChildFlags(node.questionDotToken) | - (isIdentifier(node.name) ? - propagateIdentifierNameFlags(node.name) : - propagateChildFlags(node.name) | TransformFlags.ContainsPrivateIdentifierInExpression); - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + const nodeData = node.data = { + expression, + questionDotToken, + name, + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags = propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.questionDotToken) | + (isIdentifier(nodeData.name) ? + propagateIdentifierNameFlags(nodeData.name) : + propagateChildFlags(nodeData.name) | TransformFlags.ContainsPrivateIdentifierInExpression); + + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -2925,7 +3051,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ true), questionDotToken, asName(name), - ) as Mutable; + ) as NodeData; node.flags |= NodeFlags.OptionalChain; node.transformFlags |= TransformFlags.ContainsES2020; return node; @@ -2945,15 +3071,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createBaseElementAccessExpression(expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression) { const node = createBaseDeclaration(SyntaxKind.ElementAccessExpression); - node.expression = expression; - node.questionDotToken = questionDotToken; - node.argumentExpression = argumentExpression; - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.questionDotToken) | - propagateChildFlags(node.argumentExpression); + const nodeData = node.data = { + expression, + questionDotToken, + argumentExpression, + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.questionDotToken) | + propagateChildFlags(nodeData.argumentExpression); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -2990,7 +3119,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ true), questionDotToken, asExpression(index), - ) as Mutable; + ) as NodeData; node.flags |= NodeFlags.OptionalChain; node.transformFlags |= TransformFlags.ContainsES2020; return node; @@ -3010,18 +3139,22 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createBaseCallExpression(expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, typeArguments: NodeArray | undefined, argumentsArray: NodeArray) { const node = createBaseDeclaration(SyntaxKind.CallExpression); - node.expression = expression; - node.questionDotToken = questionDotToken; - node.typeArguments = typeArguments; - node.arguments = argumentsArray; - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.questionDotToken) | - propagateChildrenFlags(node.typeArguments) | - propagateChildrenFlags(node.arguments); - if (node.typeArguments) { + const nodeData = node.data = { + expression, + questionDotToken, + typeArguments, + arguments: argumentsArray, + localSymbol: undefined, + }; + + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.questionDotToken) | + propagateChildrenFlags(nodeData.typeArguments) | + propagateChildrenFlags(nodeData.arguments); + if (nodeData.typeArguments) { node.transformFlags |= TransformFlags.ContainsTypeScript; } - if (isSuperProperty(node.expression)) { + if (isSuperProperty(nodeData.expression)) { node.transformFlags |= TransformFlags.ContainsLexicalThis; } return node; @@ -3060,7 +3193,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode questionDotToken, asNodeArray(typeArguments), parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(createNodeArray(argumentsArray)), - ) as Mutable; + ) as NodeData; node.flags |= NodeFlags.OptionalChain; node.transformFlags |= TransformFlags.ContainsES2020; return node; @@ -3080,14 +3213,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNewExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { const node = createBaseDeclaration(SyntaxKind.NewExpression); - node.expression = parenthesizerRules().parenthesizeExpressionOfNew(expression); - node.typeArguments = asNodeArray(typeArguments); - node.arguments = argumentsArray ? parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(argumentsArray) : undefined; - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildrenFlags(node.typeArguments) | - propagateChildrenFlags(node.arguments) | + const nodeData = node.data = { + expression: parenthesizerRules().parenthesizeExpressionOfNew(expression), + typeArguments: asNodeArray(typeArguments), + arguments: argumentsArray ? parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(argumentsArray) : undefined, + localSymbol: undefined, + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildrenFlags(nodeData.typeArguments) | + propagateChildrenFlags(nodeData.arguments) | TransformFlags.ContainsES2020; - if (node.typeArguments) { + if (nodeData.typeArguments) { node.transformFlags |= TransformFlags.ContainsTypeScript; } return node; @@ -3105,17 +3241,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTaggedTemplateExpression(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral) { const node = createBaseNode(SyntaxKind.TaggedTemplateExpression); - node.tag = parenthesizerRules().parenthesizeLeftSideOfAccess(tag, /*optionalChain*/ false); - node.typeArguments = asNodeArray(typeArguments); - node.template = template; - node.transformFlags |= propagateChildFlags(node.tag) | - propagateChildrenFlags(node.typeArguments) | - propagateChildFlags(node.template) | + const nodeData = node.data = { + tag: parenthesizerRules().parenthesizeLeftSideOfAccess(tag, /*optionalChain*/ false), + typeArguments: asNodeArray(typeArguments), + template, + // questionDotToken: undefined, + }; + node.transformFlags |= propagateChildFlags(nodeData.tag) | + propagateChildrenFlags(nodeData.typeArguments) | + propagateChildFlags(nodeData.template) | TransformFlags.ContainsES2015; - if (node.typeArguments) { + if (nodeData.typeArguments) { node.transformFlags |= TransformFlags.ContainsTypeScript; } - if (hasInvalidEscape(node.template)) { + if (hasInvalidEscape(nodeData.template)) { node.transformFlags |= TransformFlags.ContainsES2018; } return node; @@ -3133,8 +3272,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTypeAssertion(type: TypeNode, expression: Expression) { const node = createBaseNode(SyntaxKind.TypeAssertionExpression); - node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); - node.type = type; + node.data = { + expression: parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression), + type, + }; node.transformFlags |= propagateChildFlags(node.expression) | propagateChildFlags(node.type) | TransformFlags.ContainsTypeScript; @@ -3152,10 +3293,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createParenthesizedExpression(expression: Expression) { const node = createBaseNode(SyntaxKind.ParenthesizedExpression); - node.expression = expression; + node.data = { + expression, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = propagateChildFlags(node.expression); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -3177,39 +3320,46 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode body: Block, ) { const node = createBaseDeclaration(SyntaxKind.FunctionExpression); - node.modifiers = asNodeArray(modifiers); - node.asteriskToken = asteriskToken; - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - - const isAsync = modifiersToFlags(node.modifiers) & ModifierFlags.Async; - const isGenerator = !!node.asteriskToken; + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + asteriskToken, + name: asName(name), + typeParameters: asNodeArray(typeParameters), + parameters: createNodeArray(parameters), + type, + body, + + typeArguments: undefined, // used in quick info + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + endFlowNode: undefined, + returnFlowNode: undefined, + // exclamationToken: undefined, + localSymbol: undefined, + // questionToken: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + // // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + + const isAsync = modifiersToFlags(nodeData.modifiers) & ModifierFlags.Async; + const isGenerator = !!nodeData.asteriskToken; const isAsyncGenerator = isAsync && isGenerator; - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateChildFlags(node.asteriskToken) | - propagateNameFlags(node.name) | - propagateChildrenFlags(node.typeParameters) | - propagateChildrenFlags(node.parameters) | - propagateChildFlags(node.type) | - (propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateChildFlags(nodeData.asteriskToken) | + propagateNameFlags(nodeData.name) | + propagateChildrenFlags(nodeData.typeParameters) | + propagateChildrenFlags(nodeData.parameters) | + propagateChildFlags(nodeData.type) | + (propagateChildFlags(nodeData.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | (isAsyncGenerator ? TransformFlags.ContainsES2018 : isAsync ? TransformFlags.ContainsES2017 : isGenerator ? TransformFlags.ContainsGenerator : TransformFlags.None) | - (node.typeParameters || node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | + (nodeData.typeParameters || nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | TransformFlags.ContainsHoistedDeclarationOrCompletion; - node.typeArguments = undefined; // used in quick info - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) - node.endFlowNode = undefined; - node.returnFlowNode = undefined; return node; } @@ -3245,32 +3395,40 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode body: ConciseBody, ) { const node = createBaseDeclaration(SyntaxKind.ArrowFunction); - node.modifiers = asNodeArray(modifiers); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; - node.equalsGreaterThanToken = equalsGreaterThanToken ?? createToken(SyntaxKind.EqualsGreaterThanToken); - node.body = parenthesizerRules().parenthesizeConciseBodyOfArrowFunction(body); - - const isAsync = modifiersToFlags(node.modifiers) & ModifierFlags.Async; - - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateChildrenFlags(node.typeParameters) | - propagateChildrenFlags(node.parameters) | - propagateChildFlags(node.type) | - propagateChildFlags(node.equalsGreaterThanToken) | - (propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | - (node.typeParameters || node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + typeParameters: asNodeArray(typeParameters), + parameters: createNodeArray(parameters), + type, + equalsGreaterThanToken: equalsGreaterThanToken ?? createToken(SyntaxKind.EqualsGreaterThanToken), + body: parenthesizerRules().parenthesizeConciseBodyOfArrowFunction(body), + + typeArguments: undefined, // used in quick info + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + endFlowNode: undefined, + returnFlowNode: undefined, + // asteriskToken: undefined, + // exclamationToken: undefined, + localSymbol: undefined, + // name: undefined, + // questionToken: undefined + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + + const isAsync = modifiersToFlags(nodeData.modifiers) & ModifierFlags.Async; + + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateChildrenFlags(nodeData.typeParameters) | + propagateChildrenFlags(nodeData.parameters) | + propagateChildFlags(nodeData.type) | + propagateChildFlags(nodeData.equalsGreaterThanToken) | + (propagateChildFlags(nodeData.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | + (nodeData.typeParameters || nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | (isAsync ? TransformFlags.ContainsES2017 | TransformFlags.ContainsLexicalThis : TransformFlags.None) | TransformFlags.ContainsES2015; - node.typeArguments = undefined; // used in quick info - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) - node.endFlowNode = undefined; - node.returnFlowNode = undefined; return node; } @@ -3297,7 +3455,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createDeleteExpression(expression: Expression) { const node = createBaseNode(SyntaxKind.DeleteExpression); - node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.data = { expression: parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression) }; node.transformFlags |= propagateChildFlags(node.expression); return node; } @@ -3312,7 +3470,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTypeOfExpression(expression: Expression) { const node = createBaseNode(SyntaxKind.TypeOfExpression); - node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.data = { expression: parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression) }; node.transformFlags |= propagateChildFlags(node.expression); return node; } @@ -3327,7 +3485,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createVoidExpression(expression: Expression) { const node = createBaseNode(SyntaxKind.VoidExpression); - node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.data = { expression: parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression) }; node.transformFlags |= propagateChildFlags(node.expression); return node; } @@ -3342,7 +3500,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createAwaitExpression(expression: Expression) { const node = createBaseNode(SyntaxKind.AwaitExpression); - node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.data = { expression: parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression) }; node.transformFlags |= propagateChildFlags(node.expression) | TransformFlags.ContainsES2017 | TransformFlags.ContainsES2018 | @@ -3360,8 +3518,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createPrefixUnaryExpression(operator: PrefixUnaryOperator, operand: Expression) { const node = createBaseNode(SyntaxKind.PrefixUnaryExpression); - node.operator = operator; - node.operand = parenthesizerRules().parenthesizeOperandOfPrefixUnary(operand); + node.data = { + operator, + operand: parenthesizerRules().parenthesizeOperandOfPrefixUnary(operand), + }; node.transformFlags |= propagateChildFlags(node.operand); // Only set this flag for non-generated identifiers and non-"local" names. See the // comment in `visitPreOrPostfixUnaryExpression` in module.ts @@ -3386,8 +3546,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createPostfixUnaryExpression(operand: Expression, operator: PostfixUnaryOperator) { const node = createBaseNode(SyntaxKind.PostfixUnaryExpression); - node.operator = operator; - node.operand = parenthesizerRules().parenthesizeOperandOfPostfixUnary(operand); + node.data = { + operator, + operand: parenthesizerRules().parenthesizeOperandOfPostfixUnary(operand), + }; node.transformFlags |= propagateChildFlags(node.operand); // Only set this flag for non-generated identifiers and non-"local" names. See the // comment in `visitPreOrPostfixUnaryExpression` in module.ts @@ -3409,13 +3571,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression) { + function createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression { const node = createBaseDeclaration(SyntaxKind.BinaryExpression); const operatorToken = asToken(operator); const operatorKind = operatorToken.kind; - node.left = parenthesizerRules().parenthesizeLeftSideOfBinary(operatorKind, left); - node.operatorToken = operatorToken; - node.right = parenthesizerRules().parenthesizeRightSideOfBinary(operatorKind, node.left, right); + node.data = { + left: parenthesizerRules().parenthesizeLeftSideOfBinary(operatorKind, left), + operatorToken, + right: parenthesizerRules().parenthesizeRightSideOfBinary(operatorKind, node.left, right), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags |= propagateChildFlags(node.left) | propagateChildFlags(node.operatorToken) | propagateChildFlags(node.right); @@ -3445,7 +3611,6 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode node.transformFlags |= TransformFlags.ContainsPrivateIdentifierInExpression; } - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -3465,16 +3630,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createConditionalExpression(condition: Expression, questionToken: QuestionToken | undefined, whenTrue: Expression, colonToken: ColonToken | undefined, whenFalse: Expression) { const node = createBaseNode(SyntaxKind.ConditionalExpression); - node.condition = parenthesizerRules().parenthesizeConditionOfConditionalExpression(condition); - node.questionToken = questionToken ?? createToken(SyntaxKind.QuestionToken); - node.whenTrue = parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenTrue); - node.colonToken = colonToken ?? createToken(SyntaxKind.ColonToken); - node.whenFalse = parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenFalse); - node.transformFlags |= propagateChildFlags(node.condition) | - propagateChildFlags(node.questionToken) | - propagateChildFlags(node.whenTrue) | - propagateChildFlags(node.colonToken) | - propagateChildFlags(node.whenFalse); + const nodeData = node.data = { + condition: parenthesizerRules().parenthesizeConditionOfConditionalExpression(condition), + questionToken: questionToken ?? createToken(SyntaxKind.QuestionToken), + whenTrue: parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenTrue), + colonToken: colonToken ?? createToken(SyntaxKind.ColonToken), + whenFalse: parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenFalse), + }; + node.transformFlags |= propagateChildFlags(nodeData.condition) | + propagateChildFlags(nodeData.questionToken) | + propagateChildFlags(nodeData.whenTrue) | + propagateChildFlags(nodeData.colonToken) | + propagateChildFlags(nodeData.whenFalse); return node; } @@ -3499,8 +3666,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]) { const node = createBaseNode(SyntaxKind.TemplateExpression); - node.head = head; - node.templateSpans = createNodeArray(templateSpans); + node.data = { + head, + templateSpans: createNodeArray(templateSpans), + }; node.transformFlags |= propagateChildFlags(node.head) | propagateChildrenFlags(node.templateSpans) | TransformFlags.ContainsES2015; @@ -3551,19 +3720,27 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // functions are intentionally duplicated. function createTemplateLiteralLikeToken(kind: TemplateLiteralToken["kind"], text: string, rawText: string | undefined, templateFlags: TokenFlags | undefined) { const node = createBaseToken(kind); - node.text = text; - node.rawText = rawText; - node.templateFlags = templateFlags! & TokenFlags.TemplateLiteralLikeFlags; - node.transformFlags = getTransformFlagsOfTemplateLiteralLike(node.templateFlags); + const nodeData = node.data = { + // hasExtendedUnicodeEscape: false, + // isUnterminated: false, + text, + rawText, + templateFlags: templateFlags! & TokenFlags.TemplateLiteralLikeFlags, + }; + node.transformFlags = getTransformFlagsOfTemplateLiteralLike(nodeData.templateFlags); return node; } function createTemplateLiteralLikeDeclaration(kind: SyntaxKind.NoSubstitutionTemplateLiteral, text: string, rawText: string | undefined, templateFlags: TokenFlags | undefined) { const node = createBaseDeclaration(kind); - node.text = text; - node.rawText = rawText; - node.templateFlags = templateFlags! & TokenFlags.TemplateLiteralLikeFlags; - node.transformFlags = getTransformFlagsOfTemplateLiteralLike(node.templateFlags); + const nodeData = node.data = { + // hasExtendedUnicodeEscape: false, + // isUnterminated: false, + text, + rawText, + templateFlags: templateFlags! & TokenFlags.TemplateLiteralLikeFlags, + }; + node.transformFlags = getTransformFlagsOfTemplateLiteralLike(nodeData.templateFlags); return node; } @@ -3578,19 +3755,19 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTemplateHead(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { text = checkTemplateLiteralLikeNode(SyntaxKind.TemplateHead, text, rawText, templateFlags); - return createTemplateLiteralLikeNode(SyntaxKind.TemplateHead, text, rawText, templateFlags) as TemplateHead; + return createTemplateLiteralLikeNode(SyntaxKind.TemplateHead, text, rawText, templateFlags) as TemplateLiteralLikeNode as TemplateHead; } // @api function createTemplateMiddle(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { text = checkTemplateLiteralLikeNode(SyntaxKind.TemplateHead, text, rawText, templateFlags); - return createTemplateLiteralLikeNode(SyntaxKind.TemplateMiddle, text, rawText, templateFlags) as TemplateMiddle; + return createTemplateLiteralLikeNode(SyntaxKind.TemplateMiddle, text, rawText, templateFlags) as TemplateLiteralLikeNode as TemplateMiddle; } // @api function createTemplateTail(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { text = checkTemplateLiteralLikeNode(SyntaxKind.TemplateHead, text, rawText, templateFlags); - return createTemplateLiteralLikeNode(SyntaxKind.TemplateTail, text, rawText, templateFlags) as TemplateTail; + return createTemplateLiteralLikeNode(SyntaxKind.TemplateTail, text, rawText, templateFlags) as TemplateLiteralLikeNode as TemplateTail; } // @api @@ -3603,10 +3780,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createYieldExpression(asteriskToken: AsteriskToken | undefined, expression: Expression | undefined): YieldExpression { Debug.assert(!asteriskToken || !!expression, "A `YieldExpression` with an asteriskToken must have an expression."); const node = createBaseNode(SyntaxKind.YieldExpression); - node.expression = expression && parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); - node.asteriskToken = asteriskToken; - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.asteriskToken) | + const nodeData = node.data = { + expression: expression && parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression), + asteriskToken, + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.asteriskToken) | TransformFlags.ContainsES2015 | TransformFlags.ContainsES2018 | TransformFlags.ContainsYield; @@ -3624,7 +3803,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createSpreadElement(expression: Expression) { const node = createBaseNode(SyntaxKind.SpreadElement); - node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); + node.data = { expression: parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression) }; node.transformFlags |= propagateChildFlags(node.expression) | TransformFlags.ContainsES2015 | TransformFlags.ContainsRestOrSpread; @@ -3647,20 +3826,23 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode members: readonly ClassElement[], ) { const node = createBaseDeclaration(SyntaxKind.ClassExpression); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.heritageClauses = asNodeArray(heritageClauses); - node.members = createNodeArray(members); - node.transformFlags |= propagateChildrenFlags(node.modifiers) | - propagateNameFlags(node.name) | - propagateChildrenFlags(node.typeParameters) | - propagateChildrenFlags(node.heritageClauses) | - propagateChildrenFlags(node.members) | - (node.typeParameters ? TransformFlags.ContainsTypeScript : TransformFlags.None) | + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + typeParameters: asNodeArray(typeParameters), + heritageClauses: asNodeArray(heritageClauses), + members: createNodeArray(members), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildrenFlags(nodeData.modifiers) | + propagateNameFlags(nodeData.name) | + propagateChildrenFlags(nodeData.typeParameters) | + propagateChildrenFlags(nodeData.heritageClauses) | + propagateChildrenFlags(nodeData.members) | + (nodeData.typeParameters ? TransformFlags.ContainsTypeScript : TransformFlags.None) | TransformFlags.ContainsES2015; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -3690,10 +3872,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createExpressionWithTypeArguments(expression: Expression, typeArguments: readonly TypeNode[] | undefined) { const node = createBaseNode(SyntaxKind.ExpressionWithTypeArguments); - node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); - node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildrenFlags(node.typeArguments) | + const nodeData = node.data = { + expression: parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false), + typeArguments: typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments), + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildrenFlags(nodeData.typeArguments) | TransformFlags.ContainsES2015; return node; } @@ -3709,10 +3893,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createAsExpression(expression: Expression, type: TypeNode) { const node = createBaseNode(SyntaxKind.AsExpression); - node.expression = expression; - node.type = type; - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.type) | + const nodeData = node.data = { + expression, + type, + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.type) | TransformFlags.ContainsTypeScript; return node; } @@ -3728,7 +3914,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNonNullExpression(expression: Expression) { const node = createBaseNode(SyntaxKind.NonNullExpression); - node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); + node.data = { expression: parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false) }; node.transformFlags |= propagateChildFlags(node.expression) | TransformFlags.ContainsTypeScript; return node; @@ -3747,10 +3933,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createSatisfiesExpression(expression: Expression, type: TypeNode) { const node = createBaseNode(SyntaxKind.SatisfiesExpression); - node.expression = expression; - node.type = type; - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.type) | + const nodeData = node.data = { + expression, + type, + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.type) | TransformFlags.ContainsTypeScript; return node; } @@ -3767,7 +3955,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createNonNullChain(expression: Expression) { const node = createBaseNode(SyntaxKind.NonNullExpression); node.flags |= NodeFlags.OptionalChain; - node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ true); + node.data = { expression: parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ true) }; node.transformFlags |= propagateChildFlags(node.expression) | TransformFlags.ContainsTypeScript; return node; @@ -3784,9 +3972,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier) { const node = createBaseNode(SyntaxKind.MetaProperty); - node.keywordToken = keywordToken; - node.name = name; - node.transformFlags |= propagateChildFlags(node.name); + const nodeData = node.data = { + keywordToken, + name, + }; + node.transformFlags |= propagateChildFlags(nodeData.name); switch (keywordToken) { case SyntaxKind.NewKeyword: node.transformFlags |= TransformFlags.ContainsES2015; @@ -3798,7 +3988,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode return Debug.assertNever(keywordToken); } - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -3816,10 +4006,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail) { const node = createBaseNode(SyntaxKind.TemplateSpan); - node.expression = expression; - node.literal = literal; - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.literal) | + const nodeData = node.data = { + expression, + literal, + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.literal) | TransformFlags.ContainsES2015; return node; } @@ -3846,13 +4038,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createBlock(statements: readonly Statement[], multiLine?: boolean): Block { const node = createBaseNode(SyntaxKind.Block); - node.statements = createNodeArray(statements); - node.multiLine = multiLine; - node.transformFlags |= propagateChildrenFlags(node.statements); + const nodeData = node.data = { + statements: createNodeArray(statements), + multiLine, + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) + node.transformFlags |= propagateChildrenFlags(nodeData.statements); return node; } @@ -3866,16 +4061,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createVariableStatement(modifiers: readonly ModifierLike[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]) { const node = createBaseNode(SyntaxKind.VariableStatement); - node.modifiers = asNodeArray(modifiers); - node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; - node.transformFlags |= propagateChildrenFlags(node.modifiers) | - propagateChildFlags(node.declarationList); - if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + declarationList: isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + + node.transformFlags |= propagateChildrenFlags(nodeData.modifiers) | + propagateChildFlags(nodeData.declarationList); + + if (modifiersToFlags(nodeData.modifiers) & ModifierFlags.Ambient) { node.transformFlags = TransformFlags.ContainsTypeScript; } - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -3890,18 +4089,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createEmptyStatement() { const node = createBaseNode(SyntaxKind.EmptyStatement); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) + node.data = { jsDoc: undefined }; // initialized by parser (JsDocContainer) return node; } // @api function createExpressionStatement(expression: Expression): ExpressionStatement { const node = createBaseNode(SyntaxKind.ExpressionStatement); - node.expression = parenthesizerRules().parenthesizeExpressionOfExpressionStatement(expression); - node.transformFlags |= propagateChildFlags(node.expression); + const nodeData = node.data = { + expression: parenthesizerRules().parenthesizeExpressionOfExpressionStatement(expression), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.expression); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -3915,15 +4116,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createIfStatement(expression: Expression, thenStatement: Statement, elseStatement?: Statement) { const node = createBaseNode(SyntaxKind.IfStatement); - node.expression = expression; - node.thenStatement = asEmbeddedStatement(thenStatement); - node.elseStatement = asEmbeddedStatement(elseStatement); - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.thenStatement) | - propagateChildFlags(node.elseStatement); + const nodeData = node.data = { + expression, + thenStatement: asEmbeddedStatement(thenStatement), + elseStatement: asEmbeddedStatement(elseStatement), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.thenStatement) | + propagateChildFlags(nodeData.elseStatement); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -3939,13 +4142,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createDoStatement(statement: Statement, expression: Expression) { const node = createBaseNode(SyntaxKind.DoStatement); - node.statement = asEmbeddedStatement(statement); - node.expression = expression; - node.transformFlags |= propagateChildFlags(node.statement) | - propagateChildFlags(node.expression); + const nodeData = node.data = { + statement: asEmbeddedStatement(statement), + expression, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.statement) | + propagateChildFlags(nodeData.expression); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -3960,13 +4165,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createWhileStatement(expression: Expression, statement: Statement) { const node = createBaseNode(SyntaxKind.WhileStatement); - node.expression = expression; - node.statement = asEmbeddedStatement(statement); - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.statement); + const nodeData = node.data = { + expression, + statement: asEmbeddedStatement(statement), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.statement); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -3981,19 +4188,21 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createForStatement(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { const node = createBaseNode(SyntaxKind.ForStatement); - node.initializer = initializer; - node.condition = condition; - node.incrementor = incrementor; - node.statement = asEmbeddedStatement(statement); - node.transformFlags |= propagateChildFlags(node.initializer) | - propagateChildFlags(node.condition) | - propagateChildFlags(node.incrementor) | - propagateChildFlags(node.statement); - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + const nodeData = node.data = { + initializer, + condition, + incrementor, + statement: asEmbeddedStatement(statement), + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + + node.transformFlags |= propagateChildFlags(nodeData.initializer) | + propagateChildFlags(nodeData.condition) | + propagateChildFlags(nodeData.incrementor) | + propagateChildFlags(nodeData.statement); return node; } @@ -4010,17 +4219,21 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createForInStatement(initializer: ForInitializer, expression: Expression, statement: Statement) { const node = createBaseNode(SyntaxKind.ForInStatement); - node.initializer = initializer; - node.expression = expression; - node.statement = asEmbeddedStatement(statement); - node.transformFlags |= propagateChildFlags(node.initializer) | - propagateChildFlags(node.expression) | - propagateChildFlags(node.statement); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + const nodeData = node.data = { + initializer, + expression, + statement: asEmbeddedStatement(statement), + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + node.transformFlags |= propagateChildFlags(nodeData.initializer) | + propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.statement); + return node; } @@ -4036,21 +4249,25 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createForOfStatement(awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { const node = createBaseNode(SyntaxKind.ForOfStatement); - node.awaitModifier = awaitModifier; - node.initializer = initializer; - node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); - node.statement = asEmbeddedStatement(statement); - node.transformFlags |= propagateChildFlags(node.awaitModifier) | - propagateChildFlags(node.initializer) | - propagateChildFlags(node.expression) | - propagateChildFlags(node.statement) | + const nodeData = node.data = { + awaitModifier, + initializer, + expression: parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression), + statement: asEmbeddedStatement(statement), + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + + node.transformFlags |= propagateChildFlags(nodeData.awaitModifier) | + propagateChildFlags(nodeData.initializer) | + propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.statement) | TransformFlags.ContainsES2015; if (awaitModifier) node.transformFlags |= TransformFlags.ContainsES2018; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -4067,12 +4284,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createContinueStatement(label?: string | Identifier): ContinueStatement { const node = createBaseNode(SyntaxKind.ContinueStatement); - node.label = asName(label); - node.transformFlags |= propagateChildFlags(node.label) | + const nodeData = node.data = { + label: asName(label), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.label) | TransformFlags.ContainsHoistedDeclarationOrCompletion; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -4086,12 +4305,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createBreakStatement(label?: string | Identifier): BreakStatement { const node = createBaseNode(SyntaxKind.BreakStatement); - node.label = asName(label); - node.transformFlags |= propagateChildFlags(node.label) | + const nodeData = node.data = { + label: asName(label), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.label) | TransformFlags.ContainsHoistedDeclarationOrCompletion; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -4105,14 +4326,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createReturnStatement(expression?: Expression): ReturnStatement { const node = createBaseNode(SyntaxKind.ReturnStatement); - node.expression = expression; + const nodeData = node.data = { + expression, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; // return in an ES2018 async generator must be awaited - node.transformFlags |= propagateChildFlags(node.expression) | + node.transformFlags |= propagateChildFlags(nodeData.expression) | TransformFlags.ContainsES2018 | TransformFlags.ContainsHoistedDeclarationOrCompletion; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -4126,13 +4349,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createWithStatement(expression: Expression, statement: Statement) { const node = createBaseNode(SyntaxKind.WithStatement); - node.expression = expression; - node.statement = asEmbeddedStatement(statement); - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.statement); + const nodeData = node.data = { + expression, + statement: asEmbeddedStatement(statement), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.statement); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -4147,14 +4372,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement { const node = createBaseNode(SyntaxKind.SwitchStatement); - node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); - node.caseBlock = caseBlock; - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildFlags(node.caseBlock); + const nodeData = node.data = { + possiblyExhaustive: false, // initialized by binder + expression: parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression), + caseBlock, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildFlags(nodeData.caseBlock); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) - node.possiblyExhaustive = false; // initialized by binder return node; } @@ -4169,13 +4396,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createLabeledStatement(label: string | Identifier, statement: Statement) { const node = createBaseNode(SyntaxKind.LabeledStatement); - node.label = asName(label); - node.statement = asEmbeddedStatement(statement); - node.transformFlags |= propagateChildFlags(node.label) | - propagateChildFlags(node.statement); + const nodeData = node.data = { + label: asName(label), + statement: asEmbeddedStatement(statement), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.label) | + propagateChildFlags(nodeData.statement); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -4190,11 +4419,13 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createThrowStatement(expression: Expression) { const node = createBaseNode(SyntaxKind.ThrowStatement); - node.expression = expression; - node.transformFlags |= propagateChildFlags(node.expression); + const nodeData = node.data = { + expression, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.expression); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -4208,15 +4439,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createTryStatement(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { const node = createBaseNode(SyntaxKind.TryStatement); - node.tryBlock = tryBlock; - node.catchClause = catchClause; - node.finallyBlock = finallyBlock; - node.transformFlags |= propagateChildFlags(node.tryBlock) | - propagateChildFlags(node.catchClause) | - propagateChildFlags(node.finallyBlock); - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) + const nodeData = node.data = { + tryBlock, + catchClause, + finallyBlock, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.tryBlock) | + propagateChildFlags(nodeData.catchClause) | + propagateChildFlags(nodeData.finallyBlock); + + // nodeData.flowNode = undefined; // initialized by binder (FlowContainer) return node; } @@ -4232,24 +4465,24 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createDebuggerStatement() { const node = createBaseNode(SyntaxKind.DebuggerStatement); - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.flowNode = undefined; // initialized by binder (FlowContainer) return node; } // @api function createVariableDeclaration(name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { const node = createBaseDeclaration(SyntaxKind.VariableDeclaration); - node.name = asName(name); - node.exclamationToken = exclamationToken; - node.type = type; - node.initializer = asInitializer(initializer); - node.transformFlags |= propagateNameFlags(node.name) | - propagateChildFlags(node.initializer) | - (node.exclamationToken ?? node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None); + const nodeData = node.data = { + name: asName(name), + exclamationToken, + type, + initializer: asInitializer(initializer), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateNameFlags(nodeData.name) | + propagateChildFlags(nodeData.initializer) | + (nodeData.exclamationToken ?? nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4267,7 +4500,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags = NodeFlags.None) { const node = createBaseNode(SyntaxKind.VariableDeclarationList); node.flags |= flags & NodeFlags.BlockScoped; - node.declarations = createNodeArray(declarations); + node.data = { declarations: createNodeArray(declarations) }; node.transformFlags |= propagateChildrenFlags(node.declarations) | TransformFlags.ContainsHoistedDeclarationOrCompletion; if (flags & NodeFlags.BlockScoped) { @@ -4298,43 +4531,49 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode body: Block | undefined, ) { const node = createBaseDeclaration(SyntaxKind.FunctionDeclaration); - node.modifiers = asNodeArray(modifiers); - node.asteriskToken = asteriskToken; - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - - if (!node.body || modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + asteriskToken, + name: asName(name), + typeParameters: asNodeArray(typeParameters), + parameters: createNodeArray(parameters), + type, + body, + + typeArguments: undefined, // used in quick info + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + endFlowNode: undefined, + returnFlowNode: undefined, + // exclamationToken: undefined, + localSymbol: undefined, + // questionToken: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + if (!nodeData.body || modifiersToFlags(nodeData.modifiers) & ModifierFlags.Ambient) { node.transformFlags = TransformFlags.ContainsTypeScript; } else { - const isAsync = modifiersToFlags(node.modifiers) & ModifierFlags.Async; - const isGenerator = !!node.asteriskToken; + const isAsync = modifiersToFlags(nodeData.modifiers) & ModifierFlags.Async; + const isGenerator = !!nodeData.asteriskToken; const isAsyncGenerator = isAsync && isGenerator; - node.transformFlags = propagateChildrenFlags(node.modifiers) | - propagateChildFlags(node.asteriskToken) | - propagateNameFlags(node.name) | - propagateChildrenFlags(node.typeParameters) | - propagateChildrenFlags(node.parameters) | - propagateChildFlags(node.type) | - (propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | + node.transformFlags = propagateChildrenFlags(nodeData.modifiers) | + propagateChildFlags(nodeData.asteriskToken) | + propagateNameFlags(nodeData.name) | + propagateChildrenFlags(nodeData.typeParameters) | + propagateChildrenFlags(nodeData.parameters) | + propagateChildFlags(nodeData.type) | + (propagateChildFlags(nodeData.body) & ~TransformFlags.ContainsPossibleTopLevelAwait) | (isAsyncGenerator ? TransformFlags.ContainsES2018 : isAsync ? TransformFlags.ContainsES2017 : isGenerator ? TransformFlags.ContainsGenerator : TransformFlags.None) | - (node.typeParameters || node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | + (nodeData.typeParameters || nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None) | TransformFlags.ContainsHoistedDeclarationOrCompletion; } - node.typeArguments = undefined; // used in quick info - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.endFlowNode = undefined; - node.returnFlowNode = undefined; return node; } @@ -4360,11 +4599,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateFunctionDeclaration(updated: Mutable, original: FunctionDeclaration) { + function finishUpdateFunctionDeclaration(updated: NodeData, original: FunctionDeclaration) { if (updated !== original) { // copy children used only for error reporting if (updated.modifiers === original.modifiers) { - updated.modifiers = original.modifiers; + updated.data!.modifiers = original.modifiers; } } return finishUpdateBaseSignatureDeclaration(updated, original); @@ -4379,29 +4618,32 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode members: readonly ClassElement[], ) { const node = createBaseDeclaration(SyntaxKind.ClassDeclaration); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.heritageClauses = asNodeArray(heritageClauses); - node.members = createNodeArray(members); - - if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + typeParameters: asNodeArray(typeParameters), + heritageClauses: asNodeArray(heritageClauses), + members: createNodeArray(members), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + if (modifiersToFlags(nodeData.modifiers) & ModifierFlags.Ambient) { node.transformFlags = TransformFlags.ContainsTypeScript; } else { - node.transformFlags |= propagateChildrenFlags(node.modifiers) | - propagateNameFlags(node.name) | - propagateChildrenFlags(node.typeParameters) | - propagateChildrenFlags(node.heritageClauses) | - propagateChildrenFlags(node.members) | - (node.typeParameters ? TransformFlags.ContainsTypeScript : TransformFlags.None) | + node.transformFlags |= propagateChildrenFlags(nodeData.modifiers) | + propagateNameFlags(nodeData.name) | + propagateChildrenFlags(nodeData.typeParameters) | + propagateChildrenFlags(nodeData.heritageClauses) | + propagateChildrenFlags(nodeData.members) | + (nodeData.typeParameters ? TransformFlags.ContainsTypeScript : TransformFlags.None) | TransformFlags.ContainsES2015; if (node.transformFlags & TransformFlags.ContainsTypeScriptClassSyntax) { node.transformFlags |= TransformFlags.ContainsTypeScript; } } - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4432,14 +4674,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode members: readonly TypeElement[], ) { const node = createBaseDeclaration(SyntaxKind.InterfaceDeclaration); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.heritageClauses = asNodeArray(heritageClauses); - node.members = createNodeArray(members); + node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + typeParameters: asNodeArray(typeParameters), + heritageClauses: asNodeArray(heritageClauses), + members: createNodeArray(members), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4469,15 +4714,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode type: TypeNode, ) { const node = createBaseDeclaration(SyntaxKind.TypeAliasDeclaration); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.type = type; + node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + typeParameters: asNodeArray(typeParameters), + type, + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags = TransformFlags.ContainsTypeScript; - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) return node; } @@ -4504,16 +4752,19 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode members: readonly EnumMember[], ) { const node = createBaseDeclaration(SyntaxKind.EnumDeclaration); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.members = createNodeArray(members); - node.transformFlags |= propagateChildrenFlags(node.modifiers) | - propagateChildFlags(node.name) | - propagateChildrenFlags(node.members) | + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + members: createNodeArray(members), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildrenFlags(nodeData.modifiers) | + propagateChildFlags(nodeData.name) | + propagateChildrenFlags(nodeData.members) | TransformFlags.ContainsTypeScript; node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Enum declarations cannot contain `await` - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4539,24 +4790,27 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode flags = NodeFlags.None, ) { const node = createBaseDeclaration(SyntaxKind.ModuleDeclaration); - node.modifiers = asNodeArray(modifiers); node.flags |= flags & (NodeFlags.Namespace | NodeFlags.NestedNamespace | NodeFlags.GlobalAugmentation); - node.name = name; - node.body = body; - if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + name, + body, + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + if (modifiersToFlags(nodeData.modifiers) & ModifierFlags.Ambient) { node.transformFlags = TransformFlags.ContainsTypeScript; } else { - node.transformFlags |= propagateChildrenFlags(node.modifiers) | - propagateChildFlags(node.name) | - propagateChildFlags(node.body) | + node.transformFlags |= propagateChildrenFlags(nodeData.modifiers) | + propagateChildFlags(nodeData.name) | + propagateChildFlags(nodeData.body) | TransformFlags.ContainsTypeScript; } node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Module declarations cannot contain `await`. - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) return node; } @@ -4577,10 +4831,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createModuleBlock(statements: readonly Statement[]) { const node = createBaseNode(SyntaxKind.ModuleBlock); - node.statements = createNodeArray(statements); - node.transformFlags |= propagateChildrenFlags(node.statements); + const nodeData = node.data = { + statements: createNodeArray(statements), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildrenFlags(nodeData.statements); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4594,11 +4850,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock { const node = createBaseNode(SyntaxKind.CaseBlock); - node.clauses = createNodeArray(clauses); - node.transformFlags |= propagateChildrenFlags(node.clauses); + const nodeData = node.data = { + clauses: createNodeArray(clauses), + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + }; + + node.transformFlags |= propagateChildrenFlags(nodeData.clauses); - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) return node; } @@ -4612,12 +4872,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNamespaceExportDeclaration(name: string | Identifier) { const node = createBaseDeclaration(SyntaxKind.NamespaceExportDeclaration); - node.name = asName(name); - node.transformFlags |= propagateIdentifierNameFlags(node.name) | + const nodeData = node.data = { + name: asName(name), + modifiers: undefined, // initialized by parser to report grammar errors + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateIdentifierNameFlags(nodeData.name) | TransformFlags.ContainsTypeScript; - node.modifiers = undefined; // initialized by parser to report grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4628,10 +4891,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateNamespaceExportDeclaration(updated: Mutable, original: NamespaceExportDeclaration) { + function finishUpdateNamespaceExportDeclaration(updated: NodeData, original: NamespaceExportDeclaration) { if (updated !== original) { // copy children used only for error reporting - updated.modifiers = original.modifiers; + updated.data!.modifiers = original.modifiers; } return update(updated, original); } @@ -4644,21 +4907,24 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode moduleReference: ModuleReference, ) { const node = createBaseDeclaration(SyntaxKind.ImportEqualsDeclaration); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.isTypeOnly = isTypeOnly; - node.moduleReference = moduleReference; - node.transformFlags |= propagateChildrenFlags(node.modifiers) | - propagateIdentifierNameFlags(node.name) | - propagateChildFlags(node.moduleReference); - - if (!isExternalModuleReference(node.moduleReference)) { + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + name: asName(name), + isTypeOnly, + moduleReference, + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildrenFlags(nodeData.modifiers) | + propagateIdentifierNameFlags(nodeData.name) | + propagateChildFlags(nodeData.moduleReference); + + if (!isExternalModuleReference(nodeData.moduleReference)) { node.transformFlags |= TransformFlags.ContainsTypeScript; } node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Import= declaration is always parsed in an Await context - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4686,15 +4952,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode attributes: ImportAttributes | undefined, ): ImportDeclaration { const node = createBaseNode(SyntaxKind.ImportDeclaration); - node.modifiers = asNodeArray(modifiers); - node.importClause = importClause; - node.moduleSpecifier = moduleSpecifier; - node.attributes = node.assertClause = attributes; - node.transformFlags |= propagateChildFlags(node.importClause) | - propagateChildFlags(node.moduleSpecifier); + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + importClause, + moduleSpecifier, + attributes, + assertClause: attributes, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.importClause) | + propagateChildFlags(nodeData.moduleSpecifier); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4717,11 +4986,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { const node = createBaseDeclaration(SyntaxKind.ImportClause); - node.isTypeOnly = isTypeOnly; - node.name = name; - node.namedBindings = namedBindings; - node.transformFlags |= propagateChildFlags(node.name) | - propagateChildFlags(node.namedBindings); + const nodeData = node.data = { + isTypeOnly, + name, + namedBindings, + localSymbol: undefined, + }; + node.transformFlags |= propagateChildFlags(nodeData.name) | + propagateChildFlags(nodeData.namedBindings); if (isTypeOnly) { node.transformFlags |= TransformFlags.ContainsTypeScript; } @@ -4741,9 +5013,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createAssertClause(elements: readonly AssertEntry[], multiLine?: boolean): AssertClause { const node = createBaseNode(SyntaxKind.AssertClause); - node.elements = createNodeArray(elements); - node.multiLine = multiLine; - node.token = SyntaxKind.AssertKeyword; + node.data = { + elements: createNodeArray(elements), + multiLine, + token: SyntaxKind.AssertKeyword, + }; node.transformFlags |= TransformFlags.ContainsESNext; return node; } @@ -4759,8 +5033,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createAssertEntry(name: AssertionKey, value: Expression): AssertEntry { const node = createBaseNode(SyntaxKind.AssertEntry); - node.name = name; - node.value = value; + node.data = { + name, + value, + }; node.transformFlags |= TransformFlags.ContainsESNext; return node; } @@ -4776,8 +5052,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createImportTypeAssertionContainer(clause: AssertClause, multiLine?: boolean): ImportTypeAssertionContainer { const node = createBaseNode(SyntaxKind.ImportTypeAssertionContainer); - node.assertClause = clause; - node.multiLine = multiLine; + node.data = { + assertClause: clause, + multiLine, + }; return node; } @@ -4794,9 +5072,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createImportAttributes(elements: readonly ImportAttribute[], multiLine?: boolean, token?: ImportAttributes["token"]): ImportAttributes; function createImportAttributes(elements: readonly ImportAttribute[], multiLine?: boolean, token?: ImportAttributes["token"]): ImportAttributes { const node = createBaseNode(SyntaxKind.ImportAttributes); - node.token = token ?? SyntaxKind.WithKeyword; - node.elements = createNodeArray(elements); - node.multiLine = multiLine; + node.data = { + token: token ?? SyntaxKind.WithKeyword, + elements: createNodeArray(elements), + multiLine, + }; node.transformFlags |= TransformFlags.ContainsESNext; return node; } @@ -4812,8 +5092,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createImportAttribute(name: ImportAttributeName, value: Expression): ImportAttribute { const node = createBaseNode(SyntaxKind.ImportAttribute); - node.name = name; - node.value = value; + node.data = { + name, + value, + }; node.transformFlags |= TransformFlags.ContainsESNext; return node; } @@ -4829,7 +5111,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNamespaceImport(name: Identifier): NamespaceImport { const node = createBaseDeclaration(SyntaxKind.NamespaceImport); - node.name = name; + node.data = { + name, + localSymbol: undefined, + }; node.transformFlags |= propagateChildFlags(node.name); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; @@ -4845,7 +5130,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNamespaceExport(name: ModuleExportName): NamespaceExport { const node = createBaseDeclaration(SyntaxKind.NamespaceExport); - node.name = name; + node.data = { + name, + localSymbol: undefined, + }; node.transformFlags |= propagateChildFlags(node.name) | TransformFlags.ContainsES2020; node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context @@ -4862,7 +5150,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNamedImports(elements: readonly ImportSpecifier[]): NamedImports { const node = createBaseNode(SyntaxKind.NamedImports); - node.elements = createNodeArray(elements); + node.data = { elements: createNodeArray(elements) }; node.transformFlags |= propagateChildrenFlags(node.elements); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; @@ -4878,11 +5166,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createImportSpecifier(isTypeOnly: boolean, propertyName: ModuleExportName | undefined, name: Identifier) { const node = createBaseDeclaration(SyntaxKind.ImportSpecifier); - node.isTypeOnly = isTypeOnly; - node.propertyName = propertyName; - node.name = name; - node.transformFlags |= propagateChildFlags(node.propertyName) | - propagateChildFlags(node.name); + const nodeData = node.data = { + isTypeOnly, + propertyName, + name, + localSymbol: undefined, + }; + node.transformFlags |= propagateChildFlags(nodeData.propertyName) | + propagateChildFlags(nodeData.name); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; } @@ -4903,15 +5194,19 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode expression: Expression, ) { const node = createBaseDeclaration(SyntaxKind.ExportAssignment); - node.modifiers = asNodeArray(modifiers); - node.isExportEquals = isExportEquals; - node.expression = isExportEquals - ? parenthesizerRules().parenthesizeRightSideOfBinary(SyntaxKind.EqualsToken, /*leftSide*/ undefined, expression) - : parenthesizerRules().parenthesizeExpressionOfExportDefault(expression); - node.transformFlags |= propagateChildrenFlags(node.modifiers) | propagateChildFlags(node.expression); + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + isExportEquals, + expression: isExportEquals + ? parenthesizerRules().parenthesizeRightSideOfBinary(SyntaxKind.EqualsToken, /*leftSide*/ undefined, expression) + : parenthesizerRules().parenthesizeExpressionOfExportDefault(expression), + localSymbol: undefined, + // name: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildrenFlags(nodeData.modifiers) | propagateChildFlags(nodeData.expression); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4936,17 +5231,22 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode attributes?: ImportAttributes, ) { const node = createBaseDeclaration(SyntaxKind.ExportDeclaration); - node.modifiers = asNodeArray(modifiers); - node.isTypeOnly = isTypeOnly; - node.exportClause = exportClause; - node.moduleSpecifier = moduleSpecifier; - node.attributes = node.assertClause = attributes; - node.transformFlags |= propagateChildrenFlags(node.modifiers) | - propagateChildFlags(node.exportClause) | - propagateChildFlags(node.moduleSpecifier); + const nodeData = node.data = { + modifiers: asNodeArray(modifiers), + isTypeOnly, + exportClause, + moduleSpecifier, + attributes, + assertClause: attributes, + localSymbol: undefined, + // name: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildrenFlags(nodeData.modifiers) | + propagateChildFlags(nodeData.exportClause) | + propagateChildFlags(nodeData.moduleSpecifier); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -4968,11 +5268,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateExportDeclaration(updated: Mutable, original: ExportDeclaration) { + function finishUpdateExportDeclaration(updated: NodeData, original: ExportDeclaration) { if (updated !== original) { // copy children used only for error reporting if (updated.modifiers === original.modifiers) { - updated.modifiers = original.modifiers; + updated.data!.modifiers = original.modifiers; } } return update(updated, original); @@ -4981,7 +5281,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNamedExports(elements: readonly ExportSpecifier[]) { const node = createBaseNode(SyntaxKind.NamedExports); - node.elements = createNodeArray(elements); + node.data = { elements: createNodeArray(elements) }; node.transformFlags |= propagateChildrenFlags(node.elements); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; @@ -4997,14 +5297,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createExportSpecifier(isTypeOnly: boolean, propertyName: string | ModuleExportName | undefined, name: string | ModuleExportName) { const node = createBaseNode(SyntaxKind.ExportSpecifier); - node.isTypeOnly = isTypeOnly; - node.propertyName = asName(propertyName); - node.name = asName(name); - node.transformFlags |= propagateChildFlags(node.propertyName) | - propagateChildFlags(node.name); + const nodeData = node.data = { + isTypeOnly, + propertyName: asName(propertyName), + name: asName(name), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.propertyName) | + propagateChildFlags(nodeData.name); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -5020,8 +5323,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createMissingDeclaration(): MissingDeclaration { const node = createBaseDeclaration(SyntaxKind.MissingDeclaration); - - node.jsDoc = undefined; // initialized by parser (JsDocContainer) + node.data = { + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; return node; } @@ -5032,7 +5336,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createExternalModuleReference(expression: Expression) { const node = createBaseNode(SyntaxKind.ExternalModuleReference); - node.expression = expression; + node.data = { expression }; node.transformFlags |= propagateChildFlags(node.expression); node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context return node; @@ -5063,8 +5367,8 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode const node = createJSDocUnaryTypeWorker( kind, postfix ? type && parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(type) : type, - ) as Mutable; - node.postfix = postfix; + ); + (node as unknown as NodeData).data!.postfix = postfix; return node; } @@ -5074,8 +5378,8 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // createJSDocNamepathType function createJSDocUnaryTypeWorker(kind: T["kind"], type: T["type"]): T { const node = createBaseNode(kind); - node.type = type; - return node; + node.data = { type, postfix: undefined } as any; + return node as unknown as T; } // @api @@ -5100,15 +5404,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocFunctionType(parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType { const node = createBaseDeclaration(SyntaxKind.JSDocFunctionType); - node.parameters = asNodeArray(parameters); - node.type = type; - node.transformFlags = propagateChildrenFlags(node.parameters) | - (node.type ? TransformFlags.ContainsTypeScript : TransformFlags.None); + const nodeData = node.data = { + parameters: asNodeArray(parameters), + type, + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + typeArguments: undefined, // used in quick info + localSymbol: undefined, + // name: undefined, + // typeParameters: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags = propagateChildrenFlags(nodeData.parameters) | + (nodeData.type ? TransformFlags.ContainsTypeScript : TransformFlags.None); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.typeArguments = undefined; // used in quick info return node; } @@ -5123,8 +5432,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocTypeLiteral(propertyTags?: readonly JSDocPropertyLikeTag[], isArrayType = false): JSDocTypeLiteral { const node = createBaseDeclaration(SyntaxKind.JSDocTypeLiteral); - node.jsDocPropertyTags = asNodeArray(propertyTags); - node.isArrayType = isArrayType; + node.data = { + jsDocPropertyTags: asNodeArray(propertyTags), + isArrayType, + }; return node; } @@ -5139,7 +5450,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression { const node = createBaseNode(SyntaxKind.JSDocTypeExpression); - node.type = type; + node.data = { type }; return node; } @@ -5153,13 +5464,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature { const node = createBaseDeclaration(SyntaxKind.JSDocSignature); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; + node.data = { + typeParameters: asNodeArray(typeParameters), + parameters: createNodeArray(parameters), + type, - node.jsDoc = undefined; // initialized by parser (JsDocContainer) - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; return node; } @@ -5182,23 +5495,22 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createBaseJSDocTag(kind: T["kind"], tagName: Identifier, comment: string | NodeArray | undefined) { const node = createBaseNode(kind); - node.tagName = tagName; - node.comment = comment; - return node; - } - - function createBaseJSDocTagDeclaration(kind: T["kind"], tagName: Identifier, comment: string | NodeArray | undefined) { - const node = createBaseDeclaration(kind); - node.tagName = tagName; - node.comment = comment; + node.data = { + tagName, + comment, + } as NodeData["data"] as NodeData["data"]; return node; } // @api function createJSDocTemplateTag(tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string | NodeArray): JSDocTemplateTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocTemplateTag, tagName ?? createIdentifier("template"), comment); - node.constraint = constraint; - node.typeParameters = createNodeArray(typeParameters); + const node = createBaseNode(SyntaxKind.JSDocTemplateTag); + node.data = { + tagName: tagName ?? createIdentifier("template"), + comment, + constraint, + typeParameters: createNodeArray(typeParameters), + }; return node; } @@ -5214,13 +5526,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string | NodeArray): JSDocTypedefTag { - const node = createBaseJSDocTagDeclaration(SyntaxKind.JSDocTypedefTag, tagName ?? createIdentifier("typedef"), comment); - node.typeExpression = typeExpression; - node.fullName = fullName; - node.name = getJSDocTypeAliasName(fullName); + const node = createBaseNode(SyntaxKind.JSDocTypedefTag); + node.data = { + tagName: tagName ?? createIdentifier("typedef"), + comment, + typeExpression, + fullName, + name: getJSDocTypeAliasName(fullName), - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + localSymbol: undefined, + }; return node; } @@ -5236,11 +5553,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string | NodeArray): JSDocParameterTag { - const node = createBaseJSDocTagDeclaration(SyntaxKind.JSDocParameterTag, tagName ?? createIdentifier("param"), comment); - node.typeExpression = typeExpression; - node.name = name; - node.isNameFirst = !!isNameFirst; - node.isBracketed = isBracketed; + const node = createBaseNode(SyntaxKind.JSDocParameterTag); + node.data = { + tagName: tagName ?? createIdentifier("param"), + comment, + typeExpression, + name, + localSymbol: undefined, + isNameFirst: !!isNameFirst, + isBracketed, + }; return node; } @@ -5258,11 +5580,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string | NodeArray): JSDocPropertyTag { - const node = createBaseJSDocTagDeclaration(SyntaxKind.JSDocPropertyTag, tagName ?? createIdentifier("prop"), comment); - node.typeExpression = typeExpression; - node.name = name; - node.isNameFirst = !!isNameFirst; - node.isBracketed = isBracketed; + const node = createBaseNode(SyntaxKind.JSDocPropertyTag); + node.data = { + tagName: tagName ?? createIdentifier("prop"), + comment, + typeExpression, + name, + isNameFirst: !!isNameFirst, + isBracketed, + localSymbol: undefined, + }; return node; } @@ -5280,13 +5607,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocCallbackTag(tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string | NodeArray): JSDocCallbackTag { - const node = createBaseJSDocTagDeclaration(SyntaxKind.JSDocCallbackTag, tagName ?? createIdentifier("callback"), comment); - node.typeExpression = typeExpression; - node.fullName = fullName; - node.name = getJSDocTypeAliasName(fullName); + const node = createBaseNode(SyntaxKind.JSDocCallbackTag); + node.data = { + tagName: tagName ?? createIdentifier("callback"), + comment, + typeExpression, + fullName, + name: getJSDocTypeAliasName(fullName), - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + }; return node; } @@ -5302,8 +5633,8 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocOverloadTag(tagName: Identifier | undefined, typeExpression: JSDocSignature, comment?: string | NodeArray): JSDocOverloadTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocOverloadTag, tagName ?? createIdentifier("overload"), comment); - node.typeExpression = typeExpression; + const node = createBaseNode(SyntaxKind.JSDocOverloadTag); + node.data = { tagName: tagName ?? createIdentifier("overload"), comment, typeExpression }; return node; } @@ -5318,8 +5649,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocAugmentsTag(tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment?: string | NodeArray): JSDocAugmentsTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocAugmentsTag, tagName ?? createIdentifier("augments"), comment); - node.class = className; + const node = createBaseNode(SyntaxKind.JSDocAugmentsTag); + node.data = { + tagName: tagName ?? createIdentifier("augments"), + comment, + class: className, + }; return node; } @@ -5334,15 +5669,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocImplementsTag(tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment?: string | NodeArray): JSDocImplementsTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocImplementsTag, tagName ?? createIdentifier("implements"), comment); - node.class = className; + const node = createBaseNode(SyntaxKind.JSDocImplementsTag); + node.data = { tagName: tagName ?? createIdentifier("implements"), comment, class: className }; return node; } // @api function createJSDocSeeTag(tagName: Identifier | undefined, name: JSDocNameReference | undefined, comment?: string | NodeArray): JSDocSeeTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocSeeTag, tagName ?? createIdentifier("see"), comment); - node.name = name; + const node = createBaseNode(SyntaxKind.JSDocSeeTag); + node.data = { tagName: tagName ?? createIdentifier("see"), comment, name }; return node; } @@ -5358,7 +5693,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocNameReference(name: EntityName | JSDocMemberName): JSDocNameReference { const node = createBaseNode(SyntaxKind.JSDocNameReference); - node.name = name; + node.data = { name }; return node; } @@ -5372,8 +5707,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocMemberName(left: EntityName | JSDocMemberName, right: Identifier) { const node = createBaseNode(SyntaxKind.JSDocMemberName); - node.left = left; - node.right = right; + node.data = { + left, + right, + }; node.transformFlags |= propagateChildFlags(node.left) | propagateChildFlags(node.right); return node; @@ -5390,8 +5727,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocLink(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLink { const node = createBaseNode(SyntaxKind.JSDocLink); - node.name = name; - node.text = text; + node.data = { + name, + text, + }; return node; } @@ -5405,8 +5744,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocLinkCode(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkCode { const node = createBaseNode(SyntaxKind.JSDocLinkCode); - node.name = name; - node.text = text; + node.data = { + name, + text, + }; return node; } @@ -5420,8 +5761,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocLinkPlain(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkPlain { const node = createBaseNode(SyntaxKind.JSDocLinkPlain); - node.name = name; - node.text = text; + node.data = { + name, + text, + }; return node; } @@ -5449,9 +5792,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // createJSDocProtectedTag // createJSDocReadonlyTag // createJSDocDeprecatedTag - function createJSDocSimpleTagWorker(kind: T["kind"], tagName: Identifier | undefined, comment?: string | NodeArray) { + function createJSDocSimpleTagWorker(kind: T["kind"], tagName: Identifier | undefined, comment?: string | NodeArray): T { const node = createBaseJSDocTag(kind, tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), comment); - return node; + return node as unknown as T; } // @api @@ -5476,9 +5819,13 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // createJSDocEnumTag // createJSDocSatisfiesTag function createJSDocTypeLikeTagWorker(kind: T["kind"], tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string | NodeArray) { - const node = createBaseJSDocTag(kind, tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), comment); - node.typeExpression = typeExpression; - return node; + const node = createBaseNode(kind); + node.data = { + tagName: tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), + comment, + typeExpression, + }; + return node as any as T; } // @api @@ -5511,11 +5858,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocEnumTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string | NodeArray) { - const node = createBaseJSDocTagDeclaration(SyntaxKind.JSDocEnumTag, tagName ?? createIdentifier(getDefaultTagNameForKind(SyntaxKind.JSDocEnumTag)), comment); - node.typeExpression = typeExpression; + const node = createBaseNode(SyntaxKind.JSDocEnumTag); + node.data = { + tagName: tagName ?? createIdentifier(getDefaultTagNameForKind(SyntaxKind.JSDocEnumTag)), + comment, + typeExpression, - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + }; return node; } @@ -5530,11 +5881,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocImportTag(tagName: Identifier | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes, comment?: string | NodeArray): JSDocImportTag { - const node = createBaseJSDocTag(SyntaxKind.JSDocImportTag, tagName ?? createIdentifier("import"), comment); - node.importClause = importClause; - node.moduleSpecifier = moduleSpecifier; - node.attributes = attributes; - node.comment = comment; + const node = createBaseNode(SyntaxKind.JSDocImportTag); + node.data = { + tagName: tagName ?? createIdentifier("import"), + comment, + importClause, + moduleSpecifier, + attributes, + }; return node; } @@ -5551,7 +5905,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocText(text: string): JSDocText { const node = createBaseNode(SyntaxKind.JSDocText); - node.text = text; + node.data = { text }; return node; } @@ -5565,8 +5919,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJSDocComment(comment?: string | NodeArray | undefined, tags?: readonly JSDocTag[] | undefined) { const node = createBaseNode(SyntaxKind.JSDoc); - node.comment = comment; - node.tags = asNodeArray(tags); + node.data = { + comment, + tags: asNodeArray(tags), + }; return node; } @@ -5585,12 +5941,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { const node = createBaseNode(SyntaxKind.JsxElement); - node.openingElement = openingElement; - node.children = createNodeArray(children); - node.closingElement = closingElement; - node.transformFlags |= propagateChildFlags(node.openingElement) | - propagateChildrenFlags(node.children) | - propagateChildFlags(node.closingElement) | + const nodeData = node.data = { + openingElement, + children: createNodeArray(children), + closingElement, + }; + node.transformFlags |= propagateChildFlags(nodeData.openingElement) | + propagateChildrenFlags(nodeData.children) | + propagateChildFlags(nodeData.closingElement) | TransformFlags.ContainsJsx; return node; } @@ -5607,14 +5965,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { const node = createBaseNode(SyntaxKind.JsxSelfClosingElement); - node.tagName = tagName; - node.typeArguments = asNodeArray(typeArguments); - node.attributes = attributes; - node.transformFlags |= propagateChildFlags(node.tagName) | - propagateChildrenFlags(node.typeArguments) | - propagateChildFlags(node.attributes) | + const nodeData = node.data = { + tagName, + typeArguments: asNodeArray(typeArguments), + attributes, + }; + node.transformFlags |= propagateChildFlags(nodeData.tagName) | + propagateChildrenFlags(nodeData.typeArguments) | + propagateChildFlags(nodeData.attributes) | TransformFlags.ContainsJsx; - if (node.typeArguments) { + if (nodeData.typeArguments) { node.transformFlags |= TransformFlags.ContainsTypeScript; } return node; @@ -5632,12 +5992,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { const node = createBaseNode(SyntaxKind.JsxOpeningElement); - node.tagName = tagName; - node.typeArguments = asNodeArray(typeArguments); - node.attributes = attributes; - node.transformFlags |= propagateChildFlags(node.tagName) | - propagateChildrenFlags(node.typeArguments) | - propagateChildFlags(node.attributes) | + const nodeData = node.data = { + tagName, + typeArguments: asNodeArray(typeArguments), + attributes, + }; + node.transformFlags |= propagateChildFlags(nodeData.tagName) | + propagateChildrenFlags(nodeData.typeArguments) | + propagateChildFlags(nodeData.attributes) | TransformFlags.ContainsJsx; if (typeArguments) { node.transformFlags |= TransformFlags.ContainsTypeScript; @@ -5657,7 +6019,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxClosingElement(tagName: JsxTagNameExpression) { const node = createBaseNode(SyntaxKind.JsxClosingElement); - node.tagName = tagName; + node.data = { tagName }; node.transformFlags |= propagateChildFlags(node.tagName) | TransformFlags.ContainsJsx; return node; @@ -5673,12 +6035,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { const node = createBaseNode(SyntaxKind.JsxFragment); - node.openingFragment = openingFragment; - node.children = createNodeArray(children); - node.closingFragment = closingFragment; - node.transformFlags |= propagateChildFlags(node.openingFragment) | - propagateChildrenFlags(node.children) | - propagateChildFlags(node.closingFragment) | + const nodeData = node.data = { + openingFragment, + children: createNodeArray(children), + closingFragment, + }; + node.transformFlags |= propagateChildFlags(nodeData.openingFragment) | + propagateChildrenFlags(nodeData.children) | + propagateChildFlags(nodeData.closingFragment) | TransformFlags.ContainsJsx; return node; } @@ -5695,8 +6059,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean) { const node = createBaseNode(SyntaxKind.JsxText); - node.text = text; - node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces; + node.data = { + // hasExtendedUnicodeEscape: false, + // isUnterminated: false, + text, + containsOnlyTriviaWhiteSpaces: !!containsOnlyTriviaWhiteSpaces, + }; node.transformFlags |= TransformFlags.ContainsJsx; return node; } @@ -5726,8 +6094,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxAttribute(name: JsxAttributeName, initializer: JsxAttributeValue | undefined) { const node = createBaseDeclaration(SyntaxKind.JsxAttribute); - node.name = name; - node.initializer = initializer; + node.data = { + name, + initializer, + localSymbol: undefined, + }; node.transformFlags |= propagateChildFlags(node.name) | propagateChildFlags(node.initializer) | TransformFlags.ContainsJsx; @@ -5745,7 +6116,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxAttributes(properties: readonly JsxAttributeLike[]) { const node = createBaseDeclaration(SyntaxKind.JsxAttributes); - node.properties = createNodeArray(properties); + node.data = { properties: createNodeArray(properties) }; node.transformFlags |= propagateChildrenFlags(node.properties) | TransformFlags.ContainsJsx; return node; @@ -5761,7 +6132,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxSpreadAttribute(expression: Expression) { const node = createBaseNode(SyntaxKind.JsxSpreadAttribute); - node.expression = expression; + node.data = { + expression, + localSymbol: undefined, + name: undefined, + }; node.transformFlags |= propagateChildFlags(node.expression) | TransformFlags.ContainsJsx; return node; @@ -5777,8 +6152,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) { const node = createBaseNode(SyntaxKind.JsxExpression); - node.dotDotDotToken = dotDotDotToken; - node.expression = expression; + node.data = { + dotDotDotToken, + expression, + }; node.transformFlags |= propagateChildFlags(node.dotDotDotToken) | propagateChildFlags(node.expression) | TransformFlags.ContainsJsx; @@ -5795,8 +6172,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createJsxNamespacedName(namespace: Identifier, name: Identifier) { const node = createBaseNode(SyntaxKind.JsxNamespacedName); - node.namespace = namespace; - node.name = name; + node.data = { + namespace, + name, + }; node.transformFlags |= propagateChildFlags(node.namespace) | propagateChildFlags(node.name) | TransformFlags.ContainsJsx; @@ -5818,12 +6197,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createCaseClause(expression: Expression, statements: readonly Statement[]) { const node = createBaseNode(SyntaxKind.CaseClause); - node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); - node.statements = createNodeArray(statements); - node.transformFlags |= propagateChildFlags(node.expression) | - propagateChildrenFlags(node.statements); + const nodeData = node.data = { + expression: parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression), + statements: createNodeArray(statements), + // fallthroughFlowNode: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + node.transformFlags |= propagateChildFlags(nodeData.expression) | + propagateChildrenFlags(nodeData.statements); - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -5838,7 +6220,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createDefaultClause(statements: readonly Statement[]) { const node = createBaseNode(SyntaxKind.DefaultClause); - node.statements = createNodeArray(statements); + node.data = { statements: createNodeArray(statements) }; node.transformFlags = propagateChildrenFlags(node.statements); return node; } @@ -5853,8 +6235,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]) { const node = createBaseNode(SyntaxKind.HeritageClause); - node.token = token; - node.types = createNodeArray(types); + node.data = { + token, + types: createNodeArray(types), + }; node.transformFlags |= propagateChildrenFlags(node.types); switch (token) { case SyntaxKind.ExtendsKeyword: @@ -5879,15 +6263,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createCatchClause(variableDeclaration: string | BindingName | VariableDeclaration | undefined, block: Block) { const node = createBaseNode(SyntaxKind.CatchClause); - node.variableDeclaration = asVariableDeclaration(variableDeclaration); - node.block = block; - - node.transformFlags |= propagateChildFlags(node.variableDeclaration) | - propagateChildFlags(node.block) | + const nodeData = node.data = { + variableDeclaration: asVariableDeclaration(variableDeclaration), + block, + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + }; + + node.transformFlags |= propagateChildFlags(nodeData.variableDeclaration) | + propagateChildFlags(nodeData.block) | (!variableDeclaration ? TransformFlags.ContainsES2019 : TransformFlags.None); - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) return node; } @@ -5906,15 +6292,19 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createPropertyAssignment(name: string | PropertyName, initializer: Expression) { const node = createBaseDeclaration(SyntaxKind.PropertyAssignment); - node.name = asName(name); - node.initializer = parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer); - node.transformFlags |= propagateNameFlags(node.name) | - propagateChildFlags(node.initializer); + const nodeData = node.data = { + name: asName(name), + initializer: parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer), + + modifiers: undefined, // initialized by parser to report grammar errors + questionToken: undefined, // initialized by parser to report grammar errors + exclamationToken: undefined, // initialized by parser to report grammar errors + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; - node.modifiers = undefined; // initialized by parser to report grammar errors - node.questionToken = undefined; // initialized by parser to report grammar errors - node.exclamationToken = undefined; // initialized by parser to report grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) + node.transformFlags |= propagateNameFlags(nodeData.name) | + propagateChildFlags(nodeData.initializer); return node; } @@ -5926,13 +6316,13 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdatePropertyAssignment(updated: Mutable, original: PropertyAssignment) { + function finishUpdatePropertyAssignment(updated: NodeData, original: PropertyAssignment) { // copy children used only for error reporting if (updated !== original) { // copy children used only for error reporting - updated.modifiers = original.modifiers; - updated.questionToken = original.questionToken; - updated.exclamationToken = original.exclamationToken; + updated.data!.modifiers = original.modifiers; + updated.data!.questionToken = original.questionToken; + updated.data!.exclamationToken = original.exclamationToken; } return update(updated, original); } @@ -5940,17 +6330,21 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression) { const node = createBaseDeclaration(SyntaxKind.ShorthandPropertyAssignment); - node.name = asName(name); - node.objectAssignmentInitializer = objectAssignmentInitializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(objectAssignmentInitializer); - node.transformFlags |= propagateIdentifierNameFlags(node.name) | - propagateChildFlags(node.objectAssignmentInitializer) | + const nodeData = node.data = { + name: asName(name), + objectAssignmentInitializer: objectAssignmentInitializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(objectAssignmentInitializer), + + equalsToken: undefined, // initialized by parser to report grammar errors + modifiers: undefined, // initialized by parser to report grammar errors + questionToken: undefined, // initialized by parser to report grammar errors + exclamationToken: undefined, // initialized by parser to report grammar errors + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; + + node.transformFlags |= propagateIdentifierNameFlags(nodeData.name) | + propagateChildFlags(nodeData.objectAssignmentInitializer) | TransformFlags.ContainsES2015; - - node.equalsToken = undefined; // initialized by parser to report grammar errors - node.modifiers = undefined; // initialized by parser to report grammar errors - node.questionToken = undefined; // initialized by parser to report grammar errors - node.exclamationToken = undefined; // initialized by parser to report grammar errors - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -5962,13 +6356,13 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } - function finishUpdateShorthandPropertyAssignment(updated: Mutable, original: ShorthandPropertyAssignment) { + function finishUpdateShorthandPropertyAssignment(updated: NodeData, original: ShorthandPropertyAssignment) { if (updated !== original) { // copy children used only for error reporting - updated.modifiers = original.modifiers; - updated.questionToken = original.questionToken; - updated.exclamationToken = original.exclamationToken; - updated.equalsToken = original.equalsToken; + updated.data!.modifiers = original.modifiers; + updated.data!.questionToken = original.questionToken; + updated.data!.exclamationToken = original.exclamationToken; + updated.data!.equalsToken = original.equalsToken; } return update(updated, original); } @@ -5976,12 +6370,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createSpreadAssignment(expression: Expression) { const node = createBaseDeclaration(SyntaxKind.SpreadAssignment); - node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); + node.data = { + expression: parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression), + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags |= propagateChildFlags(node.expression) | TransformFlags.ContainsES2018 | TransformFlags.ContainsObjectRestOrSpread; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -5999,13 +6395,16 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createEnumMember(name: string | PropertyName, initializer?: Expression) { const node = createBaseDeclaration(SyntaxKind.EnumMember); - node.name = asName(name); - node.initializer = initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer); + node.data = { + name: asName(name), + initializer: initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer), + localSymbol: undefined, + jsDoc: undefined, // initialized by parser (JsDocContainer) + }; node.transformFlags |= propagateChildFlags(node.name) | propagateChildFlags(node.initializer) | TransformFlags.ContainsTypeScript; - node.jsDoc = undefined; // initialized by parser (JsDocContainer) return node; } @@ -6027,52 +6426,55 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode endOfFileToken: EndOfFileToken, flags: NodeFlags, ) { - const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as Mutable; - node.statements = createNodeArray(statements); - node.endOfFileToken = endOfFileToken; - node.flags |= flags; - node.text = ""; - node.fileName = ""; - node.path = "" as Path; - node.resolvedPath = "" as Path; - node.originalFileName = ""; - node.languageVersion = ScriptTarget.ES5; - node.languageVariant = 0; - node.scriptKind = 0; - node.isDeclarationFile = false; - node.hasNoDefaultLib = false; - - node.transformFlags |= propagateChildrenFlags(node.statements) | - propagateChildFlags(node.endOfFileToken); - - node.locals = undefined; // initialized by binder (LocalsContainer) - node.nextContainer = undefined; // initialized by binder (LocalsContainer) - node.endFlowNode = undefined; - - node.nodeCount = 0; - node.identifierCount = 0; - node.symbolCount = 0; - node.parseDiagnostics = undefined!; - node.bindDiagnostics = undefined!; - node.bindSuggestionDiagnostics = undefined; - node.lineMap = undefined!; - node.externalModuleIndicator = undefined; - node.setExternalModuleIndicator = undefined; - node.pragmas = undefined!; - node.checkJsDirective = undefined; - node.referencedFiles = undefined!; - node.typeReferenceDirectives = undefined!; - node.libReferenceDirectives = undefined!; - node.amdDependencies = undefined!; - node.commentDirectives = undefined; - node.identifiers = undefined!; - node.packageJsonLocations = undefined; - node.packageJsonScope = undefined; - node.imports = undefined!; - node.moduleAugmentations = undefined!; - node.ambientModuleNames = undefined!; - node.classifiableNames = undefined; - node.impliedNodeFormat = undefined; + const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as NodeData; + node.flags = flags; + + const nodeData = node.data = { + statements: createNodeArray(statements), + endOfFileToken, + text: "", + fileName: "", + path: "" as Path, + resolvedPath: "" as Path, + originalFileName: "", + languageVersion: ScriptTarget.ES5, + languageVariant: 0, + scriptKind: 0, + isDeclarationFile: false, + hasNoDefaultLib: false, + + locals: undefined, // initialized by binder (LocalsContainer) + nextContainer: undefined, // initialized by binder (LocalsContainer) + endFlowNode: undefined, + + nodeCount: 0, + identifierCount: 0, + symbolCount: 0, + parseDiagnostics: undefined!, + bindDiagnostics: undefined!, + bindSuggestionDiagnostics: undefined, + lineMap: undefined!, + externalModuleIndicator: undefined, + setExternalModuleIndicator: undefined, + pragmas: undefined!, + checkJsDirective: undefined, + referencedFiles: undefined!, + typeReferenceDirectives: undefined!, + libReferenceDirectives: undefined!, + amdDependencies: undefined!, + commentDirectives: undefined, + identifiers: undefined!, + packageJsonLocations: undefined, + packageJsonScope: undefined, + imports: undefined!, + moduleAugmentations: undefined!, + ambientModuleNames: undefined!, + classifiableNames: undefined, + impliedNodeFormat: undefined, + }; + + node.transformFlags |= propagateChildrenFlags(nodeData.statements) | + propagateChildFlags(nodeData.endOfFileToken); return node; } @@ -6096,19 +6498,21 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode }, }, }); + (node as any).data = Object.create((redirectInfo.redirectTarget as any).data); node.redirectInfo = redirectInfo; return node; } function cloneRedirectedSourceFile(source: SourceFile) { - const node = createRedirectedSourceFile(source.redirectInfo!) as Mutable; + const node = createRedirectedSourceFile(source.redirectInfo!) as NodeData; + const nodeData = node.data!; node.flags |= source.flags & ~NodeFlags.Synthesized; - node.fileName = source.fileName; - node.path = source.path; - node.resolvedPath = source.resolvedPath; - node.originalFileName = source.originalFileName; - node.packageJsonLocations = source.packageJsonLocations; - node.packageJsonScope = source.packageJsonScope; + nodeData.fileName = source.fileName; + nodeData.path = source.path; + nodeData.resolvedPath = source.resolvedPath; + nodeData.originalFileName = source.originalFileName; + nodeData.packageJsonLocations = source.packageJsonLocations; + nodeData.packageJsonScope = source.packageJsonScope; node.emitNode = undefined; return node; } @@ -6116,17 +6520,17 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function cloneSourceFileWorker(source: SourceFile) { // TODO: This mechanism for cloning results in megamorphic property reads and writes. In future perf-related // work, we should consider switching explicit property assignments instead of using `for..in`. - const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as Mutable; + const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as NodeData; node.flags |= source.flags & ~NodeFlags.Synthesized; - for (const p in source) { - if (hasProperty(node, p) || !hasProperty(source, p)) { - continue; - } - if (p === "emitNode") { - node.emitNode = undefined; - continue; - } - (node as any)[p] = (source as any)[p]; + node.symbol = source.symbol; + + const sourceData = (source as any).data; + const nodeData: any = (node as any).data = {}; + for (const p in sourceData) { + if (p === "emitNode") continue; + const value = sourceData[p]; + if (value === undefined) continue; + nodeData[p] = sourceData[p]; } return node; } @@ -6147,14 +6551,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode libReferences: readonly FileReference[], ) { const node = cloneSourceFile(source); - node.statements = createNodeArray(statements); - node.isDeclarationFile = isDeclarationFile; - node.referencedFiles = referencedFiles; - node.typeReferenceDirectives = typeReferences; - node.hasNoDefaultLib = hasNoDefaultLib; - node.libReferenceDirectives = libReferences; - node.transformFlags = propagateChildrenFlags(node.statements) | - propagateChildFlags(node.endOfFileToken); + const nodeData = node.data!; + nodeData.statements = createNodeArray(statements); + nodeData.isDeclarationFile = isDeclarationFile; + nodeData.referencedFiles = referencedFiles; + nodeData.typeReferenceDirectives = typeReferences; + nodeData.hasNoDefaultLib = hasNoDefaultLib; + nodeData.libReferenceDirectives = libReferences; + node.transformFlags = propagateChildrenFlags(nodeData.statements) | + propagateChildFlags(nodeData.endOfFileToken); return node; } @@ -6181,11 +6586,13 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createBundle(sourceFiles: readonly SourceFile[]) { const node = createBaseNode(SyntaxKind.Bundle); - node.sourceFiles = sourceFiles; - node.syntheticFileReferences = undefined; - node.syntheticTypeReferences = undefined; - node.syntheticLibReferences = undefined; - node.hasNoDefaultLib = undefined; + node.data = { + sourceFiles, + syntheticFileReferences: undefined, + syntheticTypeReferences: undefined, + syntheticLibReferences: undefined, + hasNoDefaultLib: undefined, + }; return node; } @@ -6203,9 +6610,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createSyntheticExpression(type: Type, isSpread = false, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { const node = createBaseNode(SyntaxKind.SyntheticExpression); - node.type = type; - node.isSpread = isSpread; - node.tupleNameSource = tupleNameSource; + node.data = { + type, + isSpread, + tupleNameSource, + }; return node; } @@ -6229,7 +6638,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createNotEmittedStatement(original: Node) { const node = createBaseNode(SyntaxKind.NotEmittedStatement); - node.original = original; + (node as Mutable).original = original; setTextRange(node, original); return node; } @@ -6244,9 +6653,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createPartiallyEmittedExpression(expression: Expression, original?: Node) { const node = createBaseNode(SyntaxKind.PartiallyEmittedExpression); - node.expression = expression; + const nodeData = node.data = { expression }; node.original = original; - node.transformFlags |= propagateChildFlags(node.expression) | + node.transformFlags |= propagateChildFlags(nodeData.expression) | TransformFlags.ContainsTypeScript; setTextRange(node, original); return node; @@ -6274,7 +6683,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createCommaListExpression(elements: readonly Expression[]) { const node = createBaseNode(SyntaxKind.CommaListExpression); - node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements)); + node.data = { elements: createNodeArray(sameFlatMap(elements, flattenCommaElements)) }; node.transformFlags |= propagateChildrenFlags(node.elements); return node; } @@ -6289,8 +6698,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // @api function createSyntheticReferenceExpression(expression: Expression, thisArg: Expression) { const node = createBaseNode(SyntaxKind.SyntheticReferenceExpression); - node.expression = expression; - node.thisArg = thisArg; + node.data = { + expression, + thisArg, + }; node.transformFlags |= propagateChildFlags(node.expression) | propagateChildFlags(node.thisArg); return node; @@ -6305,18 +6716,20 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } function cloneGeneratedIdentifier(node: GeneratedIdentifier): GeneratedIdentifier { - const clone = createBaseIdentifier(node.escapedText) as Mutable; + const clone = createBaseIdentifier(node.escapedText) as NodeData; clone.flags |= node.flags & ~NodeFlags.Synthesized; clone.transformFlags = node.transformFlags; setOriginal(clone, node); setIdentifierAutoGenerate(clone, { ...node.emitNode.autoGenerate }); - return clone; + return clone as GeneratedIdentifier; } function cloneIdentifier(node: Identifier): Identifier { const clone = createBaseIdentifier(node.escapedText); clone.flags |= node.flags & ~NodeFlags.Synthesized; - clone.jsDoc = node.jsDoc; + if (node.jsDoc) { + clone.jsDoc = node.jsDoc; + } clone.flowNode = node.flowNode; clone.symbol = node.symbol; clone.transformFlags = node.transformFlags; @@ -6329,12 +6742,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } function cloneGeneratedPrivateIdentifier(node: GeneratedPrivateIdentifier): GeneratedPrivateIdentifier { - const clone = createBasePrivateIdentifier(node.escapedText) as Mutable; + const clone = createBasePrivateIdentifier(node.escapedText) as NodeData; clone.flags |= node.flags & ~NodeFlags.Synthesized; clone.transformFlags = node.transformFlags; setOriginal(clone, node); setIdentifierAutoGenerate(clone, { ...node.emitNode.autoGenerate }); - return clone; + return clone as GeneratedPrivateIdentifier; } function clonePrivateIdentifier(node: PrivateIdentifier): PrivateIdentifier { @@ -6355,7 +6768,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode return node; } if (isSourceFile(node)) { - return cloneSourceFile(node) as T & SourceFile; + return cloneSourceFile(node) as SourceFile as T & SourceFile; } if (isGeneratedIdentifier(node)) { return cloneGeneratedIdentifier(node) as T & GeneratedIdentifier; @@ -6370,28 +6783,30 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode return clonePrivateIdentifier(node) as T & PrivateIdentifier; } - const clone = !isNodeKind(node.kind) ? baseFactory.createBaseTokenNode(node.kind) as T : - baseFactory.createBaseNode(node.kind) as T; + const clone = baseFactory.createBaseNode(node.kind) as Mutable; - (clone as Mutable).flags |= node.flags & ~NodeFlags.Synthesized; - (clone as Mutable).transformFlags = node.transformFlags; - setOriginal(clone, node); - - for (const key in node) { - if (hasProperty(clone, key) || !hasProperty(node, key)) { - continue; + clone.flags |= node.flags & ~NodeFlags.Synthesized; + // clone.jsDoc = (node as any).jsDoc; + clone.flowNode = (node as any).flowNode; + clone.symbol = (node as any).symbol; + + const nodeData = (node as any).data; + const cloneData: any = (clone as any).data = {}; + if (nodeData) { + for (const key in nodeData) { + if (key === "emitNode") continue; + const value = nodeData[key]; + if (value === undefined) continue; + cloneData[key] = nodeData[key]; } - - clone[key] = node[key]; } - + setOriginal(clone, node); return clone; } - // compound nodes function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): ImmediatelyInvokedFunctionExpression; function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): ImmediatelyInvokedFunctionExpression; - function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { + function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression): CallExpression { return createCallExpression( createFunctionExpression( /*modifiers*/ undefined, @@ -6409,7 +6824,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode function createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): ImmediatelyInvokedArrowFunction; function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): ImmediatelyInvokedArrowFunction; - function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { + function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression): CallExpression { return createCallExpression( createArrowFunction( /*modifiers*/ undefined, @@ -7155,7 +7570,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode return variableDeclaration; } - function update(updated: Mutable, original: T): T { + function update(updated: T, original: T): T { if (updated !== original) { setOriginal(updated, original); setTextRange(updated, original); @@ -7371,7 +7786,7 @@ function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) { const baseFactory = createBaseNodeFactory(); function makeSynthetic(node: Node) { - (node as Mutable).flags |= NodeFlags.Synthesized; + (node as NodeData).flags |= NodeFlags.Synthesized; return node; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1b972e990f7fb..3a65905485745 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -107,6 +107,7 @@ import { ElementAccessExpression, EmitFlags, EmitHost, + EmitNode, EmitResolver, EmitTextWriter, emptyArray, @@ -8217,43 +8218,1331 @@ function Signature(this: Signature, checker: TypeChecker, flags: SignatureFlags) } } -function Node(this: Mutable, kind: SyntaxKind, pos: number, end: number) { - // Note: if modifying this, be sure to update NodeObject in src/services/services.ts - this.pos = pos; - this.end = end; - this.kind = kind; - this.id = 0; - this.flags = NodeFlags.None; - this.modifierFlagsCache = ModifierFlags.None; - this.transformFlags = TransformFlags.None; - this.parent = undefined!; - this.original = undefined; - this.emitNode = undefined; -} - -function Token(this: Mutable, kind: SyntaxKind, pos: number, end: number) { - // Note: if modifying this, be sure to update TokenOrIdentifierObject in src/services/services.ts - this.pos = pos; - this.end = end; - this.kind = kind; - this.id = 0; - this.flags = NodeFlags.None; - this.transformFlags = TransformFlags.None; - this.parent = undefined!; - this.emitNode = undefined; -} +/** @internal */ +export class NodeImpl { + pos: number; + end: number; + kind: number; + id: number; + flags: NodeFlags; + transformFlags: TransformFlags; + parent: Node; + modifierFlagsCache: ModifierFlags; + escapedText: __String; + flowNode: any; + symbol: any; + __symbolTestOutputCache?: any; // For tests only + constructor(kind: SyntaxKind, pos: number, end: number) { + this.pos = pos; + this.end = end; + this.kind = kind; + this.id = 0; + this.flags = NodeFlags.None; + this.transformFlags = TransformFlags.None; + this.modifierFlagsCache = ModifierFlags.None; + this.parent = undefined!; + this.escapedText = undefined!; + this.flowNode = undefined; + this.symbol = undefined; + if (Debug.isDebugging || tracing) { + this.__symbolTestOutputCache = undefined; + } + } + data: any = undefined; + + get jsDoc() { + return this.data?.jsDoc; + } + set jsDoc(value: any) { + if (!this.data) { + this.data = { jsDoc: value }; + } + else { + this.data.jsDoc = value; + } + } + get emitNode() { + return this.data?.emitNode; + } + set emitNode(value: EmitNode) { + if (!this.data) { + this.data = { emitNode: value }; + } + else { + this.data.emitNode = value; + } + } + + get original() { + return this.data?.original; + } + set original(value: any) { + if (!this.data) { + this.data = { original: value }; + } + else { + this.data.original = value; + } + } + + get sourceText() { + return this.data?.sourceText; + } + set sourceText(value: any) { + this.data.sourceText = value; + } + get localSymbol() { + return this.data?.localSymbol; + } + set localSymbol(value: any) { + this.data.localSymbol = value; + } + + get resolvedSymbol() { + return this.data?.resolvedSymbol; + } + set resolvedSymbol(value: any) { + this.data.resolvedSymbol = value; + } + + get modifiers() { + return this.data?.modifiers; + } + set modifiers(value: any) { + this.data.modifiers = value; + } + + get name() { + return this.data?.name; + } + set name(value: any) { + this.data.name = value; + } + + get constraint() { + return this.data?.constraint; + } + set constraint(value: any) { + this.data.constraint = value; + } + + get default() { + return this.data?.default; + } + set default(value: any) { + this.data.default = value; + } + + get expression() { + return this.data?.expression; + } + set expression(value: any) { + this.data.expression = value; + } + + get typeParameters() { + return this.data?.typeParameters; + } + set typeParameters(value: any) { + this.data.typeParameters = value; + } + + get parameters() { + return this.data?.parameters; + } + set parameters(value: any) { + this.data.parameters = value; + } + + get type() { + return this.data?.type; + } + set type(value: any) { + this.data.type = value; + } + + get typeArguments() { + return this.data?.typeArguments; + } + set typeArguments(value: any) { + this.data.typeArguments = value; + } + + get questionToken() { + return this.data?.questionToken; + } + set questionToken(value: any) { + this.data.questionToken = value; + } + + get locals() { + return this.data?.locals; + } + set locals(value: any) { + this.data.locals = value; + } + + get nextContainer() { + return this.data?.nextContainer; + } + set nextContainer(value: any) { + this.data.nextContainer = value; + } + + get asteriskToken() { + return this.data?.asteriskToken; + } + set asteriskToken(value: any) { + this.data.asteriskToken = value; + } + + get exclamationToken() { + return this.data?.exclamationToken; + } + set exclamationToken(value: any) { + this.data.exclamationToken = value; + } + + get body() { + return this.data?.body; + } + set body(value: any) { + this.data.body = value; + } + + get endFlowNode() { + return this.data?.endFlowNode; + } + set endFlowNode(value: any) { + this.data.endFlowNode = value; + } + + get returnFlowNode() { + return this.data?.returnFlowNode; + } + set returnFlowNode(value: any) { + this.data.returnFlowNode = value; + } + + get equalsGreaterThanToken() { + return this.data?.equalsGreaterThanToken; + } + set equalsGreaterThanToken(value: any) { + this.data.equalsGreaterThanToken = value; + } + + get initializer() { + return this.data?.initializer; + } + set initializer(value: any) { + this.data.initializer = value; + } + + get dotDotDotToken() { + return this.data?.dotDotDotToken; + } + set dotDotDotToken(value: any) { + this.data.dotDotDotToken = value; + } + + get equalsToken() { + return this.data?.equalsToken; + } + set equalsToken(value: any) { + this.data.equalsToken = value; + } + + get objectAssignmentInitializer() { + return this.data?.objectAssignmentInitializer; + } + set objectAssignmentInitializer(value: any) { + this.data.objectAssignmentInitializer = value; + } + + get left() { + return this.data?.left; + } + set left(value: any) { + this.data.left = value; + } + + get operatorToken() { + return this.data?.operatorToken; + } + set operatorToken(value: any) { + this.data.operatorToken = value; + } + + get right() { + return this.data?.right; + } + set right(value: any) { + this.data.right = value; + } + + get multiLine() { + return this.data?.multiLine; + } + set multiLine(value: any) { + this.data.multiLine = value; + } + + get properties() { + return this.data?.properties; + } + set properties(value: any) { + this.data.properties = value; + } + + get questionDotToken() { + return this.data?.questionDotToken; + } + set questionDotToken(value: any) { + this.data.questionDotToken = value; + } + + get argumentExpression() { + return this.data?.argumentExpression; + } + set argumentExpression(value: any) { + this.data.argumentExpression = value; + } + + get heritageClauses() { + return this.data?.heritageClauses; + } + set heritageClauses(value: any) { + this.data.heritageClauses = value; + } + + get members() { + return this.data?.members; + } + set members(value: any) { + this.data.members = value; + } + + get isTypeOnly() { + return this.data?.isTypeOnly; + } + set isTypeOnly(value: any) { + this.data.isTypeOnly = value; + } + + get moduleReference() { + return this.data?.moduleReference; + } + set moduleReference(value: any) { + this.data.moduleReference = value; + } + + get exportClause() { + return this.data?.exportClause; + } + set exportClause(value: any) { + this.data.exportClause = value; + } + + get moduleSpecifier() { + return this.data?.moduleSpecifier; + } + set moduleSpecifier(value: any) { + this.data.moduleSpecifier = value; + } + + get assertClause() { + return this.data?.assertClause; + } + set assertClause(value: any) { + this.data.assertClause = value; + } + + get attributes() { + return this.data?.attributes; + } + set attributes(value: any) { + this.data.attributes = value; + } + + get isExportEquals() { + return this.data?.isExportEquals; + } + set isExportEquals(value: any) { + this.data.isExportEquals = value; + } + + get statements() { + return this.data?.statements; + } + set statements(value: any) { + this.data.statements = value; + } + + get declarationList() { + return this.data?.declarationList; + } + set declarationList(value: any) { + this.data.declarationList = value; + } + + get thenStatement() { + return this.data?.thenStatement; + } + set thenStatement(value: any) { + this.data.thenStatement = value; + } + + get elseStatement() { + return this.data?.elseStatement; + } + set elseStatement(value: any) { + this.data.elseStatement = value; + } + + get statement() { + return this.data?.statement; + } + set statement(value: any) { + this.data.statement = value; + } + + get condition() { + return this.data?.condition; + } + set condition(value: any) { + this.data.condition = value; + } + + get incrementor() { + return this.data?.incrementor; + } + set incrementor(value: any) { + this.data.incrementor = value; + } + + get awaitModifier() { + return this.data?.awaitModifier; + } + set awaitModifier(value: any) { + this.data.awaitModifier = value; + } + + get label() { + return this.data?.label; + } + set label(value: any) { + this.data.label = value; + } + + get caseBlock() { + return this.data?.caseBlock; + } + set caseBlock(value: any) { + this.data.caseBlock = value; + } + + get possiblyExhaustive() { + return this.data?.possiblyExhaustive; + } + set possiblyExhaustive(value: any) { + this.data.possiblyExhaustive = value; + } + + get tryBlock() { + return this.data?.tryBlock; + } + set tryBlock(value: any) { + this.data.tryBlock = value; + } + + get catchClause() { + return this.data?.catchClause; + } + set catchClause(value: any) { + this.data.catchClause = value; + } + + get finallyBlock() { + return this.data?.finallyBlock; + } + set finallyBlock(value: any) { + this.data.finallyBlock = value; + } + + get importClause() { + return this.data?.importClause; + } + set importClause(value: any) { + this.data.importClause = value; + } + + get fallthroughFlowNode() { + return this.data?.fallthroughFlowNode; + } + set fallthroughFlowNode(value: any) { + this.data.fallthroughFlowNode = value; + } + + get propertyName() { + return this.data?.propertyName; + } + set propertyName(value: any) { + this.data.propertyName = value; + } + + get checkType() { + return this.data?.checkType; + } + set checkType(value: any) { + this.data.checkType = value; + } + + get extendsType() { + return this.data?.extendsType; + } + set extendsType(value: any) { + this.data.extendsType = value; + } + + get trueType() { + return this.data?.trueType; + } + set trueType(value: any) { + this.data.trueType = value; + } + + get falseType() { + return this.data?.falseType; + } + set falseType(value: any) { + this.data.falseType = value; + } + + get readonlyToken() { + return this.data?.readonlyToken; + } + set readonlyToken(value: any) { + this.data.readonlyToken = value; + } + + get typeParameter() { + return this.data?.typeParameter; + } + set typeParameter(value: any) { + this.data.typeParameter = value; + } + + get nameType() { + return this.data?.nameType; + } + set nameType(value: any) { + this.data.nameType = value; + } + + get clauses() { + return this.data?.clauses; + } + set clauses(value: any) { + this.data.clauses = value; + } + + get variableDeclaration() { + return this.data?.variableDeclaration; + } + set variableDeclaration(value: any) { + this.data.variableDeclaration = value; + } + + get block() { + return this.data?.block; + } + set block(value: any) { + this.data.block = value; + } + + get typeExpression() { + return this.data?.typeExpression; + } + set typeExpression(value: any) { + this.data.typeExpression = value; + } + + get tagName() { + return this.data?.tagName; + } + set tagName(value: any) { + this.data.tagName = value; + } + + get comment() { + return this.data?.comment; + } + set comment(value: any) { + this.data.comment = value; + } + + get fullName() { + return this.data?.fullName; + } + set fullName(value: any) { + this.data.fullName = value; + } + + get endOfFileToken() { + return this.data?.endOfFileToken; + } + set endOfFileToken(value: any) { + this.data.endOfFileToken = value; + } + + get fileName() { + return this.data?.fileName; + } + set fileName(value: any) { + this.data.fileName = value; + } + + get path() { + return this.data?.path; + } + set path(value: any) { + this.data.path = value; + } + + get text() { + return this.data?.text; + } + set text(value: any) { + this.data.text = value; + } + + get resolvedPath() { + return this.data?.resolvedPath; + } + set resolvedPath(value: any) { + this.data.resolvedPath = value; + } + + get originalFileName() { + return this.data?.originalFileName; + } + set originalFileName(value: any) { + this.data.originalFileName = value; + } + + get redirectInfo() { + return this.data?.redirectInfo; + } + set redirectInfo(value: any) { + this.data.redirectInfo = value; + } + + get amdDependencies() { + return this.data?.amdDependencies; + } + set amdDependencies(value: any) { + this.data.amdDependencies = value; + } + + get moduleName() { + return this.data?.moduleName; + } + set moduleName(value: any) { + this.data.moduleName = value; + } + + get referencedFiles() { + return this.data?.referencedFiles; + } + set referencedFiles(value: any) { + this.data.referencedFiles = value; + } + + get typeReferenceDirectives() { + return this.data?.typeReferenceDirectives; + } + set typeReferenceDirectives(value: any) { + this.data.typeReferenceDirectives = value; + } + + get libReferenceDirectives() { + return this.data?.libReferenceDirectives; + } + set libReferenceDirectives(value: any) { + this.data.libReferenceDirectives = value; + } + + get languageVariant() { + return this.data?.languageVariant; + } + set languageVariant(value: any) { + this.data.languageVariant = value; + } + + get isDeclarationFile() { + return this.data?.isDeclarationFile; + } + set isDeclarationFile(value: any) { + this.data.isDeclarationFile = value; + } + + get renamedDependencies() { + return this.data?.renamedDependencies; + } + set renamedDependencies(value: any) { + this.data.renamedDependencies = value; + } + + get hasNoDefaultLib() { + return this.data?.hasNoDefaultLib; + } + set hasNoDefaultLib(value: any) { + this.data.hasNoDefaultLib = value; + } + + get languageVersion() { + return this.data?.languageVersion; + } + set languageVersion(value: any) { + this.data.languageVersion = value; + } + + get impliedNodeFormat() { + return this.data?.impliedNodeFormat; + } + set impliedNodeFormat(value: any) { + this.data.impliedNodeFormat = value; + } + + get packageJsonLocations() { + return this.data?.packageJsonLocations; + } + set packageJsonLocations(value: any) { + this.data.packageJsonLocations = value; + } + + get packageJsonScope() { + return this.data?.packageJsonScope; + } + set packageJsonScope(value: any) { + this.data.packageJsonScope = value; + } + + get scriptKind() { + return this.data?.scriptKind; + } + set scriptKind(value: any) { + this.data.scriptKind = value; + } + + get externalModuleIndicator() { + return this.data?.externalModuleIndicator; + } + set externalModuleIndicator(value: any) { + this.data.externalModuleIndicator = value; + } + + get setExternalModuleIndicator() { + return this.data?.setExternalModuleIndicator; + } + set setExternalModuleIndicator(value: any) { + this.data.setExternalModuleIndicator = value; + } -function Identifier(this: Mutable, kind: SyntaxKind, pos: number, end: number) { - // Note: if modifying this, be sure to update TokenOrIdentifierObject in src/services/services.ts - this.pos = pos; - this.end = end; - this.kind = kind; - this.id = 0; - this.flags = NodeFlags.None; - this.transformFlags = TransformFlags.None; - this.parent = undefined!; - this.original = undefined; - this.emitNode = undefined; + get commonJsModuleIndicator() { + return this.data?.commonJsModuleIndicator; + } + set commonJsModuleIndicator(value: any) { + this.data.commonJsModuleIndicator = value; + } + + get jsGlobalAugmentations() { + return this.data?.jsGlobalAugmentations; + } + set jsGlobalAugmentations(value: any) { + this.data.jsGlobalAugmentations = value; + } + + get identifiers() { + return this.data?.identifiers; + } + set identifiers(value: any) { + this.data.identifiers = value; + } + + get nodeCount() { + return this.data?.nodeCount; + } + set nodeCount(value: any) { + this.data.nodeCount = value; + } + + get identifierCount() { + return this.data?.identifierCount; + } + set identifierCount(value: any) { + this.data.identifierCount = value; + } + + get symbolCount() { + return this.data?.symbolCount; + } + set symbolCount(value: any) { + this.data.symbolCount = value; + } + + get parseDiagnostics() { + return this.data?.parseDiagnostics; + } + set parseDiagnostics(value: any) { + this.data.parseDiagnostics = value; + } + + get bindDiagnostics() { + return this.data?.bindDiagnostics; + } + set bindDiagnostics(value: any) { + this.data.bindDiagnostics = value; + } + + get bindSuggestionDiagnostics() { + return this.data?.bindSuggestionDiagnostics; + } + set bindSuggestionDiagnostics(value: any) { + this.data.bindSuggestionDiagnostics = value; + } + + get jsDocDiagnostics() { + return this.data?.jsDocDiagnostics; + } + set jsDocDiagnostics(value: any) { + this.data.jsDocDiagnostics = value; + } + + get additionalSyntacticDiagnostics() { + return this.data?.additionalSyntacticDiagnostics; + } + set additionalSyntacticDiagnostics(value: any) { + this.data.additionalSyntacticDiagnostics = value; + } + + get lineMap() { + return this.data?.lineMap; + } + set lineMap(value: any) { + this.data.lineMap = value; + } + + get classifiableNames() { + return this.data?.classifiableNames; + } + set classifiableNames(value: any) { + this.data.classifiableNames = value; + } + + get commentDirectives() { + return this.data?.commentDirectives; + } + set commentDirectives(value: any) { + this.data.commentDirectives = value; + } + + get imports() { + return this.data?.imports; + } + set imports(value: any) { + this.data.imports = value; + } + + get moduleAugmentations() { + return this.data?.moduleAugmentations; + } + set moduleAugmentations(value: any) { + this.data.moduleAugmentations = value; + } + + get patternAmbientModules() { + return this.data?.patternAmbientModules; + } + set patternAmbientModules(value: any) { + this.data.patternAmbientModules = value; + } + + get ambientModuleNames() { + return this.data?.ambientModuleNames; + } + set ambientModuleNames(value: any) { + this.data.ambientModuleNames = value; + } + + get checkJsDirective() { + return this.data?.checkJsDirective; + } + set checkJsDirective(value: any) { + this.data.checkJsDirective = value; + } + + get version() { + return this.data?.version; + } + set version(value: any) { + this.data.version = value; + } + + get pragmas() { + return this.data?.pragmas; + } + set pragmas(value: any) { + this.data.pragmas = value; + } + + get localJsxNamespace() { + return this.data?.localJsxNamespace; + } + set localJsxNamespace(value: any) { + this.data.localJsxNamespace = value; + } + + get localJsxFragmentNamespace() { + return this.data?.localJsxFragmentNamespace; + } + set localJsxFragmentNamespace(value: any) { + this.data.localJsxFragmentNamespace = value; + } + + get localJsxFactory() { + return this.data?.localJsxFactory; + } + set localJsxFactory(value: any) { + this.data.localJsxFactory = value; + } + + get localJsxFragmentFactory() { + return this.data?.localJsxFragmentFactory; + } + set localJsxFragmentFactory(value: any) { + this.data.localJsxFragmentFactory = value; + } + + get jsDocParsingMode() { + return this.data?.jsDocParsingMode; + } + set jsDocParsingMode(value: any) { + this.data.jsDocParsingMode = value; + } + + get extendedSourceFiles() { + return this.data?.extendedSourceFiles; + } + set extendedSourceFiles(value: any) { + this.data.extendedSourceFiles = value; + } + + get configFileSpecs() { + return this.data?.configFileSpecs; + } + set configFileSpecs(value: any) { + this.data.configFileSpecs = value; + } + + get keywordToken() { + return this.data?.keywordToken; + } + set keywordToken(value: any) { + this.data.keywordToken = value; + } + + get namedBindings() { + return this.data?.namedBindings; + } + set namedBindings(value: any) { + this.data.namedBindings = value; + } + + get textSourceNode() { + return this.data?.textSourceNode; + } + set textSourceNode(value: any) { + this.data.textSourceNode = value; + } + + get singleQuote() { + return this.data?.singleQuote; + } + set singleQuote(value: any) { + this.data.singleQuote = value; + } + + get isUnterminated() { + return this.data?.isUnterminated; + } + set isUnterminated(value: any) { + this.data.isUnterminated = value; + } + + get hasExtendedUnicodeEscape() { + return this.data?.hasExtendedUnicodeEscape; + } + set hasExtendedUnicodeEscape(value: any) { + this.data.hasExtendedUnicodeEscape = value; + } + + get templateFlags() { + return this.data?.templateFlags; + } + set templateFlags(value: any) { + this.data.templateFlags = value; + } + + get rawText() { + return this.data?.rawText; + } + set rawText(value: any) { + this.data.rawText = value; + } + + get numericLiteralFlags() { + return this.data?.numericLiteralFlags; + } + set numericLiteralFlags(value: any) { + this.data.numericLiteralFlags = value; + } + + get arguments() { + return this.data?.arguments; + } + set arguments(value: any) { + this.data.arguments = value; + } + + get isNameFirst() { + return this.data?.isNameFirst; + } + set isNameFirst(value: any) { + this.data.isNameFirst = value; + } + + get isBracketed() { + return this.data?.isBracketed; + } + set isBracketed(value: any) { + this.data.isBracketed = value; + } + + get jsDocPropertyTags() { + return this.data?.jsDocPropertyTags; + } + set jsDocPropertyTags(value: any) { + this.data.jsDocPropertyTags = value; + } + + get isArrayType() { + return this.data?.isArrayType; + } + set isArrayType(value: any) { + this.data.isArrayType = value; + } + + get declarations() { + return this.data?.declarations; + } + set declarations(value: any) { + this.data.declarations = value; + } + + get elements() { + return this.data?.elements; + } + set elements(value: any) { + this.data.elements = value; + } + + get isTypeOf() { + return this.data?.isTypeOf; + } + set isTypeOf(value: any) { + this.data.isTypeOf = value; + } + + get argument() { + return this.data?.argument; + } + set argument(value: any) { + this.data.argument = value; + } + + get assertions() { + return this.data?.assertions; + } + set assertions(value: any) { + this.data.assertions = value; + } + + get qualifier() { + return this.data?.qualifier; + } + set qualifier(value: any) { + this.data.qualifier = value; + } + + get typeName() { + return this.data?.typeName; + } + set typeName(value: any) { + this.data.typeName = value; + } + + get exprName() { + return this.data?.exprName; + } + set exprName(value: any) { + this.data.exprName = value; + } + + get assertsModifier() { + return this.data?.assertsModifier; + } + set assertsModifier(value: any) { + this.data.assertsModifier = value; + } + + get parameterName() { + return this.data?.parameterName; + } + set parameterName(value: any) { + this.data.parameterName = value; + } + + get elementType() { + return this.data?.elementType; + } + set elementType(value: any) { + this.data.elementType = value; + } + + get types() { + return this.data?.types; + } + set types(value: any) { + this.data.types = value; + } + + get operator() { + return this.data?.operator; + } + set operator(value: any) { + this.data.operator = value; + } + + get objectType() { + return this.data?.objectType; + } + set objectType(value: any) { + this.data.objectType = value; + } + + get indexType() { + return this.data?.indexType; + } + set indexType(value: any) { + this.data.indexType = value; + } + + get literal() { + return this.data?.literal; + } + set literal(value: any) { + this.data.literal = value; + } + + get head() { + return this.data?.head; + } + set head(value: any) { + this.data.head = value; + } + + get templateSpans() { + return this.data?.templateSpans; + } + set templateSpans(value: any) { + this.data.templateSpans = value; + } + + get postfix() { + return this.data?.postfix; + } + set postfix(value: any) { + this.data.postfix = value; + } + + get operand() { + return this.data?.operand; + } + set operand(value: any) { + this.data.operand = value; + } + + get openingElement() { + return this.data?.openingElement; + } + set openingElement(value: any) { + this.data.openingElement = value; + } + + get children() { + return this.data?.children; + } + set children(value: any) { + this.data.children = value; + } + + get closingElement() { + return this.data?.closingElement; + } + set closingElement(value: any) { + this.data.closingElement = value; + } + + get openingFragment() { + return this.data?.openingFragment; + } + set openingFragment(value: any) { + this.data.openingFragment = value; + } + + get closingFragment() { + return this.data?.closingFragment; + } + set closingFragment(value: any) { + this.data.closingFragment = value; + } + + get tag() { + return this.data?.tag; + } + set tag(value: any) { + this.data.tag = value; + } + + get template() { + return this.data?.template; + } + set template(value: any) { + this.data.template = value; + } + + get thisArg() { + return this.data?.thisArg; + } + set thisArg(value: any) { + this.data.thisArg = value; + } + + get isSpread() { + return this.data?.isSpread; + } + set isSpread(value: any) { + this.data.isSpread = value; + } + + get tupleNameSource() { + return this.data?.tupleNameSource; + } + set tupleNameSource(value: any) { + this.data.tupleNameSource = value; + } + + get whenTrue() { + return this.data?.whenTrue; + } + set whenTrue(value: any) { + this.data.whenTrue = value; + } + + get colonToken() { + return this.data?.colonToken; + } + set colonToken(value: any) { + this.data.colonToken = value; + } + + get whenFalse() { + return this.data?.whenFalse; + } + set whenFalse(value: any) { + this.data.whenFalse = value; + } + + get containsOnlyTriviaWhiteSpaces() { + return this.data?.containsOnlyTriviaWhiteSpaces; + } + set containsOnlyTriviaWhiteSpaces(value: any) { + this.data.containsOnlyTriviaWhiteSpaces = value; + } + + get namespace() { + return this.data?.namespace; + } + set namespace(value: any) { + this.data.namespace = value; + } + + get token() { + return this.data?.token; + } + set token(value: any) { + this.data.token = value; + } + + get value() { + return this.data?.value; + } + set value(value: any) { + this.data.value = value; + } + + get tags() { + return this.data?.tags; + } + set tags(value: any) { + this.data.tags = value; + } + + get class() { + return this.data?.class; + } + set class(value: any) { + this.data.class = value; + } + + get sourceFiles() { + return this.data?.sourceFiles; + } + set sourceFiles(value: any) { + this.data.sourceFiles = value; + } + + get syntheticFileReferences() { + return this.data?.syntheticFileReferences; + } + set syntheticFileReferences(value: any) { + this.data.syntheticFileReferences = value; + } + + get syntheticTypeReferences() { + return this.data?.syntheticTypeReferences; + } + set syntheticTypeReferences(value: any) { + this.data.syntheticTypeReferences = value; + } + + get syntheticLibReferences() { + return this.data?.syntheticLibReferences; + } + set syntheticLibReferences(value: any) { + this.data.syntheticLibReferences = value; + } } function SourceMapSource(this: SourceMapSource, fileName: string, text: string, skipTrivia?: (pos: number) => number) { @@ -8265,11 +9554,11 @@ function SourceMapSource(this: SourceMapSource, fileName: string, text: string, /** @internal */ export const objectAllocator: ObjectAllocator = { - getNodeConstructor: () => Node as any, - getTokenConstructor: () => Token as any, - getIdentifierConstructor: () => Identifier as any, - getPrivateIdentifierConstructor: () => Node as any, - getSourceFileConstructor: () => Node as any, + getNodeConstructor: () => NodeImpl as any, + getTokenConstructor: () => NodeImpl as any, + getIdentifierConstructor: () => NodeImpl as any, + getPrivateIdentifierConstructor: () => NodeImpl as any, + getSourceFileConstructor: () => NodeImpl as any, getSymbolConstructor: () => Symbol as any, getTypeConstructor: () => Type as any, getSignatureConstructor: () => Signature as any, diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index b049c51d5f416..5b483e79e7364 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -177,13 +177,49 @@ export function sourceFileToJSON(file: ts.Node): string { return ts.Debug.formatNodeFlags(f); } + function addSerializableFlags(o: any, n: ts.Node) { + // Clear the flags that are produced by aggregating child values. That is ephemeral + // data we don't care about in the dump. We only care what the parser set directly + // on the AST. + let flags = n.flags & ~(ts.NodeFlags.JavaScriptFile | ts.NodeFlags.HasAggregatedChildData); + if (ts.isIdentifier(n)) { + if (flags & ts.NodeFlags.IdentifierHasExtendedUnicodeEscape) { + o.hasExtendedUnicodeEscape = true; + flags &= ~ts.NodeFlags.IdentifierHasExtendedUnicodeEscape; + } + } + if (flags) { + o.flags = getNodeFlagName(flags); + } + } function serializeNode(n: ts.Node): any { const o: any = { kind: getKindName(n.kind) }; if (ts.containsParseError(n)) { o.containsParseError = true; } + let nodeData; + if (n instanceof ts.NodeImpl) { + nodeData = (n as any as ts.NodeImpl).data; + o.pos = n.pos; + o.end = n.end; + addSerializableFlags(o, n); + if (ts.isNodeKind(n.kind) || ts.isLiteralKind(n.kind)) { + o.modifierFlagsCache = n.modifierFlagsCache; + } + o.transformFlags = n.transformFlags; + if (n.kind === ts.SyntaxKind.Identifier) { + o.escapedText = n.escapedText; + } + if (n.jsDoc) { + o.jsDoc = n.jsDoc; + } + } + else { + nodeData = n; + } + if (!nodeData) return o; - for (const propertyName of Object.getOwnPropertyNames(n) as readonly (keyof ts.SourceFile | keyof ts.Identifier | keyof ts.StringLiteral)[]) { + for (const propertyName of Object.getOwnPropertyNames(nodeData) as readonly (keyof ts.SourceFile | keyof ts.Identifier | keyof ts.StringLiteral)[]) { switch (propertyName) { case "parent": case "symbol": @@ -198,29 +234,15 @@ export function sourceFileToJSON(file: ts.Node): string { case "emitNode": // Blocklist of items we never put in the baseline file. break; - + case "flags": + addSerializableFlags(o, nodeData); + break; case "hasExtendedUnicodeEscape": - if ((n as any).hasExtendedUnicodeEscape) { + if (nodeData.hasExtendedUnicodeEscape) { o.hasExtendedUnicodeEscape = true; } break; - case "flags": - // Clear the flags that are produced by aggregating child values. That is ephemeral - // data we don't care about in the dump. We only care what the parser set directly - // on the AST. - let flags = n.flags & ~(ts.NodeFlags.JavaScriptFile | ts.NodeFlags.HasAggregatedChildData); - if (ts.isIdentifier(n)) { - if (flags & ts.NodeFlags.IdentifierHasExtendedUnicodeEscape) { - o.hasExtendedUnicodeEscape = true; - flags &= ~ts.NodeFlags.IdentifierHasExtendedUnicodeEscape; - } - } - if (flags) { - o[propertyName] = getNodeFlagName(flags); - } - break; - case "parseDiagnostics": o[propertyName] = convertDiagnostics((n as any)[propertyName]); break; @@ -239,7 +261,7 @@ export function sourceFileToJSON(file: ts.Node): string { break; default: - o[propertyName] = (n as any)[propertyName]; + o[propertyName] = nodeData[propertyName]; } } @@ -319,8 +341,8 @@ function assertArrayStructuralEquals(array1: ts.NodeArray, array2: ts.N } function findChildName(parent: any, child: any) { - for (const name in parent) { - if (ts.hasProperty(parent, name) && parent[name] === child) { + for (const name in parent.data) { + if (ts.hasProperty(parent.data, name) && parent[name] === child) { return name; } } diff --git a/src/services/services.ts b/src/services/services.ts index 101fcebc91a99..555651a840b7a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -15,7 +15,6 @@ import { canIncludeBindAndCheckDiagnostics, changeCompilerHostLikeToUseCache, CharacterCodes, - CheckJsDirective, Classifications, ClassifiedSpan, ClassifiedSpan2020, @@ -61,17 +60,14 @@ import { EditorOptions, EditorSettings, ElementAccessExpression, - EmitNode, EmitTextWriter, emptyArray, emptyOptions, EndOfFileToken, - EntityName, equateValues, ExportDeclaration, Extension, extensionFromPath, - FileReference, FileTextChanges, filter, find, @@ -197,7 +193,6 @@ import { isTextWhiteSpaceLike, isThisTypeParameter, isTransientSymbol, - JSDoc, JsDoc, JSDocContainer, JSDocParsingMode, @@ -211,7 +206,6 @@ import { LanguageService, LanguageServiceHost, LanguageServiceMode, - LanguageVariant, lastOrUndefined, length, LineAndCharacter, @@ -233,6 +227,7 @@ import { Node, NodeArray, NodeFlags, + NodeImpl, noop, normalizePath, normalizeSpans, @@ -257,8 +252,6 @@ import { Path, positionIsSynthesized, PossibleProgramFileInfo, - PragmaMap, - PrivateIdentifier, Program, PropertyName, PropertySignature, @@ -301,8 +294,6 @@ import { SourceFileLike, SourceMapSource, startsWith, - Statement, - StringLiteral, StringLiteralLike, StringLiteralType, Symbol, @@ -328,14 +319,11 @@ import { timestamp, TodoComment, TodoCommentDescriptor, - Token, toPath, tracing, - TransformFlags, Type, TypeChecker, TypeFlags, - TypeNode, TypeParameter, TypePredicate, TypeReference, @@ -359,44 +347,40 @@ import * as classifier2020 from "./classifier2020.js"; /** The version of the language service API */ export const servicesVersion = "0.8"; -function createNode(kind: TKind, pos: number, end: number, parent: Node): NodeObject | TokenObject | IdentifierObject | PrivateIdentifierObject { - const node = isNodeKind(kind) ? new NodeObject(kind, pos, end) : - kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) : - kind === SyntaxKind.PrivateIdentifier ? new PrivateIdentifierObject(SyntaxKind.PrivateIdentifier, pos, end) : - new TokenObject(kind, pos, end); +function createNode(kind: TKind, pos: number, end: number, parent: Node): Node { + const node = new NodeObject(kind, pos, end); node.parent = parent; node.flags = parent.flags & NodeFlags.ContextFlags; return node; } -class NodeObject implements Node { - public kind: TKind; - public pos: number; - public end: number; - public flags: NodeFlags; - public modifierFlagsCache: ModifierFlags; - public transformFlags: TransformFlags; - public parent: Node; - public symbol!: Symbol; // Actually optional, but it was too annoying to access `node.symbol!` everywhere since in many cases we know it must be defined - public jsDoc?: JSDoc[]; - public original?: Node; - public id?: number; - public emitNode?: EmitNode; +class NodeObject extends NodeImpl implements Node { + override kind!: TKind; + + declare _declarationBrand: any; + declare _localsContainerBrand: any; + declare _primaryExpressionBrand: any; + declare _memberExpressionBrand: any; + declare _leftHandSideExpressionBrand: any; + declare _updateExpressionBrand: any; + declare _unaryExpressionBrand: any; + declare _expressionBrand: any; + declare _jsdocContainerBrand: any; + declare _flowContainerBrand: any; constructor(kind: TKind, pos: number, end: number) { - // Note: if modifying this, be sure to update Node in src/compiler/utilities.ts - this.pos = pos; - this.end = end; - this.kind = kind; - this.id = 0; - this.flags = NodeFlags.None; - this.modifierFlagsCache = ModifierFlags.None; - this.transformFlags = TransformFlags.None; - this.parent = undefined!; - this.original = undefined; - this.emitNode = undefined; + super(kind, pos, end); } + override get text(): string { + if (this.kind === SyntaxKind.Identifier || this.kind === SyntaxKind.PrivateIdentifier) { + return idText(this as any as Identifier); + } + return super.text; + } + override set text(value) { + super.text = value; + } private assertHasRealPosition(message?: string) { // eslint-disable-next-line local/debug-assert Debug.assert(!positionIsSynthesized(this.pos) && !positionIsSynthesized(this.end), message || "Node must have a real position for this operation"); @@ -458,37 +442,273 @@ class NodeObject implements Node { } public getChildren(sourceFile?: SourceFileLike): readonly Node[] { - this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine"); - return getNodeChildren(this) ?? setNodeChildren(this, createChildren(this, sourceFile)); + if (isNodeKind(this.kind)) { + this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine"); + return getNodeChildren(this) ?? setNodeChildren(this, createChildren(this, sourceFile)); + } + else { + return this.kind === SyntaxKind.EndOfFileToken ? (this as Node as EndOfFileToken).jsDoc || emptyArray : emptyArray; + } } public getFirstToken(sourceFile?: SourceFileLike): Node | undefined { - this.assertHasRealPosition(); - const children = this.getChildren(sourceFile); - if (!children.length) { + if (isNodeKind(this.kind)) { + this.assertHasRealPosition(); + const children = this.getChildren(sourceFile); + if (!children.length) { + return undefined; + } + + const child = find(children, kid => kid.kind < SyntaxKind.FirstJSDocNode || kid.kind > SyntaxKind.LastJSDocNode)!; + return child.kind < SyntaxKind.FirstNode ? + child : + child.getFirstToken(sourceFile); + } + else { return undefined; } - - const child = find(children, kid => kid.kind < SyntaxKind.FirstJSDocNode || kid.kind > SyntaxKind.LastJSDocNode)!; - return child.kind < SyntaxKind.FirstNode ? - child : - child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFileLike): Node | undefined { - this.assertHasRealPosition(); - const children = this.getChildren(sourceFile); + if (isNodeKind(this.kind)) { + this.assertHasRealPosition(); + const children = this.getChildren(sourceFile); + + const child = lastOrUndefined(children); + if (!child) { + return undefined; + } - const child = lastOrUndefined(children); - if (!child) { + return child.kind < SyntaxKind.FirstNode ? child : child.getLastToken(sourceFile); + } + else { return undefined; } - - return child.kind < SyntaxKind.FirstNode ? child : child.getLastToken(sourceFile); } public forEachChild(cbNode: (node: Node) => T, cbNodeArray?: (nodes: NodeArray) => T): T | undefined { - return forEachChild(this, cbNode, cbNodeArray); + if (isNodeKind(this.kind)) { + return forEachChild(this, cbNode, cbNodeArray); + } + else { + return undefined; + } + } + + private get namedDeclarations(): Map | undefined { + return this.data.namedDeclarations; + } + private set namedDeclarations(value: Map | undefined) { + this.data.namedDeclarations = value; + } + + public get scriptSnapshot(): IScriptSnapshot { + return this.data.scriptSnapshot; + } + public set scriptSnapshot(value: IScriptSnapshot) { + this.data.scriptSnapshot = value; + } + + public get nameTable(): Map<__String, number> | undefined { + return this.data.nameTable; + } + public set nameTable(value: Map<__String, number> | undefined) { + this.data.nameTable = value; + } + + public update(newText: string, textChangeRange: TextChangeRange): SourceFile { + Debug.assertEqual(this.kind, SyntaxKind.SourceFile); + return updateSourceFile(this as SourceFile, newText, textChangeRange); + } + + public getLineAndCharacterOfPosition(position: number): LineAndCharacter { + Debug.assertEqual(this.kind, SyntaxKind.SourceFile); + return getLineAndCharacterOfPosition(this, position); + } + + public getLineStarts(): readonly number[] { + Debug.assertEqual(this.kind, SyntaxKind.SourceFile); + return getLineStarts(this); + } + + public getPositionOfLineAndCharacter(line: number, character: number, allowEdits?: true): number { + Debug.assertEqual(this.kind, SyntaxKind.SourceFile); + return computePositionOfLineAndCharacter(getLineStarts(this), line, character, this.text, allowEdits); + } + + public getLineEndOfPosition(pos: number): number { + Debug.assertEqual(this.kind, SyntaxKind.SourceFile); + const { line } = this.getLineAndCharacterOfPosition(pos); + const lineStarts = this.getLineStarts(); + + let lastCharPos: number | undefined; + if (line + 1 >= lineStarts.length) { + lastCharPos = this.getEnd(); + } + if (!lastCharPos) { + lastCharPos = lineStarts[line + 1] - 1; + } + + const fullText = this.getFullText(); + // if the new line is "\r\n", we should return the last non-new-line-character position + return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos; + } + + public getNamedDeclarations(): Map { + Debug.assertEqual(this.kind, SyntaxKind.SourceFile); + if (!this.namedDeclarations) { + this.namedDeclarations = this.computeNamedDeclarations(); + } + + return this.namedDeclarations; + } + + private computeNamedDeclarations(): Map { + const result = createMultiMap(); + + this.forEachChild(visit); + + return result; + + function addDeclaration(declaration: Declaration) { + const name = getDeclarationName(declaration); + if (name) { + result.add(name, declaration); + } + } + + function getDeclarations(name: string) { + let declarations = result.get(name); + if (!declarations) { + result.set(name, declarations = []); + } + return declarations; + } + + function getDeclarationName(declaration: Declaration) { + const name = getNonAssignedNameOfDeclaration(declaration); + return name && (isComputedPropertyName(name) && isPropertyAccessExpression(name.expression) ? name.expression.name.text + : isPropertyName(name) ? getNameFromPropertyName(name) : undefined); + } + + function visit(node: Node): void { + switch (node.kind) { + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + const functionDeclaration = node as FunctionLikeDeclaration; + const declarationName = getDeclarationName(functionDeclaration); + + if (declarationName) { + const declarations = getDeclarations(declarationName); + const lastDeclaration = lastOrUndefined(declarations); + + // Check whether this declaration belongs to an "overload group". + if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) { + // Overwrite the last declaration if it was an overload + // and this one is an implementation. + if (functionDeclaration.body && !(lastDeclaration as FunctionLikeDeclaration).body) { + declarations[declarations.length - 1] = functionDeclaration; + } + } + else { + declarations.push(functionDeclaration); + } + } + forEachChild(node, visit); + break; + + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.ExportSpecifier: + case SyntaxKind.ImportSpecifier: + case SyntaxKind.ImportClause: + case SyntaxKind.NamespaceImport: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.TypeLiteral: + addDeclaration(node as Declaration); + forEachChild(node, visit); + break; + + case SyntaxKind.Parameter: + // Only consider parameter properties + if (!hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier)) { + break; + } + // falls through + + case SyntaxKind.VariableDeclaration: + case SyntaxKind.BindingElement: { + const decl = node as VariableDeclaration; + if (isBindingPattern(decl.name)) { + forEachChild(decl.name, visit); + break; + } + if (decl.initializer) { + visit(decl.initializer); + } + } + // falls through + case SyntaxKind.EnumMember: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + addDeclaration(node as Declaration); + break; + + case SyntaxKind.ExportDeclaration: + // Handle named exports case e.g.: + // export {a, b as B} from "mod"; + const exportDeclaration = node as ExportDeclaration; + if (exportDeclaration.exportClause) { + if (isNamedExports(exportDeclaration.exportClause)) { + forEach(exportDeclaration.exportClause.elements, visit); + } + else { + visit(exportDeclaration.exportClause.name); + } + } + break; + + case SyntaxKind.ImportDeclaration: + const importClause = (node as ImportDeclaration).importClause; + if (importClause) { + // Handle default import case e.g.: + // import d from "mod"; + if (importClause.name) { + addDeclaration(importClause.name); + } + + // Handle named bindings in imports e.g.: + // import * as NS from "mod"; + // import {a, b as B} from "mod"; + if (importClause.namedBindings) { + if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { + addDeclaration(importClause.namedBindings); + } + else { + forEach(importClause.namedBindings.elements, visit); + } + } + } + break; + + case SyntaxKind.BinaryExpression: + if (getAssignmentDeclarationKind(node as BinaryExpression) !== AssignmentDeclarationKind.None) { + addDeclaration(node as BinaryExpression); + } + // falls through + + default: + forEachChild(node, visit); + } + } } } @@ -541,114 +761,25 @@ function addSyntheticNodes(nodes: Node[], pos: number, end: number, parent: Node } nodes.push(createNode(token, pos, textPos, parent)); } - pos = textPos; - if (token === SyntaxKind.EndOfFileToken) { - break; - } - } -} - -function createSyntaxList(nodes: NodeArray, parent: Node): Node { - const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, parent) as any as SyntaxList; - const children: Node[] = []; - let pos = nodes.pos; - for (const node of nodes) { - addSyntheticNodes(children, pos, node.pos, parent); - children.push(node); - pos = node.end; - } - addSyntheticNodes(children, pos, nodes.end, parent); - setNodeChildren(list, children); - return list; -} - -class TokenOrIdentifierObject implements Node { - public kind: TKind; - public pos: number; - public end: number; - public flags: NodeFlags; - public modifierFlagsCache!: ModifierFlags; - public transformFlags: TransformFlags; - public parent: Node; - public symbol!: Symbol; - public jsDocComments?: JSDoc[]; - public id?: number; - public emitNode?: EmitNode | undefined; - - constructor(kind: TKind, pos: number, end: number) { - // Note: if modifying this, be sure to update Token and Identifier in src/compiler/utilities.ts - this.pos = pos; - this.end = end; - this.kind = kind; - this.id = 0; - this.flags = NodeFlags.None; - this.transformFlags = TransformFlags.None; - this.parent = undefined!; - this.emitNode = undefined; - } - - public getSourceFile(): SourceFile { - return getSourceFileOfNode(this); - } - - public getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number { - return getTokenPosOfNode(this, sourceFile, includeJsDocComment); - } - - public getFullStart(): number { - return this.pos; - } - - public getEnd(): number { - return this.end; - } - - public getWidth(sourceFile?: SourceFile): number { - return this.getEnd() - this.getStart(sourceFile); - } - - public getFullWidth(): number { - return this.end - this.pos; - } - - public getLeadingTriviaWidth(sourceFile?: SourceFile): number { - return this.getStart(sourceFile) - this.pos; - } - - public getFullText(sourceFile?: SourceFile): string { - return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); - } - - public getText(sourceFile?: SourceFile): string { - if (!sourceFile) { - sourceFile = this.getSourceFile(); - } - return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd()); - } - - public getChildCount(): number { - return this.getChildren().length; - } - - public getChildAt(index: number): Node { - return this.getChildren()[index]; - } - - public getChildren(): Node[] { - return this.kind === SyntaxKind.EndOfFileToken ? (this as Node as EndOfFileToken).jsDoc || emptyArray : emptyArray; - } - - public getFirstToken(): Node | undefined { - return undefined; - } - - public getLastToken(): Node | undefined { - return undefined; + pos = textPos; + if (token === SyntaxKind.EndOfFileToken) { + break; + } } +} - public forEachChild(): T | undefined { - return undefined; +function createSyntaxList(nodes: NodeArray, parent: Node): Node { + const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, parent) as any as SyntaxList; + const children: Node[] = []; + let pos = nodes.pos; + for (const node of nodes) { + addSyntheticNodes(children, pos, node.pos, parent); + children.push(node); + pos = node.end; } + addSyntheticNodes(children, pos, nodes.end, parent); + setNodeChildren(list, children); + return list; } class SymbolObject implements Symbol { @@ -785,50 +916,6 @@ class SymbolObject implements Symbol { } } -class TokenObject extends TokenOrIdentifierObject implements Token { - constructor(kind: TKind, pos: number, end: number) { - super(kind, pos, end); - } -} - -class IdentifierObject extends TokenOrIdentifierObject implements Identifier { - public escapedText!: __String; - declare _primaryExpressionBrand: any; - declare _memberExpressionBrand: any; - declare _leftHandSideExpressionBrand: any; - declare _updateExpressionBrand: any; - declare _unaryExpressionBrand: any; - declare _expressionBrand: any; - declare _declarationBrand: any; - declare _jsdocContainerBrand: any; - declare _flowContainerBrand: any; - typeArguments!: NodeArray; - constructor(kind: SyntaxKind.Identifier, pos: number, end: number) { - super(kind, pos, end); - } - - get text(): string { - return idText(this); - } -} - -class PrivateIdentifierObject extends TokenOrIdentifierObject implements PrivateIdentifier { - public escapedText!: __String; - declare _primaryExpressionBrand: any; - declare _memberExpressionBrand: any; - declare _leftHandSideExpressionBrand: any; - declare _updateExpressionBrand: any; - declare _unaryExpressionBrand: any; - declare _expressionBrand: any; - constructor(kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) { - super(kind, pos, end); - } - - get text(): string { - return idText(this); - } -} - class TypeObject implements Type { checker: TypeChecker; flags: TypeFlags; @@ -1051,250 +1138,6 @@ function findBaseOfDeclaration(checker: TypeChecker, declaration: Declaration }); } -class SourceFileObject extends NodeObject implements SourceFile { - declare _declarationBrand: any; - declare _localsContainerBrand: any; - public fileName!: string; - public path!: Path; - public resolvedPath!: Path; - public originalFileName!: string; - public text!: string; - public scriptSnapshot!: IScriptSnapshot; - public lineMap!: readonly number[]; - - public statements!: NodeArray; - public endOfFileToken!: Token; - - public amdDependencies!: { name: string; path: string; }[]; - public moduleName!: string; - public referencedFiles!: FileReference[]; - public typeReferenceDirectives!: FileReference[]; - public libReferenceDirectives!: FileReference[]; - - public syntacticDiagnostics!: DiagnosticWithLocation[]; - public parseDiagnostics!: DiagnosticWithLocation[]; - public bindDiagnostics!: DiagnosticWithLocation[]; - public bindSuggestionDiagnostics?: DiagnosticWithLocation[]; - - public isDeclarationFile!: boolean; - public isDefaultLib!: boolean; - public hasNoDefaultLib!: boolean; - public externalModuleIndicator!: Node; // The first node that causes this file to be an external module - public commonJsModuleIndicator!: Node; // The first node that causes this file to be a CommonJS module - public nodeCount!: number; - public identifierCount!: number; - public symbolCount!: number; - public version!: string; - public scriptKind!: ScriptKind; - public languageVersion!: ScriptTarget; - public languageVariant!: LanguageVariant; - public identifiers!: Map; - public nameTable: Map<__String, number> | undefined; - public imports!: readonly StringLiteralLike[]; - public moduleAugmentations!: StringLiteral[]; - private namedDeclarations: Map | undefined; - public ambientModuleNames!: string[]; - public checkJsDirective: CheckJsDirective | undefined; - public errorExpectations: TextRange[] | undefined; - public possiblyContainDynamicImport?: boolean; - public pragmas!: PragmaMap; - public localJsxFactory: EntityName | undefined; - public localJsxNamespace: __String | undefined; - - constructor(kind: SyntaxKind.SourceFile, pos: number, end: number) { - super(kind, pos, end); - } - - public update(newText: string, textChangeRange: TextChangeRange): SourceFile { - return updateSourceFile(this, newText, textChangeRange); - } - - public getLineAndCharacterOfPosition(position: number): LineAndCharacter { - return getLineAndCharacterOfPosition(this, position); - } - - public getLineStarts(): readonly number[] { - return getLineStarts(this); - } - - public getPositionOfLineAndCharacter(line: number, character: number, allowEdits?: true): number { - return computePositionOfLineAndCharacter(getLineStarts(this), line, character, this.text, allowEdits); - } - - public getLineEndOfPosition(pos: number): number { - const { line } = this.getLineAndCharacterOfPosition(pos); - const lineStarts = this.getLineStarts(); - - let lastCharPos: number | undefined; - if (line + 1 >= lineStarts.length) { - lastCharPos = this.getEnd(); - } - if (!lastCharPos) { - lastCharPos = lineStarts[line + 1] - 1; - } - - const fullText = this.getFullText(); - // if the new line is "\r\n", we should return the last non-new-line-character position - return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos; - } - - public getNamedDeclarations(): Map { - if (!this.namedDeclarations) { - this.namedDeclarations = this.computeNamedDeclarations(); - } - - return this.namedDeclarations; - } - - private computeNamedDeclarations(): Map { - const result = createMultiMap(); - - this.forEachChild(visit); - - return result; - - function addDeclaration(declaration: Declaration) { - const name = getDeclarationName(declaration); - if (name) { - result.add(name, declaration); - } - } - - function getDeclarations(name: string) { - let declarations = result.get(name); - if (!declarations) { - result.set(name, declarations = []); - } - return declarations; - } - - function getDeclarationName(declaration: Declaration) { - const name = getNonAssignedNameOfDeclaration(declaration); - return name && (isComputedPropertyName(name) && isPropertyAccessExpression(name.expression) ? name.expression.name.text - : isPropertyName(name) ? getNameFromPropertyName(name) : undefined); - } - - function visit(node: Node): void { - switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - const functionDeclaration = node as FunctionLikeDeclaration; - const declarationName = getDeclarationName(functionDeclaration); - - if (declarationName) { - const declarations = getDeclarations(declarationName); - const lastDeclaration = lastOrUndefined(declarations); - - // Check whether this declaration belongs to an "overload group". - if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) { - // Overwrite the last declaration if it was an overload - // and this one is an implementation. - if (functionDeclaration.body && !(lastDeclaration as FunctionLikeDeclaration).body) { - declarations[declarations.length - 1] = functionDeclaration; - } - } - else { - declarations.push(functionDeclaration); - } - } - forEachChild(node, visit); - break; - - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceImport: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.TypeLiteral: - addDeclaration(node as Declaration); - forEachChild(node, visit); - break; - - case SyntaxKind.Parameter: - // Only consider parameter properties - if (!hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier)) { - break; - } - // falls through - - case SyntaxKind.VariableDeclaration: - case SyntaxKind.BindingElement: { - const decl = node as VariableDeclaration; - if (isBindingPattern(decl.name)) { - forEachChild(decl.name, visit); - break; - } - if (decl.initializer) { - visit(decl.initializer); - } - } - // falls through - case SyntaxKind.EnumMember: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - addDeclaration(node as Declaration); - break; - - case SyntaxKind.ExportDeclaration: - // Handle named exports case e.g.: - // export {a, b as B} from "mod"; - const exportDeclaration = node as ExportDeclaration; - if (exportDeclaration.exportClause) { - if (isNamedExports(exportDeclaration.exportClause)) { - forEach(exportDeclaration.exportClause.elements, visit); - } - else { - visit(exportDeclaration.exportClause.name); - } - } - break; - - case SyntaxKind.ImportDeclaration: - const importClause = (node as ImportDeclaration).importClause; - if (importClause) { - // Handle default import case e.g.: - // import d from "mod"; - if (importClause.name) { - addDeclaration(importClause.name); - } - - // Handle named bindings in imports e.g.: - // import * as NS from "mod"; - // import {a, b as B} from "mod"; - if (importClause.namedBindings) { - if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { - addDeclaration(importClause.namedBindings); - } - else { - forEach(importClause.namedBindings.elements, visit); - } - } - } - break; - - case SyntaxKind.BinaryExpression: - if (getAssignmentDeclarationKind(node as BinaryExpression) !== AssignmentDeclarationKind.None) { - addDeclaration(node as BinaryExpression); - } - // falls through - - default: - forEachChild(node, visit); - } - } - } -} - class SourceMapSourceObject implements SourceMapSource { fileName: string; text: string; @@ -1316,11 +1159,11 @@ class SourceMapSourceObject implements SourceMapSource { function getServicesObjectAllocator(): ObjectAllocator { return { getNodeConstructor: () => NodeObject, - getTokenConstructor: () => TokenObject, + getTokenConstructor: () => NodeObject, - getIdentifierConstructor: () => IdentifierObject, - getPrivateIdentifierConstructor: () => PrivateIdentifierObject, - getSourceFileConstructor: () => SourceFileObject, + getIdentifierConstructor: () => NodeObject, + getPrivateIdentifierConstructor: () => NodeObject, + getSourceFileConstructor: () => NodeObject, getSymbolConstructor: () => SymbolObject, getTypeConstructor: () => TypeObject, getSignatureConstructor: () => SignatureObject, diff --git a/tests/baselines/reference/skipJSDocParsing/deprecated-ParseForTypeErrors-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/deprecated-ParseForTypeErrors-file.ts.diff index c50da716b91b9..943b25dcb2fb8 100644 --- a/tests/baselines/reference/skipJSDocParsing/deprecated-ParseForTypeErrors-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/deprecated-ParseForTypeErrors-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeErrors -@@ -8,9 +8,8 @@ +@@ -8,44 +8,10 @@ "0": { "kind": "FunctionDeclaration", "pos": 0, @@ -9,14 +9,6 @@ - "flags": "Deprecated", "modifierFlagsCache": 0, "transformFlags": 4194304, - "name": { - "kind": "Identifier", -@@ -39,42 +38,9 @@ - "hasTrailingComma": false, - "transformFlags": 0 - }, - "multiLine": false -- }, - "jsDoc": [ - { - "kind": "JSDoc", @@ -49,12 +41,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "1": { - "kind": "ExpressionStatement", - "pos": 46, +- ], + "name": { + "kind": "Identifier", + "pos": 28, + "end": 41, @@ -230,6 +196,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/deprecated-ParseForTypeInfo-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/deprecated-ParseForTypeInfo-file.ts.diff index f63d4526fd75c..cd158dbfbc1be 100644 --- a/tests/baselines/reference/skipJSDocParsing/deprecated-ParseForTypeInfo-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/deprecated-ParseForTypeInfo-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeInfo -@@ -8,9 +8,8 @@ +@@ -8,44 +8,10 @@ "0": { "kind": "FunctionDeclaration", "pos": 0, @@ -9,14 +9,6 @@ - "flags": "Deprecated", "modifierFlagsCache": 0, "transformFlags": 4194304, - "name": { - "kind": "Identifier", -@@ -39,42 +38,9 @@ - "hasTrailingComma": false, - "transformFlags": 0 - }, - "multiLine": false -- }, - "jsDoc": [ - { - "kind": "JSDoc", @@ -49,13 +41,12 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "1": { - "kind": "ExpressionStatement", - "pos": 46, -@@ -106,9 +72,8 @@ +- ], + "name": { + "kind": "Identifier", + "pos": 28, + "end": 41, +@@ -106,45 +72,10 @@ "2": { "kind": "FunctionDeclaration", "pos": 61, @@ -63,14 +54,6 @@ - "flags": "Deprecated", "modifierFlagsCache": 0, "transformFlags": 4194304, - "name": { - "kind": "Identifier", -@@ -137,43 +102,9 @@ - "hasTrailingComma": false, - "transformFlags": 0 - }, - "multiLine": false -- }, - "jsDoc": [ - { - "kind": "JSDoc", @@ -104,12 +87,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "3": { - "kind": "ExpressionStatement", - "pos": 135, +- ], + "name": { + "kind": "Identifier", + "pos": 116, + "end": 130, @@ -230,6 +161,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/deprecated-ParseNone-file.js.diff b/tests/baselines/reference/skipJSDocParsing/deprecated-ParseNone-file.js.diff index 567ff8973d13a..d123442d7230d 100644 --- a/tests/baselines/reference/skipJSDocParsing/deprecated-ParseNone-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/deprecated-ParseNone-file.js.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseNone -@@ -8,9 +8,8 @@ +@@ -8,44 +8,10 @@ "0": { "kind": "FunctionDeclaration", "pos": 0, @@ -9,14 +9,6 @@ - "flags": "Deprecated", "modifierFlagsCache": 0, "transformFlags": 4194304, - "name": { - "kind": "Identifier", -@@ -39,42 +38,9 @@ - "hasTrailingComma": false, - "transformFlags": 0 - }, - "multiLine": false -- }, - "jsDoc": [ - { - "kind": "JSDoc", @@ -49,13 +41,12 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "1": { - "kind": "ExpressionStatement", - "pos": 46, -@@ -106,9 +72,8 @@ +- ], + "name": { + "kind": "Identifier", + "pos": 28, + "end": 41, +@@ -106,45 +72,10 @@ "2": { "kind": "FunctionDeclaration", "pos": 61, @@ -63,14 +54,6 @@ - "flags": "Deprecated", "modifierFlagsCache": 0, "transformFlags": 4194304, - "name": { - "kind": "Identifier", -@@ -137,43 +102,9 @@ - "hasTrailingComma": false, - "transformFlags": 0 - }, - "multiLine": false -- }, - "jsDoc": [ - { - "kind": "JSDoc", @@ -104,12 +87,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "3": { - "kind": "ExpressionStatement", - "pos": 135, +- ], + "name": { + "kind": "Identifier", + "pos": 116, + "end": 130, @@ -230,7 +161,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/deprecated-ParseNone-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/deprecated-ParseNone-file.ts.diff index 852412d8420f3..80ff7ac9429be 100644 --- a/tests/baselines/reference/skipJSDocParsing/deprecated-ParseNone-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/deprecated-ParseNone-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseNone -@@ -8,9 +8,8 @@ +@@ -8,44 +8,10 @@ "0": { "kind": "FunctionDeclaration", "pos": 0, @@ -9,14 +9,6 @@ - "flags": "Deprecated", "modifierFlagsCache": 0, "transformFlags": 4194304, - "name": { - "kind": "Identifier", -@@ -39,42 +38,9 @@ - "hasTrailingComma": false, - "transformFlags": 0 - }, - "multiLine": false -- }, - "jsDoc": [ - { - "kind": "JSDoc", @@ -49,13 +41,12 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "1": { - "kind": "ExpressionStatement", - "pos": 46, -@@ -106,9 +72,8 @@ +- ], + "name": { + "kind": "Identifier", + "pos": 28, + "end": 41, +@@ -106,45 +72,10 @@ "2": { "kind": "FunctionDeclaration", "pos": 61, @@ -63,14 +54,6 @@ - "flags": "Deprecated", "modifierFlagsCache": 0, "transformFlags": 4194304, - "name": { - "kind": "Identifier", -@@ -137,43 +102,9 @@ - "hasTrailingComma": false, - "transformFlags": 0 - }, - "multiLine": false -- }, - "jsDoc": [ - { - "kind": "JSDoc", @@ -104,12 +87,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "3": { - "kind": "ExpressionStatement", - "pos": 135, +- ], + "name": { + "kind": "Identifier", + "pos": 116, + "end": 130, @@ -230,6 +161,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff index 0c2bff5a4677e..b527b2d016da9 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff @@ -1,12 +1,11 @@ =================================================================== --- default +++ ParseForTypeInfo -@@ -88,52 +88,9 @@ - "pos": 69, - "end": 69, - "hasTrailingComma": false, - "transformFlags": 0 -- }, +@@ -62,51 +62,8 @@ + "pos": 30, + "end": 70, + "modifierFlagsCache": 0, + "transformFlags": 1, - "jsDoc": [ - { - "kind": "JSDoc", @@ -49,12 +48,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "length": 2, - "pos": 0, - "end": 70, +- ], + "modifiers": { + "0": { + "kind": "ExportKeyword", + "pos": 30, @@ -214,6 +171,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff index 3a1028bb08254..a6e9f5f2ded40 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff @@ -1,12 +1,11 @@ =================================================================== --- default +++ ParseNone -@@ -88,52 +88,9 @@ - "pos": 69, - "end": 69, - "hasTrailingComma": false, - "transformFlags": 0 -- }, +@@ -62,51 +62,8 @@ + "pos": 30, + "end": 70, + "modifierFlagsCache": 0, + "transformFlags": 1, - "jsDoc": [ - { - "kind": "JSDoc", @@ -49,12 +48,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "length": 2, - "pos": 0, - "end": 70, +- ], + "modifiers": { + "0": { + "kind": "ExportKeyword", + "pos": 30, @@ -214,7 +171,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff index 41135dc2495ba..38b49375f3292 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff @@ -1,12 +1,11 @@ =================================================================== --- default +++ ParseNone -@@ -88,52 +88,9 @@ - "pos": 69, - "end": 69, - "hasTrailingComma": false, - "transformFlags": 0 -- }, +@@ -62,51 +62,8 @@ + "pos": 30, + "end": 70, + "modifierFlagsCache": 0, + "transformFlags": 1, - "jsDoc": [ - { - "kind": "JSDoc", @@ -49,12 +48,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "length": 2, - "pos": 0, - "end": 70, +- ], + "modifiers": { + "0": { + "kind": "ExportKeyword", + "pos": 30, @@ -214,6 +171,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/see-ParseForTypeInfo-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/see-ParseForTypeInfo-file.ts.diff index 277a3fbe56a55..710ad9ae82741 100644 --- a/tests/baselines/reference/skipJSDocParsing/see-ParseForTypeInfo-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/see-ParseForTypeInfo-file.ts.diff @@ -1,12 +1,11 @@ =================================================================== --- default +++ ParseForTypeInfo -@@ -38,235 +38,9 @@ - "end": 108, - "hasTrailingComma": false, - "transformFlags": 0 - } -- }, +@@ -10,234 +10,8 @@ + "pos": 0, + "end": 109, + "modifierFlagsCache": 0, + "transformFlags": 4457472, - "jsDoc": [ - { - "kind": "JSDoc", @@ -232,12 +231,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "length": 1, - "pos": 0, - "end": 109, +- ], + "declarationList": { + "kind": "VariableDeclarationList", + "pos": 0, + "end": 108, @@ -295,6 +69,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/see-ParseNone-file.js.diff b/tests/baselines/reference/skipJSDocParsing/see-ParseNone-file.js.diff index cae5537d772c6..e15e60dfa305d 100644 --- a/tests/baselines/reference/skipJSDocParsing/see-ParseNone-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/see-ParseNone-file.js.diff @@ -1,12 +1,11 @@ =================================================================== --- default +++ ParseNone -@@ -38,235 +38,9 @@ - "end": 108, - "hasTrailingComma": false, - "transformFlags": 0 - } -- }, +@@ -10,234 +10,8 @@ + "pos": 0, + "end": 109, + "modifierFlagsCache": 0, + "transformFlags": 4457472, - "jsDoc": [ - { - "kind": "JSDoc", @@ -232,12 +231,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "length": 1, - "pos": 0, - "end": 109, +- ], + "declarationList": { + "kind": "VariableDeclarationList", + "pos": 0, + "end": 108, @@ -295,7 +69,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], diff --git a/tests/baselines/reference/skipJSDocParsing/see-ParseNone-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/see-ParseNone-file.ts.diff index d89f8511e680a..0c60572516f2d 100644 --- a/tests/baselines/reference/skipJSDocParsing/see-ParseNone-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/see-ParseNone-file.ts.diff @@ -1,12 +1,11 @@ =================================================================== --- default +++ ParseNone -@@ -38,235 +38,9 @@ - "end": 108, - "hasTrailingComma": false, - "transformFlags": 0 - } -- }, +@@ -10,234 +10,8 @@ + "pos": 0, + "end": 109, + "modifierFlagsCache": 0, + "transformFlags": 4457472, - "jsDoc": [ - { - "kind": "JSDoc", @@ -232,12 +231,11 @@ - "transformFlags": 0 - } - } -- ] -+ } - }, - "length": 1, - "pos": 0, - "end": 109, +- ], + "declarationList": { + "kind": "VariableDeclarationList", + "pos": 0, + "end": 108, @@ -295,6 +69,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [],