1import { 2 addRange, AnnotationDeclaration, AnnotationElement, AnnotationPropertyDeclaration, append, appendIfUnique, ArrayBindingElement, 3 ArrayBindingPattern, ArrayLiteralExpression, ArrayTypeNode, 4 ArrowFunction, AsExpression, AssertClause, AssertEntry, AssertionKey, AssertsKeyword, AssignmentPattern, 5 AsteriskToken, AwaitExpression, AwaitKeyword, BaseNodeFactory, BigIntLiteral, BinaryExpression, BinaryOperator, 6 BinaryOperatorToken, BindingElement, BindingName, BindingPattern, Block, BooleanLiteral, BreakStatement, BuildInfo, 7 Bundle, BundleFileHasNoDefaultLib, BundleFileInfo, BundleFileReference, BundleFileSectionKind, CallBinding, 8 CallChain, CallExpression, CallSignatureDeclaration, canHaveModifiers, CaseBlock, CaseClause, CaseOrDefaultClause, 9 cast, CatchClause, ClassDeclaration, ClassElement, ClassExpression, ClassLikeDeclaration, 10 ClassStaticBlockDeclaration, ColonToken, CommaListExpression, ComputedPropertyName, ConciseBody, 11 ConditionalExpression, ConditionalTypeNode, ConstructorDeclaration, ConstructorTypeNode, 12 ConstructSignatureDeclaration, ContinueStatement, createBaseNodeFactory, createNodeConverters, 13 createParenthesizerRules, createScanner, Debug, DebuggerStatement, Declaration, DeclarationName, Decorator, 14 DefaultClause, DeleteExpression, DoStatement, DotDotDotToken, ElementAccessChain, ElementAccessExpression, 15 EmitFlags, EmitNode, emptyArray, EmptyStatement, EndOfDeclarationMarker, EndOfFileToken, EntityName, 16 EnumDeclaration, EnumMember, EqualsGreaterThanToken, escapeLeadingUnderscores, EtsComponentExpression, every, 17 ExclamationToken, ExportAssignment, ExportDeclaration, ExportSpecifier, Expression, ExpressionStatement, 18 ExpressionWithTypeArguments, ExternalModuleReference, FalseLiteral, FileReference, findUseStrictPrologue, forEach, 19 ForInitializer, ForInStatement, formatGeneratedName, ForOfStatement, ForStatement, FunctionDeclaration, 20 FunctionExpression, FunctionLikeDeclaration, FunctionTypeNode, GeneratedIdentifier, GeneratedIdentifierFlags, 21 GeneratedNamePart, GetAccessorDeclaration, getAllUnscopedEmitHelpers, getBuildInfo, getCommentRange, 22 getElementsOfBindingOrAssignmentPattern, getEmitFlags, getJSDocTypeAliasName, getLineAndCharacterOfPosition, 23 getNameOfDeclaration, getNodeId, getSourceMapRange, getSyntheticLeadingComments, getSyntheticTrailingComments, 24 getTargetOfBindingOrAssignmentElement, getTextOfIdentifierOrLiteral, hasInvalidEscape, HasModifiers, hasProperty, 25 hasStaticModifier, hasSyntacticModifier, HeritageClause, Identifier, idText, IfStatement, ImportClause, 26 ImportDeclaration, ImportEqualsDeclaration, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, 27 IndexedAccessTypeNode, IndexSignatureDeclaration, InferTypeNode, InputFiles, InterfaceDeclaration, 28 IntersectionTypeNode, isAnnotationDeclaration, isArray, isArrayLiteralExpression, isArrowFunction, isAssignmentPattern, isBinaryExpression, 29 isCallChain, isClassDeclaration, isClassExpression, isCommaListExpression, isCommaToken, isComputedPropertyName, 30 isConstructorDeclaration, isConstructorTypeNode, isCustomPrologue, isElementAccessChain, isElementAccessExpression, 31 isEnumDeclaration, isExclamationToken, isExportAssignment, isExportDeclaration, isExternalModuleReference, 32 isFunctionDeclaration, isFunctionExpression, isGeneratedIdentifier, isGetAccessorDeclaration, isHoistedFunction, 33 isHoistedVariableStatement, isIdentifier, isImportDeclaration, isImportEqualsDeclaration, isImportKeyword, 34 isIndexSignatureDeclaration, isInterfaceDeclaration, isLabeledStatement, isLocalName, 35 isLogicalOrCoalescingAssignmentOperator, isMemberName, isMethodDeclaration, isMethodSignature, isModuleDeclaration, 36 isNamedDeclaration, isNodeArray, isNodeKind, isNonNullChain, isNotEmittedStatement, isObjectLiteralExpression, 37 isOmittedExpression, isOuterExpression, isParameter, isParenthesizedExpression, isParseTreeNode, 38 isPrivateIdentifier, isPrologueDirective, isPropertyAccessChain, isPropertyAccessExpression, isPropertyDeclaration, 39 isPropertyName, isPropertySignature, isQuestionToken, isSetAccessorDeclaration, isSourceFile, isStatement, 40 isStatementOrBlock, isString, isStringLiteral, isStructDeclaration, isSuperKeyword, isSuperProperty, 41 isThisIdentifier, isTypeAliasDeclaration, isTypeParameterDeclaration, isVariableDeclaration, isVariableStatement, 42 JSDoc, JSDocAllType, JSDocAugmentsTag, JSDocAuthorTag, JSDocCallbackTag, JSDocClassTag, JSDocComment, 43 JSDocDeprecatedTag, JSDocEnumTag, JSDocFunctionType, JSDocImplementsTag, JSDocLink, JSDocLinkCode, JSDocLinkPlain, 44 JSDocMemberName, JSDocNamepathType, JSDocNameReference, JSDocNamespaceDeclaration, JSDocNonNullableType, 45 JSDocNullableType, JSDocOptionalType, JSDocOverrideTag, JSDocParameterTag, JSDocPrivateTag, JSDocPropertyLikeTag, 46 JSDocPropertyTag, JSDocProtectedTag, JSDocPublicTag, JSDocReadonlyTag, JSDocReturnTag, JSDocSeeTag, JSDocSignature, 47 JSDocTag, JSDocTemplateTag, JSDocText, JSDocThisTag, JSDocType, JSDocTypedefTag, JSDocTypeExpression, 48 JSDocTypeLiteral, JSDocTypeTag, JSDocUnknownTag, JSDocUnknownType, JSDocVariadicType, JsxAttribute, 49 JsxAttributeLike, JsxAttributes, JsxAttributeValue, JsxChild, JsxClosingElement, JsxClosingFragment, JsxElement, 50 JsxExpression, JsxFragment, JsxOpeningElement, JsxOpeningFragment, JsxSelfClosingElement, JsxSpreadAttribute, 51 JsxTagNameExpression, JsxText, KeywordSyntaxKind, KeywordToken, KeywordTypeNode, KeywordTypeSyntaxKind, 52 LabeledStatement, LanguageVariant, lastOrUndefined, LeftHandSideExpression, LiteralToken, LiteralTypeNode, map, Map, 53 MappedTypeNode, memoize, memoizeOne, MergeDeclarationMarker, MetaProperty, MethodDeclaration, 54 MethodSignature, MinusToken, MissingDeclaration, Modifier, ModifierFlags, ModifierLike, modifiersToFlags, 55 ModifierSyntaxKind, ModifierToken, ModuleBlock, ModuleBody, ModuleDeclaration, ModuleKind, ModuleName, 56 ModuleReference, Mutable, MutableNodeArray, NamedDeclaration, NamedExportBindings, NamedExports, 57 NamedImportBindings, NamedImports, NamedTupleMember, NamespaceExport, NamespaceExportDeclaration, NamespaceImport, 58 NewExpression, Node, NodeArray, NodeFactory, NodeFlags, nodeIsSynthesized, NonNullChain, NonNullExpression, 59 NoSubstitutionTemplateLiteral, NotEmittedStatement, NullLiteral, nullNodeConverters, nullParenthesizerRules, 60 NumericLiteral, objectAllocator, ObjectBindingPattern, ObjectLiteralElementLike, ObjectLiteralExpression, 61 OmittedExpression, OptionalTypeNode, OuterExpression, OuterExpressionKinds, ParameterDeclaration, 62 ParenthesizedExpression, ParenthesizedTypeNode, parseNodeFactory, PartiallyEmittedExpression, PlusToken, 63 PostfixUnaryExpression, PostfixUnaryOperator, PrefixUnaryExpression, PrefixUnaryOperator, PrimaryExpression, 64 PrivateIdentifier, PrologueDirective, PropertyAccessChain, PropertyAccessExpression, PropertyAssignment, 65 PropertyDeclaration, PropertyDescriptorAttributes, PropertyName, PropertyNameLiteral, PropertySignature, 66 PseudoBigInt, pseudoBigIntToString, PunctuationSyntaxKind, PunctuationToken, Push, QualifiedName, QuestionDotToken, 67 QuestionToken, ReadonlyKeyword, reduceLeft, RegularExpressionLiteral, RestTypeNode, ReturnStatement, returnTrue, 68 sameFlatMap, SatisfiesExpression, Scanner, ScriptTarget, SemicolonClassElement, SetAccessorDeclaration, 69 setEachParent, setEmitFlags, setParent, setTextRange, setTextRangePosEnd, setTextRangePosWidth, 70 ShorthandPropertyAssignment, SignatureDeclarationBase, singleOrUndefined, skipOuterExpressions, skipParentheses, 71 some, SourceFile, SourceMapSource, SpreadAssignment, SpreadElement, startOnNewLine, startsWith, Statement, 72 StringLiteral, StringLiteralLike, stringToToken, StructDeclaration, SuperExpression, SwitchStatement, SyntaxKind, 73 SyntaxList, SyntheticExpression, SyntheticReferenceExpression, TaggedTemplateExpression, TemplateExpression, 74 TemplateHead, TemplateLiteral, TemplateLiteralLikeNode, TemplateLiteralToken, TemplateLiteralTypeNode, 75 TemplateLiteralTypeSpan, TemplateMiddle, TemplateSpan, TemplateTail, TextRange, ThisExpression, ThisTypeNode, 76 ThrowStatement, Token, TokenFlags, TransformFlags, TrueLiteral, TryStatement, TupleTypeNode, Type, 77 TypeAliasDeclaration, TypeAssertion, TypeElement, TypeLiteralNode, TypeNode, TypeOfExpression, TypeOfTag, 78 TypeOperatorNode, TypeParameterDeclaration, TypePredicateNode, TypeQueryNode, TypeReferenceNode, 79 UnionOrIntersectionTypeNode, UnionTypeNode, UnparsedNode, UnparsedPrepend, UnparsedPrologue, UnparsedSource, 80 UnparsedSourceText, UnparsedSyntheticReference, UnparsedTextLike, UnscopedEmitHelper, VariableDeclaration, 81 VariableDeclarationList, VariableStatement, visitNode, VisitResult, VoidExpression, WhileStatement, WithStatement, 82 YieldExpression, 83} from "../_namespaces/ts"; 84 85let nextAutoGenerateId = 0; 86 87/** @internal */ 88export const enum NodeFactoryFlags { 89 None = 0, 90 // Disables the parenthesizer rules for the factory. 91 NoParenthesizerRules = 1 << 0, 92 // Disables the node converters for the factory. 93 NoNodeConverters = 1 << 1, 94 // Ensures new `PropertyAccessExpression` nodes are created with the `NoIndentation` emit flag set. 95 NoIndentationOnFreshPropertyAccess = 1 << 2, 96 // Do not set an `original` pointer when updating a node. 97 NoOriginalNode = 1 << 3, 98} 99 100const nodeFactoryPatchers: ((factory: NodeFactory) => void)[] = []; 101 102/** @internal */ 103export function addNodeFactoryPatcher(fn: (factory: NodeFactory) => void) { 104 nodeFactoryPatchers.push(fn); 105} 106 107/** 108 * Creates a `NodeFactory` that can be used to create and update a syntax tree. 109 * @param flags Flags that control factory behavior. 110 * @param baseFactory A `BaseNodeFactory` used to create the base `Node` objects. 111 * 112 * @internal 113 */ 114export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNodeFactory): NodeFactory { 115 const update = flags & NodeFactoryFlags.NoOriginalNode ? updateWithoutOriginal : updateWithOriginal; 116 117 // Lazily load the parenthesizer, node converters, and some factory methods until they are used. 118 const parenthesizerRules = memoize(() => flags & NodeFactoryFlags.NoParenthesizerRules ? nullParenthesizerRules : createParenthesizerRules(factory)); 119 const converters = memoize(() => flags & NodeFactoryFlags.NoNodeConverters ? nullNodeConverters : createNodeConverters(factory)); 120 121 // lazy initializaton of common operator factories 122 const getBinaryCreateFunction = memoizeOne((operator: BinaryOperator) => (left: Expression, right: Expression) => createBinaryExpression(left, operator, right)); 123 const getPrefixUnaryCreateFunction = memoizeOne((operator: PrefixUnaryOperator) => (operand: Expression) => createPrefixUnaryExpression(operator, operand)); 124 const getPostfixUnaryCreateFunction = memoizeOne((operator: PostfixUnaryOperator) => (operand: Expression) => createPostfixUnaryExpression(operand, operator)); 125 const getJSDocPrimaryTypeCreateFunction = memoizeOne(<T extends JSDocType>(kind: T["kind"]) => () => createJSDocPrimaryTypeWorker(kind)); 126 const getJSDocUnaryTypeCreateFunction = memoizeOne(<T extends JSDocType & { readonly type: TypeNode | undefined; }>(kind: T["kind"]) => (type: T["type"]) => createJSDocUnaryTypeWorker<T>(kind, type)); 127 const getJSDocUnaryTypeUpdateFunction = memoizeOne(<T extends JSDocType & { readonly type: TypeNode | undefined; }>(kind: T["kind"]) => (node: T, type: T["type"]) => updateJSDocUnaryTypeWorker<T>(kind, node, type)); 128 const getJSDocPrePostfixUnaryTypeCreateFunction = memoizeOne(<T extends JSDocType & { readonly type: TypeNode | undefined; readonly postfix: boolean; }>(kind: T["kind"]) => (type: T["type"], postfix?: boolean) => createJSDocPrePostfixUnaryTypeWorker<T>(kind, type, postfix)); 129 const getJSDocPrePostfixUnaryTypeUpdateFunction = memoizeOne(<T extends JSDocType & { readonly type: TypeNode | undefined; readonly postfix: boolean; }>(kind: T["kind"]) => (node: T, type: T["type"]) => updateJSDocPrePostfixUnaryTypeWorker<T>(kind, node, type)); 130 const getJSDocSimpleTagCreateFunction = memoizeOne(<T extends JSDocTag>(kind: T["kind"]) => (tagName: Identifier | undefined, comment?: NodeArray<JSDocComment>) => createJSDocSimpleTagWorker(kind, tagName, comment)); 131 const getJSDocSimpleTagUpdateFunction = memoizeOne(<T extends JSDocTag>(kind: T["kind"]) => (node: T, tagName: Identifier | undefined, comment?: NodeArray<JSDocComment>) => updateJSDocSimpleTagWorker(kind, node, tagName, comment)); 132 const getJSDocTypeLikeTagCreateFunction = memoizeOne(<T extends JSDocTag & { typeExpression?: JSDocTypeExpression }>(kind: T["kind"]) => (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: NodeArray<JSDocComment>) => createJSDocTypeLikeTagWorker(kind, tagName, typeExpression, comment)); 133 const getJSDocTypeLikeTagUpdateFunction = memoizeOne(<T extends JSDocTag & { typeExpression?: JSDocTypeExpression }>(kind: T["kind"]) => (node: T, tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: NodeArray<JSDocComment>) => updateJSDocTypeLikeTagWorker(kind, node, tagName, typeExpression, comment)); 134 135 const factory: NodeFactory = { 136 get parenthesizer() { return parenthesizerRules(); }, 137 get converters() { return converters(); }, 138 baseFactory, 139 flags, 140 createNodeArray, 141 createNumericLiteral, 142 createBigIntLiteral, 143 createStringLiteral, 144 createStringLiteralFromNode, 145 createRegularExpressionLiteral, 146 createLiteralLikeNode, 147 createIdentifier, 148 updateIdentifier, 149 createTempVariable, 150 createLoopVariable, 151 createUniqueName, 152 getGeneratedNameForNode, 153 createPrivateIdentifier, 154 createUniquePrivateName, 155 getGeneratedPrivateNameForNode, 156 createToken, 157 createSuper, 158 createThis, 159 createNull, 160 createTrue, 161 createFalse, 162 createModifier, 163 createModifiersFromModifierFlags, 164 createQualifiedName, 165 updateQualifiedName, 166 createComputedPropertyName, 167 updateComputedPropertyName, 168 createTypeParameterDeclaration, 169 updateTypeParameterDeclaration, 170 createParameterDeclaration, 171 updateParameterDeclaration, 172 createDecorator, 173 updateDecorator, 174 createPropertySignature, 175 updatePropertySignature, 176 createPropertyDeclaration, 177 updatePropertyDeclaration, 178 createAnnotationPropertyDeclaration, 179 updateAnnotationPropertyDeclaration, 180 createMethodSignature, 181 updateMethodSignature, 182 createMethodDeclaration, 183 updateMethodDeclaration, 184 createConstructorDeclaration, 185 updateConstructorDeclaration, 186 createGetAccessorDeclaration, 187 updateGetAccessorDeclaration, 188 createSetAccessorDeclaration, 189 updateSetAccessorDeclaration, 190 createCallSignature, 191 updateCallSignature, 192 createConstructSignature, 193 updateConstructSignature, 194 createIndexSignature, 195 updateIndexSignature, 196 createClassStaticBlockDeclaration, 197 updateClassStaticBlockDeclaration, 198 createTemplateLiteralTypeSpan, 199 updateTemplateLiteralTypeSpan, 200 createKeywordTypeNode, 201 createTypePredicateNode, 202 updateTypePredicateNode, 203 createTypeReferenceNode, 204 updateTypeReferenceNode, 205 createFunctionTypeNode, 206 updateFunctionTypeNode, 207 createConstructorTypeNode, 208 updateConstructorTypeNode, 209 createTypeQueryNode, 210 updateTypeQueryNode, 211 createTypeLiteralNode, 212 updateTypeLiteralNode, 213 createArrayTypeNode, 214 updateArrayTypeNode, 215 createTupleTypeNode, 216 updateTupleTypeNode, 217 createNamedTupleMember, 218 updateNamedTupleMember, 219 createOptionalTypeNode, 220 updateOptionalTypeNode, 221 createRestTypeNode, 222 updateRestTypeNode, 223 createUnionTypeNode, 224 updateUnionTypeNode, 225 createIntersectionTypeNode, 226 updateIntersectionTypeNode, 227 createConditionalTypeNode, 228 updateConditionalTypeNode, 229 createInferTypeNode, 230 updateInferTypeNode, 231 createImportTypeNode, 232 updateImportTypeNode, 233 createParenthesizedType, 234 updateParenthesizedType, 235 createThisTypeNode, 236 createTypeOperatorNode, 237 updateTypeOperatorNode, 238 createIndexedAccessTypeNode, 239 updateIndexedAccessTypeNode, 240 createMappedTypeNode, 241 updateMappedTypeNode, 242 createLiteralTypeNode, 243 updateLiteralTypeNode, 244 createTemplateLiteralType, 245 updateTemplateLiteralType, 246 createObjectBindingPattern, 247 updateObjectBindingPattern, 248 createArrayBindingPattern, 249 updateArrayBindingPattern, 250 createBindingElement, 251 updateBindingElement, 252 createArrayLiteralExpression, 253 updateArrayLiteralExpression, 254 createObjectLiteralExpression, 255 updateObjectLiteralExpression, 256 createPropertyAccessExpression: flags & NodeFactoryFlags.NoIndentationOnFreshPropertyAccess ? 257 (expression: Expression, name: string) => setEmitFlags(createPropertyAccessExpression(expression, name), EmitFlags.NoIndentation) : 258 createPropertyAccessExpression, 259 updatePropertyAccessExpression, 260 createPropertyAccessChain: flags & NodeFactoryFlags.NoIndentationOnFreshPropertyAccess ? 261 (expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string) => setEmitFlags(createPropertyAccessChain(expression, questionDotToken, name), EmitFlags.NoIndentation) : 262 createPropertyAccessChain, 263 updatePropertyAccessChain, 264 createElementAccessExpression, 265 updateElementAccessExpression, 266 createElementAccessChain, 267 updateElementAccessChain, 268 createCallExpression, 269 updateCallExpression, 270 createCallChain, 271 updateCallChain, 272 createNewExpression, 273 updateNewExpression, 274 createTaggedTemplateExpression, 275 updateTaggedTemplateExpression, 276 createTypeAssertion, 277 updateTypeAssertion, 278 createParenthesizedExpression, 279 updateParenthesizedExpression, 280 createFunctionExpression, 281 updateFunctionExpression, 282 createEtsComponentExpression, 283 updateEtsComponentExpression, 284 createArrowFunction, 285 updateArrowFunction, 286 createDeleteExpression, 287 updateDeleteExpression, 288 createTypeOfExpression, 289 updateTypeOfExpression, 290 createVoidExpression, 291 updateVoidExpression, 292 createAwaitExpression, 293 updateAwaitExpression, 294 createPrefixUnaryExpression, 295 updatePrefixUnaryExpression, 296 createPostfixUnaryExpression, 297 updatePostfixUnaryExpression, 298 createBinaryExpression, 299 updateBinaryExpression, 300 createConditionalExpression, 301 updateConditionalExpression, 302 createTemplateExpression, 303 updateTemplateExpression, 304 createTemplateHead, 305 createTemplateMiddle, 306 createTemplateTail, 307 createNoSubstitutionTemplateLiteral, 308 createTemplateLiteralLikeNode, 309 createYieldExpression, 310 updateYieldExpression, 311 createSpreadElement, 312 updateSpreadElement, 313 createClassExpression, 314 updateClassExpression, 315 createOmittedExpression, 316 createExpressionWithTypeArguments, 317 updateExpressionWithTypeArguments, 318 createAsExpression, 319 updateAsExpression, 320 createNonNullExpression, 321 updateNonNullExpression, 322 createSatisfiesExpression, 323 updateSatisfiesExpression, 324 createNonNullChain, 325 updateNonNullChain, 326 createMetaProperty, 327 updateMetaProperty, 328 createTemplateSpan, 329 updateTemplateSpan, 330 createSemicolonClassElement, 331 createBlock, 332 updateBlock, 333 createVariableStatement, 334 updateVariableStatement, 335 createEmptyStatement, 336 createExpressionStatement, 337 updateExpressionStatement, 338 createIfStatement, 339 updateIfStatement, 340 createDoStatement, 341 updateDoStatement, 342 createWhileStatement, 343 updateWhileStatement, 344 createForStatement, 345 updateForStatement, 346 createForInStatement, 347 updateForInStatement, 348 createForOfStatement, 349 updateForOfStatement, 350 createContinueStatement, 351 updateContinueStatement, 352 createBreakStatement, 353 updateBreakStatement, 354 createReturnStatement, 355 updateReturnStatement, 356 createWithStatement, 357 updateWithStatement, 358 createSwitchStatement, 359 updateSwitchStatement, 360 createLabeledStatement, 361 updateLabeledStatement, 362 createThrowStatement, 363 updateThrowStatement, 364 createTryStatement, 365 updateTryStatement, 366 createDebuggerStatement, 367 createVariableDeclaration, 368 updateVariableDeclaration, 369 createVariableDeclarationList, 370 updateVariableDeclarationList, 371 createFunctionDeclaration, 372 updateFunctionDeclaration, 373 createClassDeclaration, 374 updateClassDeclaration, 375 createStructDeclaration, 376 updateStructDeclaration, 377 createAnnotationDeclaration, 378 updateAnnotationDeclaration, 379 createInterfaceDeclaration, 380 updateInterfaceDeclaration, 381 createTypeAliasDeclaration, 382 updateTypeAliasDeclaration, 383 createEnumDeclaration, 384 updateEnumDeclaration, 385 createModuleDeclaration, 386 updateModuleDeclaration, 387 createModuleBlock, 388 updateModuleBlock, 389 createCaseBlock, 390 updateCaseBlock, 391 createNamespaceExportDeclaration, 392 updateNamespaceExportDeclaration, 393 createImportEqualsDeclaration, 394 updateImportEqualsDeclaration, 395 createImportDeclaration, 396 updateImportDeclaration, 397 createImportClause, 398 updateImportClause, 399 createAssertClause, 400 updateAssertClause, 401 createAssertEntry, 402 updateAssertEntry, 403 createImportTypeAssertionContainer, 404 updateImportTypeAssertionContainer, 405 createNamespaceImport, 406 updateNamespaceImport, 407 createNamespaceExport, 408 updateNamespaceExport, 409 createNamedImports, 410 updateNamedImports, 411 createImportSpecifier, 412 updateImportSpecifier, 413 createExportAssignment, 414 updateExportAssignment, 415 createExportDeclaration, 416 updateExportDeclaration, 417 createNamedExports, 418 updateNamedExports, 419 createExportSpecifier, 420 updateExportSpecifier, 421 createMissingDeclaration, 422 createExternalModuleReference, 423 updateExternalModuleReference, 424 // lazily load factory members for JSDoc types with similar structure 425 get createJSDocAllType() { return getJSDocPrimaryTypeCreateFunction<JSDocAllType>(SyntaxKind.JSDocAllType); }, 426 get createJSDocUnknownType() { return getJSDocPrimaryTypeCreateFunction<JSDocUnknownType>(SyntaxKind.JSDocUnknownType); }, 427 get createJSDocNonNullableType() { return getJSDocPrePostfixUnaryTypeCreateFunction<JSDocNonNullableType>(SyntaxKind.JSDocNonNullableType); }, 428 get updateJSDocNonNullableType() { return getJSDocPrePostfixUnaryTypeUpdateFunction<JSDocNonNullableType>(SyntaxKind.JSDocNonNullableType); }, 429 get createJSDocNullableType() { return getJSDocPrePostfixUnaryTypeCreateFunction<JSDocNullableType>(SyntaxKind.JSDocNullableType); }, 430 get updateJSDocNullableType() { return getJSDocPrePostfixUnaryTypeUpdateFunction<JSDocNullableType>(SyntaxKind.JSDocNullableType); }, 431 get createJSDocOptionalType() { return getJSDocUnaryTypeCreateFunction<JSDocOptionalType>(SyntaxKind.JSDocOptionalType); }, 432 get updateJSDocOptionalType() { return getJSDocUnaryTypeUpdateFunction<JSDocOptionalType>(SyntaxKind.JSDocOptionalType); }, 433 get createJSDocVariadicType() { return getJSDocUnaryTypeCreateFunction<JSDocVariadicType>(SyntaxKind.JSDocVariadicType); }, 434 get updateJSDocVariadicType() { return getJSDocUnaryTypeUpdateFunction<JSDocVariadicType>(SyntaxKind.JSDocVariadicType); }, 435 get createJSDocNamepathType() { return getJSDocUnaryTypeCreateFunction<JSDocNamepathType>(SyntaxKind.JSDocNamepathType); }, 436 get updateJSDocNamepathType() { return getJSDocUnaryTypeUpdateFunction<JSDocNamepathType>(SyntaxKind.JSDocNamepathType); }, 437 createJSDocFunctionType, 438 updateJSDocFunctionType, 439 createJSDocTypeLiteral, 440 updateJSDocTypeLiteral, 441 createJSDocTypeExpression, 442 updateJSDocTypeExpression, 443 createJSDocSignature, 444 updateJSDocSignature, 445 createJSDocTemplateTag, 446 updateJSDocTemplateTag, 447 createJSDocTypedefTag, 448 updateJSDocTypedefTag, 449 createJSDocParameterTag, 450 updateJSDocParameterTag, 451 createJSDocPropertyTag, 452 updateJSDocPropertyTag, 453 createJSDocCallbackTag, 454 updateJSDocCallbackTag, 455 createJSDocAugmentsTag, 456 updateJSDocAugmentsTag, 457 createJSDocImplementsTag, 458 updateJSDocImplementsTag, 459 createJSDocSeeTag, 460 updateJSDocSeeTag, 461 createJSDocNameReference, 462 updateJSDocNameReference, 463 createJSDocMemberName, 464 updateJSDocMemberName, 465 createJSDocLink, 466 updateJSDocLink, 467 createJSDocLinkCode, 468 updateJSDocLinkCode, 469 createJSDocLinkPlain, 470 updateJSDocLinkPlain, 471 // lazily load factory members for JSDoc tags with similar structure 472 get createJSDocTypeTag() { return getJSDocTypeLikeTagCreateFunction<JSDocTypeTag>(SyntaxKind.JSDocTypeTag); }, 473 get updateJSDocTypeTag() { return getJSDocTypeLikeTagUpdateFunction<JSDocTypeTag>(SyntaxKind.JSDocTypeTag); }, 474 get createJSDocReturnTag() { return getJSDocTypeLikeTagCreateFunction<JSDocReturnTag>(SyntaxKind.JSDocReturnTag); }, 475 get updateJSDocReturnTag() { return getJSDocTypeLikeTagUpdateFunction<JSDocReturnTag>(SyntaxKind.JSDocReturnTag); }, 476 get createJSDocThisTag() { return getJSDocTypeLikeTagCreateFunction<JSDocThisTag>(SyntaxKind.JSDocThisTag); }, 477 get updateJSDocThisTag() { return getJSDocTypeLikeTagUpdateFunction<JSDocThisTag>(SyntaxKind.JSDocThisTag); }, 478 get createJSDocEnumTag() { return getJSDocTypeLikeTagCreateFunction<JSDocEnumTag>(SyntaxKind.JSDocEnumTag); }, 479 get updateJSDocEnumTag() { return getJSDocTypeLikeTagUpdateFunction<JSDocEnumTag>(SyntaxKind.JSDocEnumTag); }, 480 get createJSDocAuthorTag() { return getJSDocSimpleTagCreateFunction<JSDocAuthorTag>(SyntaxKind.JSDocAuthorTag); }, 481 get updateJSDocAuthorTag() { return getJSDocSimpleTagUpdateFunction<JSDocAuthorTag>(SyntaxKind.JSDocAuthorTag); }, 482 get createJSDocClassTag() { return getJSDocSimpleTagCreateFunction<JSDocClassTag>(SyntaxKind.JSDocClassTag); }, 483 get updateJSDocClassTag() { return getJSDocSimpleTagUpdateFunction<JSDocClassTag>(SyntaxKind.JSDocClassTag); }, 484 get createJSDocPublicTag() { return getJSDocSimpleTagCreateFunction<JSDocPublicTag>(SyntaxKind.JSDocPublicTag); }, 485 get updateJSDocPublicTag() { return getJSDocSimpleTagUpdateFunction<JSDocPublicTag>(SyntaxKind.JSDocPublicTag); }, 486 get createJSDocPrivateTag() { return getJSDocSimpleTagCreateFunction<JSDocPrivateTag>(SyntaxKind.JSDocPrivateTag); }, 487 get updateJSDocPrivateTag() { return getJSDocSimpleTagUpdateFunction<JSDocPrivateTag>(SyntaxKind.JSDocPrivateTag); }, 488 get createJSDocProtectedTag() { return getJSDocSimpleTagCreateFunction<JSDocProtectedTag>(SyntaxKind.JSDocProtectedTag); }, 489 get updateJSDocProtectedTag() { return getJSDocSimpleTagUpdateFunction<JSDocProtectedTag>(SyntaxKind.JSDocProtectedTag); }, 490 get createJSDocReadonlyTag() { return getJSDocSimpleTagCreateFunction<JSDocReadonlyTag>(SyntaxKind.JSDocReadonlyTag); }, 491 get updateJSDocReadonlyTag() { return getJSDocSimpleTagUpdateFunction<JSDocReadonlyTag>(SyntaxKind.JSDocReadonlyTag); }, 492 get createJSDocOverrideTag() { return getJSDocSimpleTagCreateFunction<JSDocOverrideTag>(SyntaxKind.JSDocOverrideTag); }, 493 get updateJSDocOverrideTag() { return getJSDocSimpleTagUpdateFunction<JSDocOverrideTag>(SyntaxKind.JSDocOverrideTag); }, 494 get createJSDocDeprecatedTag() { return getJSDocSimpleTagCreateFunction<JSDocDeprecatedTag>(SyntaxKind.JSDocDeprecatedTag); }, 495 get updateJSDocDeprecatedTag() { return getJSDocSimpleTagUpdateFunction<JSDocDeprecatedTag>(SyntaxKind.JSDocDeprecatedTag); }, 496 createJSDocUnknownTag, 497 updateJSDocUnknownTag, 498 createJSDocText, 499 updateJSDocText, 500 createJSDocComment, 501 updateJSDocComment, 502 createJsxElement, 503 updateJsxElement, 504 createJsxSelfClosingElement, 505 updateJsxSelfClosingElement, 506 createJsxOpeningElement, 507 updateJsxOpeningElement, 508 createJsxClosingElement, 509 updateJsxClosingElement, 510 createJsxFragment, 511 createJsxText, 512 updateJsxText, 513 createJsxOpeningFragment, 514 createJsxJsxClosingFragment, 515 updateJsxFragment, 516 createJsxAttribute, 517 updateJsxAttribute, 518 createJsxAttributes, 519 updateJsxAttributes, 520 createJsxSpreadAttribute, 521 updateJsxSpreadAttribute, 522 createJsxExpression, 523 updateJsxExpression, 524 createCaseClause, 525 updateCaseClause, 526 createDefaultClause, 527 updateDefaultClause, 528 createHeritageClause, 529 updateHeritageClause, 530 createCatchClause, 531 updateCatchClause, 532 createPropertyAssignment, 533 updatePropertyAssignment, 534 createShorthandPropertyAssignment, 535 updateShorthandPropertyAssignment, 536 createSpreadAssignment, 537 updateSpreadAssignment, 538 createEnumMember, 539 updateEnumMember, 540 createSourceFile, 541 updateSourceFile, 542 createBundle, 543 updateBundle, 544 createUnparsedSource, 545 createUnparsedPrologue, 546 createUnparsedPrepend, 547 createUnparsedTextLike, 548 createUnparsedSyntheticReference, 549 createInputFiles, 550 createSyntheticExpression, 551 createSyntaxList, 552 createNotEmittedStatement, 553 createPartiallyEmittedExpression, 554 updatePartiallyEmittedExpression, 555 createCommaListExpression, 556 updateCommaListExpression, 557 createEndOfDeclarationMarker, 558 createMergeDeclarationMarker, 559 createSyntheticReferenceExpression, 560 updateSyntheticReferenceExpression, 561 cloneNode, 562 563 // Lazily load factory methods for common operator factories and utilities 564 get createComma() { return getBinaryCreateFunction(SyntaxKind.CommaToken); }, 565 get createAssignment() { return getBinaryCreateFunction(SyntaxKind.EqualsToken) as NodeFactory["createAssignment"]; }, 566 get createLogicalOr() { return getBinaryCreateFunction(SyntaxKind.BarBarToken); }, 567 get createLogicalAnd() { return getBinaryCreateFunction(SyntaxKind.AmpersandAmpersandToken); }, 568 get createBitwiseOr() { return getBinaryCreateFunction(SyntaxKind.BarToken); }, 569 get createBitwiseXor() { return getBinaryCreateFunction(SyntaxKind.CaretToken); }, 570 get createBitwiseAnd() { return getBinaryCreateFunction(SyntaxKind.AmpersandToken); }, 571 get createStrictEquality() { return getBinaryCreateFunction(SyntaxKind.EqualsEqualsEqualsToken); }, 572 get createStrictInequality() { return getBinaryCreateFunction(SyntaxKind.ExclamationEqualsEqualsToken); }, 573 get createEquality() { return getBinaryCreateFunction(SyntaxKind.EqualsEqualsToken); }, 574 get createInequality() { return getBinaryCreateFunction(SyntaxKind.ExclamationEqualsToken); }, 575 get createLessThan() { return getBinaryCreateFunction(SyntaxKind.LessThanToken); }, 576 get createLessThanEquals() { return getBinaryCreateFunction(SyntaxKind.LessThanEqualsToken); }, 577 get createGreaterThan() { return getBinaryCreateFunction(SyntaxKind.GreaterThanToken); }, 578 get createGreaterThanEquals() { return getBinaryCreateFunction(SyntaxKind.GreaterThanEqualsToken); }, 579 get createLeftShift() { return getBinaryCreateFunction(SyntaxKind.LessThanLessThanToken); }, 580 get createRightShift() { return getBinaryCreateFunction(SyntaxKind.GreaterThanGreaterThanToken); }, 581 get createUnsignedRightShift() { return getBinaryCreateFunction(SyntaxKind.GreaterThanGreaterThanGreaterThanToken); }, 582 get createAdd() { return getBinaryCreateFunction(SyntaxKind.PlusToken); }, 583 get createSubtract() { return getBinaryCreateFunction(SyntaxKind.MinusToken); }, 584 get createMultiply() { return getBinaryCreateFunction(SyntaxKind.AsteriskToken); }, 585 get createDivide() { return getBinaryCreateFunction(SyntaxKind.SlashToken); }, 586 get createModulo() { return getBinaryCreateFunction(SyntaxKind.PercentToken); }, 587 get createExponent() { return getBinaryCreateFunction(SyntaxKind.AsteriskAsteriskToken); }, 588 get createPrefixPlus() { return getPrefixUnaryCreateFunction(SyntaxKind.PlusToken); }, 589 get createPrefixMinus() { return getPrefixUnaryCreateFunction(SyntaxKind.MinusToken); }, 590 get createPrefixIncrement() { return getPrefixUnaryCreateFunction(SyntaxKind.PlusPlusToken); }, 591 get createPrefixDecrement() { return getPrefixUnaryCreateFunction(SyntaxKind.MinusMinusToken); }, 592 get createBitwiseNot() { return getPrefixUnaryCreateFunction(SyntaxKind.TildeToken); }, 593 get createLogicalNot() { return getPrefixUnaryCreateFunction(SyntaxKind.ExclamationToken); }, 594 get createPostfixIncrement() { return getPostfixUnaryCreateFunction(SyntaxKind.PlusPlusToken); }, 595 get createPostfixDecrement() { return getPostfixUnaryCreateFunction(SyntaxKind.MinusMinusToken); }, 596 597 // Compound nodes 598 createImmediatelyInvokedFunctionExpression, 599 createImmediatelyInvokedArrowFunction, 600 createVoidZero, 601 createExportDefault, 602 createExternalModuleExport, 603 createTypeCheck, 604 createMethodCall, 605 createGlobalMethodCall, 606 createFunctionBindCall, 607 createFunctionCallCall, 608 createFunctionApplyCall, 609 createArraySliceCall, 610 createArrayConcatCall, 611 createObjectDefinePropertyCall, 612 createReflectGetCall, 613 createReflectSetCall, 614 createPropertyDescriptor, 615 createCallBinding, 616 createAssignmentTargetWrapper, 617 618 // Utilities 619 inlineExpressions, 620 getInternalName, 621 getLocalName, 622 getExportName, 623 getDeclarationName, 624 getNamespaceMemberName, 625 getExternalModuleOrNamespaceExportName, 626 restoreOuterExpressions, 627 restoreEnclosingLabel, 628 createUseStrictPrologue, 629 copyPrologue, 630 copyStandardPrologue, 631 copyCustomPrologue, 632 ensureUseStrict, 633 liftToBlock, 634 mergeLexicalEnvironment, 635 updateModifiers, 636 }; 637 638 forEach(nodeFactoryPatchers, fn => fn(factory)); 639 640 return factory; 641 642 // @api 643 function createNodeArray<T extends Node>(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray<T> { 644 if (elements === undefined || elements === emptyArray) { 645 elements = []; 646 } 647 else if (isNodeArray(elements)) { 648 if (hasTrailingComma === undefined || elements.hasTrailingComma === hasTrailingComma) { 649 // Ensure the transform flags have been aggregated for this NodeArray 650 if (elements.transformFlags === undefined) { 651 aggregateChildrenFlags(elements as MutableNodeArray<T>); 652 } 653 Debug.attachNodeArrayDebugInfo(elements); 654 return elements; 655 } 656 657 // This *was* a `NodeArray`, but the `hasTrailingComma` option differs. Recreate the 658 // array with the same elements, text range, and transform flags but with the updated 659 // value for `hasTrailingComma` 660 const array = elements.slice() as MutableNodeArray<T>; 661 array.pos = elements.pos; 662 array.end = elements.end; 663 array.hasTrailingComma = hasTrailingComma; 664 array.transformFlags = elements.transformFlags; 665 Debug.attachNodeArrayDebugInfo(array); 666 return array; 667 } 668 669 // Since the element list of a node array is typically created by starting with an empty array and 670 // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for 671 // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation. 672 const length = elements.length; 673 const array = (length >= 1 && length <= 4 ? elements.slice() : elements) as MutableNodeArray<T>; 674 setTextRangePosEnd(array, -1, -1); 675 array.hasTrailingComma = !!hasTrailingComma; 676 aggregateChildrenFlags(array); 677 Debug.attachNodeArrayDebugInfo(array); 678 return array; 679 } 680 681 function createBaseNode<T extends Node>(kind: T["kind"]) { 682 return baseFactory.createBaseNode(kind) as Mutable<T>; 683 } 684 685 function createBaseDeclaration<T extends Declaration | VariableStatement | ImportDeclaration>( 686 kind: T["kind"], 687 ) { 688 const node = createBaseNode(kind); 689 // NOTE: The following properties are commonly set by the binder and are added here to 690 // ensure declarations have a stable shape. 691 node.symbol = undefined!; // initialized by binder 692 node.localSymbol = undefined; // initialized by binder 693 node.locals = undefined; // initialized by binder 694 node.nextContainer = undefined; // initialized by binder 695 return node; 696 } 697 698 function createBaseNamedDeclaration<T extends NamedDeclaration>( 699 kind: T["kind"], 700 modifiers: readonly ModifierLike[] | undefined, 701 name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined 702 ) { 703 const node = createBaseDeclaration(kind); 704 name = asName(name); 705 node.name = name; 706 if (canHaveModifiers(node)) { 707 (node as Mutable<HasModifiers>).modifiers = asNodeArray(modifiers); 708 (node as Mutable<HasModifiers>).transformFlags |= propagateChildrenFlags(node.modifiers); 709 // node.decorators = filter(node.modifiers, isDecorator); 710 } 711 712 // The PropertyName of a member is allowed to be `await`. 713 // We don't need to exclude `await` for type signatures since types 714 // don't propagate child flags. 715 if (name) { 716 switch (node.kind) { 717 case SyntaxKind.MethodDeclaration: 718 case SyntaxKind.GetAccessor: 719 case SyntaxKind.SetAccessor: 720 case SyntaxKind.PropertyDeclaration: 721 case SyntaxKind.AnnotationPropertyDeclaration: 722 case SyntaxKind.PropertyAssignment: 723 if (isIdentifier(name)) { 724 node.transformFlags |= propagateIdentifierNameFlags(name); 725 break; 726 } 727 // fall through 728 default: 729 node.transformFlags |= propagateChildFlags(name); 730 break; 731 } 732 } 733 return node; 734 } 735 736 function createBaseGenericNamedDeclaration<T extends NamedDeclaration & { typeParameters?: NodeArray<TypeParameterDeclaration> }>( 737 kind: T["kind"], 738 modifiers: readonly ModifierLike[] | undefined, 739 name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, 740 typeParameters: readonly TypeParameterDeclaration[] | undefined 741 ) { 742 const node = createBaseNamedDeclaration( 743 kind, 744 modifiers, 745 name 746 ); 747 node.typeParameters = asNodeArray(typeParameters); 748 node.transformFlags |= propagateChildrenFlags(node.typeParameters); 749 if (typeParameters) node.transformFlags |= TransformFlags.ContainsTypeScript; 750 return node; 751 } 752 753 function createBaseSignatureDeclaration<T extends SignatureDeclarationBase>( 754 kind: T["kind"], 755 modifiers: readonly ModifierLike[] | undefined, 756 name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, 757 typeParameters: readonly TypeParameterDeclaration[] | undefined, 758 parameters: readonly ParameterDeclaration[] | undefined, 759 type: TypeNode | undefined 760 ) { 761 const node = createBaseGenericNamedDeclaration( 762 kind, 763 modifiers, 764 name, 765 typeParameters 766 ); 767 node.parameters = createNodeArray(parameters); 768 node.type = type; 769 node.transformFlags |= 770 propagateChildrenFlags(node.parameters) | 771 propagateChildFlags(node.type); 772 if (type) node.transformFlags |= TransformFlags.ContainsTypeScript; 773 774 // The following properties are used for quick info 775 node.typeArguments = undefined; 776 return node; 777 } 778 779 function finishUpdateBaseSignatureDeclaration<T extends SignatureDeclarationBase>(updated: Mutable<T>, original: T) { 780 if (updated !== original) { 781 // copy children used for quick info 782 updated.typeArguments = original.typeArguments; 783 } 784 return update(updated, original); 785 } 786 787 function createBaseFunctionLikeDeclaration<T extends FunctionLikeDeclaration>( 788 kind: T["kind"], 789 modifiers: readonly ModifierLike[] | undefined, 790 name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, 791 typeParameters: readonly TypeParameterDeclaration[] | undefined, 792 parameters: readonly ParameterDeclaration[] | undefined, 793 type: TypeNode | undefined, 794 body: T["body"] 795 ) { 796 const node = createBaseSignatureDeclaration( 797 kind, 798 modifiers, 799 name, 800 typeParameters, 801 parameters, 802 type 803 ); 804 node.body = body; 805 node.transformFlags |= propagateChildFlags(node.body) & ~TransformFlags.ContainsPossibleTopLevelAwait; 806 if (!body) node.transformFlags |= TransformFlags.ContainsTypeScript; 807 return node; 808 } 809 810 function createBaseInterfaceOrClassLikeDeclaration<T extends InterfaceDeclaration | ClassLikeDeclaration>( 811 kind: T["kind"], 812 modifiers: readonly ModifierLike[] | undefined, 813 name: string | Identifier | undefined, 814 typeParameters: readonly TypeParameterDeclaration[] | undefined, 815 heritageClauses: readonly HeritageClause[] | undefined 816 ) { 817 const node = createBaseGenericNamedDeclaration( 818 kind, 819 modifiers, 820 name, 821 typeParameters 822 ); 823 node.heritageClauses = asNodeArray(heritageClauses); 824 node.transformFlags |= propagateChildrenFlags(node.heritageClauses); 825 return node; 826 } 827 828 function createBaseClassLikeDeclaration<T extends ClassLikeDeclaration>( 829 kind: T["kind"], 830 modifiers: readonly ModifierLike[] | undefined, 831 name: string | Identifier | undefined, 832 typeParameters: readonly TypeParameterDeclaration[] | undefined, 833 heritageClauses: readonly HeritageClause[] | undefined, 834 members: readonly ClassElement[] 835 ) { 836 const node = createBaseInterfaceOrClassLikeDeclaration( 837 kind, 838 modifiers, 839 name, 840 typeParameters, 841 heritageClauses 842 ); 843 node.members = createNodeArray(members); 844 node.transformFlags |= propagateChildrenFlags(node.members); 845 return node; 846 } 847 848 function createBaseBindingLikeDeclaration<T extends PropertyDeclaration | VariableDeclaration | ParameterDeclaration | 849 BindingElement | AnnotationPropertyDeclaration>( 850 kind: T["kind"], 851 modifiers: readonly ModifierLike[] | undefined, 852 name: string | T["name"] | undefined, 853 initializer: Expression | undefined 854 ) { 855 const node = createBaseNamedDeclaration( 856 kind, 857 modifiers, 858 name 859 ); 860 node.initializer = initializer; 861 node.transformFlags |= propagateChildFlags(node.initializer); 862 return node; 863 } 864 865 function createBaseVariableLikeDeclaration<T extends PropertyDeclaration | VariableDeclaration | ParameterDeclaration | AnnotationPropertyDeclaration>( 866 kind: T["kind"], 867 modifiers: readonly ModifierLike[] | undefined, 868 name: string | T["name"] | undefined, 869 type: TypeNode | undefined, 870 initializer: Expression | undefined 871 ) { 872 const node = createBaseBindingLikeDeclaration( 873 kind, 874 modifiers, 875 name, 876 initializer 877 ); 878 node.type = type; 879 node.transformFlags |= propagateChildFlags(type); 880 if (type) node.transformFlags |= TransformFlags.ContainsTypeScript; 881 return node; 882 } 883 884 // 885 // Literals 886 // 887 888 function createBaseLiteral<T extends LiteralToken>( 889 kind: T["kind"], 890 text: string 891 ) { 892 const node = createBaseToken(kind); 893 node.text = text; 894 return node; 895 } 896 897 // @api 898 function createNumericLiteral(value: string | number, numericLiteralFlags: TokenFlags = TokenFlags.None): NumericLiteral { 899 const node = createBaseLiteral<NumericLiteral>(SyntaxKind.NumericLiteral, typeof value === "number" ? value + "" : value); 900 node.numericLiteralFlags = numericLiteralFlags; 901 if (numericLiteralFlags & TokenFlags.BinaryOrOctalSpecifier) node.transformFlags |= TransformFlags.ContainsES2015; 902 return node; 903 } 904 905 // @api 906 function createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral { 907 const node = createBaseLiteral<BigIntLiteral>(SyntaxKind.BigIntLiteral, typeof value === "string" ? value : pseudoBigIntToString(value) + "n"); 908 node.transformFlags |= TransformFlags.ContainsESNext; 909 return node; 910 } 911 912 function createBaseStringLiteral(text: string, isSingleQuote?: boolean) { 913 const node = createBaseLiteral<StringLiteral>(SyntaxKind.StringLiteral, text); 914 node.singleQuote = isSingleQuote; 915 return node; 916 } 917 918 // @api 919 function createStringLiteral(text: string, isSingleQuote?: boolean, hasExtendedUnicodeEscape?: boolean): StringLiteral { 920 const node = createBaseStringLiteral(text, isSingleQuote); 921 node.hasExtendedUnicodeEscape = hasExtendedUnicodeEscape; 922 if (hasExtendedUnicodeEscape) node.transformFlags |= TransformFlags.ContainsES2015; 923 return node; 924 } 925 926 // @api 927 function createStringLiteralFromNode(sourceNode: PropertyNameLiteral | PrivateIdentifier): StringLiteral { 928 const node = createBaseStringLiteral(getTextOfIdentifierOrLiteral(sourceNode), /*isSingleQuote*/ undefined); 929 node.textSourceNode = sourceNode; 930 return node; 931 } 932 933 // @api 934 function createRegularExpressionLiteral(text: string): RegularExpressionLiteral { 935 const node = createBaseLiteral<RegularExpressionLiteral>(SyntaxKind.RegularExpressionLiteral, text); 936 return node; 937 } 938 939 // @api 940 function createLiteralLikeNode(kind: LiteralToken["kind"] | SyntaxKind.JsxTextAllWhiteSpaces, text: string): LiteralToken { 941 switch (kind) { 942 case SyntaxKind.NumericLiteral: return createNumericLiteral(text, /*numericLiteralFlags*/ 0); 943 case SyntaxKind.BigIntLiteral: return createBigIntLiteral(text); 944 case SyntaxKind.StringLiteral: return createStringLiteral(text, /*isSingleQuote*/ undefined); 945 case SyntaxKind.JsxText: return createJsxText(text, /*containsOnlyTriviaWhiteSpaces*/ false); 946 case SyntaxKind.JsxTextAllWhiteSpaces: return createJsxText(text, /*containsOnlyTriviaWhiteSpaces*/ true); 947 case SyntaxKind.RegularExpressionLiteral: return createRegularExpressionLiteral(text); 948 case SyntaxKind.NoSubstitutionTemplateLiteral: return createTemplateLiteralLikeNode(kind, text, /*rawText*/ undefined, /*templateFlags*/ 0) as NoSubstitutionTemplateLiteral; 949 } 950 } 951 952 // 953 // Identifiers 954 // 955 956 function createBaseIdentifier(text: string, originalKeywordKind: SyntaxKind | undefined) { 957 if (originalKeywordKind === undefined && text) { 958 originalKeywordKind = stringToToken(text); 959 } 960 if (originalKeywordKind === SyntaxKind.Identifier) { 961 originalKeywordKind = undefined; 962 } 963 const node = baseFactory.createBaseIdentifierNode(SyntaxKind.Identifier) as Mutable<Identifier>; 964 node.originalKeywordKind = originalKeywordKind; 965 node.escapedText = escapeLeadingUnderscores(text); 966 return node; 967 } 968 969 function createBaseGeneratedIdentifier(text: string, autoGenerateFlags: GeneratedIdentifierFlags, prefix: string | GeneratedNamePart | undefined, suffix: string | undefined) { 970 const node = createBaseIdentifier(text, /*originalKeywordKind*/ undefined) as Mutable<GeneratedIdentifier>; 971 node.autoGenerateFlags = autoGenerateFlags; 972 node.autoGenerateId = nextAutoGenerateId; 973 node.autoGeneratePrefix = prefix; 974 node.autoGenerateSuffix = suffix; 975 nextAutoGenerateId++; 976 return node; 977 } 978 979 // @api 980 function createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[], originalKeywordKind?: SyntaxKind, hasExtendedUnicodeEscape?: boolean): Identifier { 981 const node = createBaseIdentifier(text, originalKeywordKind); 982 if (typeArguments) { 983 // NOTE: we do not use `setChildren` here because typeArguments in an identifier do not contribute to transformations 984 node.typeArguments = createNodeArray(typeArguments); 985 } 986 if (node.originalKeywordKind === SyntaxKind.AwaitKeyword) { 987 node.transformFlags |= TransformFlags.ContainsPossibleTopLevelAwait; 988 } 989 if (hasExtendedUnicodeEscape) { 990 node.hasExtendedUnicodeEscape = hasExtendedUnicodeEscape; 991 node.transformFlags |= TransformFlags.ContainsES2015; 992 } 993 return node; 994 } 995 996 // @api 997 function updateIdentifier(node: Identifier, typeArguments?: NodeArray<TypeNode | TypeParameterDeclaration> | undefined): Identifier { 998 return node.typeArguments !== typeArguments 999 ? update(createIdentifier(idText(node), typeArguments), node) 1000 : node; 1001 } 1002 1003 // @api 1004 function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean, prefix?: string | GeneratedNamePart, suffix?: string): GeneratedIdentifier { 1005 let flags = GeneratedIdentifierFlags.Auto; 1006 if (reservedInNestedScopes) flags |= GeneratedIdentifierFlags.ReservedInNestedScopes; 1007 const name = createBaseGeneratedIdentifier("", flags, prefix, suffix); 1008 if (recordTempVariable) { 1009 recordTempVariable(name); 1010 } 1011 return name; 1012 } 1013 1014 /** Create a unique temporary variable for use in a loop. */ 1015 // @api 1016 function createLoopVariable(reservedInNestedScopes?: boolean): Identifier { 1017 let flags = GeneratedIdentifierFlags.Loop; 1018 if (reservedInNestedScopes) flags |= GeneratedIdentifierFlags.ReservedInNestedScopes; 1019 return createBaseGeneratedIdentifier("", flags, /*prefix*/ undefined, /*suffix*/ undefined); 1020 } 1021 1022 /** Create a unique name based on the supplied text. */ 1023 // @api 1024 function createUniqueName(text: string, flags: GeneratedIdentifierFlags = GeneratedIdentifierFlags.None, prefix?: string | GeneratedNamePart, suffix?: string): Identifier { 1025 Debug.assert(!(flags & GeneratedIdentifierFlags.KindMask), "Argument out of range: flags"); 1026 Debug.assert((flags & (GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)) !== GeneratedIdentifierFlags.FileLevel, "GeneratedIdentifierFlags.FileLevel cannot be set without also setting GeneratedIdentifierFlags.Optimistic"); 1027 return createBaseGeneratedIdentifier(text, GeneratedIdentifierFlags.Unique | flags, prefix, suffix); 1028 } 1029 1030 /** Create a unique name generated for a node. */ 1031 // @api 1032 function getGeneratedNameForNode(node: Node | undefined, flags: GeneratedIdentifierFlags = 0, prefix?: string | GeneratedNamePart, suffix?: string): Identifier { 1033 Debug.assert(!(flags & GeneratedIdentifierFlags.KindMask), "Argument out of range: flags"); 1034 const text = !node ? "" : 1035 isMemberName(node) ? formatGeneratedName(/*privateName*/ false, prefix, node, suffix, idText) : 1036 `generated@${getNodeId(node)}`; 1037 if (prefix || suffix) flags |= GeneratedIdentifierFlags.Optimistic; 1038 const name = createBaseGeneratedIdentifier(text, GeneratedIdentifierFlags.Node | flags, prefix, suffix); 1039 name.original = node; 1040 return name; 1041 } 1042 1043 function createBasePrivateIdentifier(text: string) { 1044 const node = baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as Mutable<PrivateIdentifier>; 1045 node.escapedText = escapeLeadingUnderscores(text); 1046 node.transformFlags |= TransformFlags.ContainsClassFields; 1047 return node; 1048 } 1049 1050 // @api 1051 function createPrivateIdentifier(text: string): PrivateIdentifier { 1052 if (!startsWith(text, "#")) Debug.fail("First character of private identifier must be #: " + text); 1053 return createBasePrivateIdentifier(text); 1054 } 1055 1056 function createBaseGeneratedPrivateIdentifier(text: string, autoGenerateFlags: GeneratedIdentifierFlags, prefix: string | GeneratedNamePart | undefined, suffix: string | undefined) { 1057 const node = createBasePrivateIdentifier(text); 1058 node.autoGenerateFlags = autoGenerateFlags; 1059 node.autoGenerateId = nextAutoGenerateId; 1060 node.autoGeneratePrefix = prefix; 1061 node.autoGenerateSuffix = suffix; 1062 nextAutoGenerateId++; 1063 return node; 1064 } 1065 1066 /** Create a unique name based on the supplied text. */ 1067 // @api 1068 function createUniquePrivateName(text?: string, prefix?: string | GeneratedNamePart, suffix?: string): PrivateIdentifier { 1069 if (text && !startsWith(text, "#")) Debug.fail("First character of private identifier must be #: " + text); 1070 const autoGenerateFlags = GeneratedIdentifierFlags.ReservedInNestedScopes | 1071 (text ? GeneratedIdentifierFlags.Unique : GeneratedIdentifierFlags.Auto); 1072 return createBaseGeneratedPrivateIdentifier(text ?? "", autoGenerateFlags, prefix, suffix); 1073 } 1074 1075 // @api 1076 function getGeneratedPrivateNameForNode(node: Node, prefix?: string | GeneratedNamePart, suffix?: string): PrivateIdentifier { 1077 const text = isMemberName(node) ? formatGeneratedName(/*privateName*/ true, prefix, node, suffix, idText) : 1078 `#generated@${getNodeId(node)}`; 1079 const flags = prefix || suffix ? GeneratedIdentifierFlags.Optimistic : GeneratedIdentifierFlags.None; 1080 const name = createBaseGeneratedPrivateIdentifier(text, GeneratedIdentifierFlags.Node | flags, prefix, suffix); 1081 name.original = node; 1082 return name; 1083 } 1084 1085 // 1086 // Punctuation 1087 // 1088 1089 function createBaseToken<T extends Node>(kind: T["kind"]) { 1090 return baseFactory.createBaseTokenNode(kind) as Mutable<T>; 1091 } 1092 1093 // @api 1094 function createToken(token: SyntaxKind.SuperKeyword): SuperExpression; 1095 function createToken(token: SyntaxKind.ThisKeyword): ThisExpression; 1096 function createToken(token: SyntaxKind.NullKeyword): NullLiteral; 1097 function createToken(token: SyntaxKind.TrueKeyword): TrueLiteral; 1098 function createToken(token: SyntaxKind.FalseKeyword): FalseLiteral; 1099 function createToken<TKind extends PunctuationSyntaxKind>(token: TKind): PunctuationToken<TKind>; 1100 function createToken<TKind extends KeywordTypeSyntaxKind>(token: TKind): KeywordTypeNode<TKind>; 1101 function createToken<TKind extends ModifierSyntaxKind>(token: TKind): ModifierToken<TKind>; 1102 function createToken<TKind extends KeywordSyntaxKind>(token: TKind): KeywordToken<TKind>; 1103 function createToken<TKind extends SyntaxKind.Unknown | SyntaxKind.EndOfFileToken>(token: TKind): Token<TKind>; 1104 function createToken<TKind extends SyntaxKind>(token: TKind): Token<TKind>; 1105 function createToken<TKind extends SyntaxKind>(token: TKind) { 1106 Debug.assert(token >= SyntaxKind.FirstToken && token <= SyntaxKind.LastToken, "Invalid token"); 1107 Debug.assert(token <= SyntaxKind.FirstTemplateToken || token >= SyntaxKind.LastTemplateToken, "Invalid token. Use 'createTemplateLiteralLikeNode' to create template literals."); 1108 Debug.assert(token <= SyntaxKind.FirstLiteralToken || token >= SyntaxKind.LastLiteralToken, "Invalid token. Use 'createLiteralLikeNode' to create literals."); 1109 Debug.assert(token !== SyntaxKind.Identifier, "Invalid token. Use 'createIdentifier' to create identifiers"); 1110 const node = createBaseToken<Token<TKind>>(token); 1111 let transformFlags = TransformFlags.None; 1112 switch (token) { 1113 case SyntaxKind.AsyncKeyword: 1114 // 'async' modifier is ES2017 (async functions) or ES2018 (async generators) 1115 transformFlags = 1116 TransformFlags.ContainsES2017 | 1117 TransformFlags.ContainsES2018; 1118 break; 1119 1120 case SyntaxKind.PublicKeyword: 1121 case SyntaxKind.PrivateKeyword: 1122 case SyntaxKind.ProtectedKeyword: 1123 case SyntaxKind.ReadonlyKeyword: 1124 case SyntaxKind.AbstractKeyword: 1125 case SyntaxKind.DeclareKeyword: 1126 case SyntaxKind.ConstKeyword: 1127 case SyntaxKind.AnyKeyword: 1128 case SyntaxKind.NumberKeyword: 1129 case SyntaxKind.BigIntKeyword: 1130 case SyntaxKind.NeverKeyword: 1131 case SyntaxKind.ObjectKeyword: 1132 case SyntaxKind.InKeyword: 1133 case SyntaxKind.OutKeyword: 1134 case SyntaxKind.OverrideKeyword: 1135 case SyntaxKind.StringKeyword: 1136 case SyntaxKind.BooleanKeyword: 1137 case SyntaxKind.SymbolKeyword: 1138 case SyntaxKind.VoidKeyword: 1139 case SyntaxKind.UnknownKeyword: 1140 case SyntaxKind.UndefinedKeyword: // `undefined` is an Identifier in the expression case. 1141 transformFlags = TransformFlags.ContainsTypeScript; 1142 break; 1143 case SyntaxKind.SuperKeyword: 1144 transformFlags = TransformFlags.ContainsES2015 | TransformFlags.ContainsLexicalSuper; 1145 break; 1146 case SyntaxKind.StaticKeyword: 1147 transformFlags = TransformFlags.ContainsES2015; 1148 break; 1149 case SyntaxKind.AccessorKeyword: 1150 transformFlags = TransformFlags.ContainsClassFields; 1151 break; 1152 case SyntaxKind.ThisKeyword: 1153 // 'this' indicates a lexical 'this' 1154 transformFlags = TransformFlags.ContainsLexicalThis; 1155 break; 1156 } 1157 if (transformFlags) { 1158 node.transformFlags |= transformFlags; 1159 } 1160 return node; 1161 } 1162 1163 // 1164 // Reserved words 1165 // 1166 1167 // @api 1168 function createSuper() { 1169 return createToken(SyntaxKind.SuperKeyword); 1170 } 1171 1172 // @api 1173 function createThis() { 1174 return createToken(SyntaxKind.ThisKeyword); 1175 } 1176 1177 // @api 1178 function createNull() { 1179 return createToken(SyntaxKind.NullKeyword); 1180 } 1181 1182 // @api 1183 function createTrue() { 1184 return createToken(SyntaxKind.TrueKeyword); 1185 } 1186 1187 // @api 1188 function createFalse() { 1189 return createToken(SyntaxKind.FalseKeyword); 1190 } 1191 1192 // 1193 // Modifiers 1194 // 1195 1196 // @api 1197 function createModifier<T extends ModifierSyntaxKind>(kind: T) { 1198 return createToken(kind); 1199 } 1200 1201 // @api 1202 function createModifiersFromModifierFlags(flags: ModifierFlags) { 1203 const result: Modifier[] = []; 1204 if (flags & ModifierFlags.Export) result.push(createModifier(SyntaxKind.ExportKeyword)); 1205 if (flags & ModifierFlags.Ambient) result.push(createModifier(SyntaxKind.DeclareKeyword)); 1206 if (flags & ModifierFlags.Default) result.push(createModifier(SyntaxKind.DefaultKeyword)); 1207 if (flags & ModifierFlags.Const) result.push(createModifier(SyntaxKind.ConstKeyword)); 1208 if (flags & ModifierFlags.Public) result.push(createModifier(SyntaxKind.PublicKeyword)); 1209 if (flags & ModifierFlags.Private) result.push(createModifier(SyntaxKind.PrivateKeyword)); 1210 if (flags & ModifierFlags.Protected) result.push(createModifier(SyntaxKind.ProtectedKeyword)); 1211 if (flags & ModifierFlags.Abstract) result.push(createModifier(SyntaxKind.AbstractKeyword)); 1212 if (flags & ModifierFlags.Static) result.push(createModifier(SyntaxKind.StaticKeyword)); 1213 if (flags & ModifierFlags.Override) result.push(createModifier(SyntaxKind.OverrideKeyword)); 1214 if (flags & ModifierFlags.Readonly) result.push(createModifier(SyntaxKind.ReadonlyKeyword)); 1215 if (flags & ModifierFlags.Accessor) result.push(createModifier(SyntaxKind.AccessorKeyword)); 1216 if (flags & ModifierFlags.Async) result.push(createModifier(SyntaxKind.AsyncKeyword)); 1217 if (flags & ModifierFlags.In) result.push(createModifier(SyntaxKind.InKeyword)); 1218 if (flags & ModifierFlags.Out) result.push(createModifier(SyntaxKind.OutKeyword)); 1219 return result.length ? result : undefined; 1220 } 1221 1222 // 1223 // Names 1224 // 1225 1226 // @api 1227 function createQualifiedName(left: EntityName, right: string | Identifier) { 1228 const node = createBaseNode<QualifiedName>(SyntaxKind.QualifiedName); 1229 node.left = left; 1230 node.right = asName(right); 1231 node.transformFlags |= 1232 propagateChildFlags(node.left) | 1233 propagateIdentifierNameFlags(node.right); 1234 return node; 1235 } 1236 1237 // @api 1238 function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier) { 1239 return node.left !== left 1240 || node.right !== right 1241 ? update(createQualifiedName(left, right), node) 1242 : node; 1243 } 1244 1245 // @api 1246 function createComputedPropertyName(expression: Expression) { 1247 const node = createBaseNode<ComputedPropertyName>(SyntaxKind.ComputedPropertyName); 1248 node.expression = parenthesizerRules().parenthesizeExpressionOfComputedPropertyName(expression); 1249 node.transformFlags |= 1250 propagateChildFlags(node.expression) | 1251 TransformFlags.ContainsES2015 | 1252 TransformFlags.ContainsComputedPropertyName; 1253 return node; 1254 } 1255 1256 // @api 1257 function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression) { 1258 return node.expression !== expression 1259 ? update(createComputedPropertyName(expression), node) 1260 : node; 1261 } 1262 1263 // 1264 // Signature elements 1265 // 1266 1267 // @api 1268 function createTypeParameterDeclaration(modifiers: readonly Modifier[] | undefined, name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration { 1269 const node = createBaseNamedDeclaration<TypeParameterDeclaration>( 1270 SyntaxKind.TypeParameter, 1271 modifiers, 1272 name 1273 ); 1274 node.constraint = constraint; 1275 node.default = defaultType; 1276 node.transformFlags = TransformFlags.ContainsTypeScript; 1277 return node; 1278 } 1279 1280 // @api 1281 function updateTypeParameterDeclaration(node: TypeParameterDeclaration, modifiers: readonly Modifier[] | undefined, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined): TypeParameterDeclaration { 1282 return node.modifiers !== modifiers 1283 || node.name !== name 1284 || node.constraint !== constraint 1285 || node.default !== defaultType 1286 ? update(createTypeParameterDeclaration(modifiers, name, constraint, defaultType), node) 1287 : node; 1288 } 1289 1290 // @api 1291 function createParameterDeclaration( 1292 modifiers: readonly ModifierLike[] | undefined, 1293 dotDotDotToken: DotDotDotToken | undefined, 1294 name: string | BindingName, 1295 questionToken?: QuestionToken, 1296 type?: TypeNode, 1297 initializer?: Expression 1298 ) { 1299 const node = createBaseVariableLikeDeclaration<ParameterDeclaration>( 1300 SyntaxKind.Parameter, 1301 modifiers, 1302 name, 1303 type, 1304 initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer) 1305 ); 1306 node.dotDotDotToken = dotDotDotToken; 1307 node.questionToken = questionToken; 1308 if (isThisIdentifier(node.name)) { 1309 node.transformFlags = TransformFlags.ContainsTypeScript; 1310 } 1311 else { 1312 node.transformFlags |= 1313 propagateChildFlags(node.dotDotDotToken) | 1314 propagateChildFlags(node.questionToken); 1315 if (questionToken) node.transformFlags |= TransformFlags.ContainsTypeScript; 1316 if (modifiersToFlags(node.modifiers) & ModifierFlags.ParameterPropertyModifier) node.transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax; 1317 if (initializer || dotDotDotToken) node.transformFlags |= TransformFlags.ContainsES2015; 1318 } 1319 return node; 1320 } 1321 1322 // @api 1323 function updateParameterDeclaration( 1324 node: ParameterDeclaration, 1325 modifiers: readonly ModifierLike[] | undefined, 1326 dotDotDotToken: DotDotDotToken | undefined, 1327 name: string | BindingName, 1328 questionToken: QuestionToken | undefined, 1329 type: TypeNode | undefined, 1330 initializer: Expression | undefined 1331 ) { 1332 return node.modifiers !== modifiers 1333 || node.dotDotDotToken !== dotDotDotToken 1334 || node.name !== name 1335 || node.questionToken !== questionToken 1336 || node.type !== type 1337 || node.initializer !== initializer 1338 ? update(createParameterDeclaration(modifiers, dotDotDotToken, name, questionToken, type, initializer), node) 1339 : node; 1340 } 1341 1342 // @api 1343 function createDecorator(expression: Expression, annotationDeclaration?: AnnotationDeclaration) { 1344 const node = createBaseNode<Decorator>(SyntaxKind.Decorator); 1345 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); 1346 node.annotationDeclaration = annotationDeclaration; 1347 node.transformFlags |= 1348 propagateChildFlags(node.expression) | 1349 TransformFlags.ContainsTypeScript | 1350 TransformFlags.ContainsTypeScriptClassSyntax | 1351 TransformFlags.ContainsDecorators; 1352 return node; 1353 } 1354 1355 // @api 1356 function updateDecorator(node: Decorator, expression: Expression, annotationDeclaration?: AnnotationDeclaration) { 1357 return node.expression !== expression || node.annotationDeclaration !== annotationDeclaration 1358 ? update(createDecorator(expression, annotationDeclaration), node) 1359 : node; 1360 } 1361 1362 // 1363 // Type Elements 1364 // 1365 1366 // @api 1367 function createPropertySignature( 1368 modifiers: readonly ModifierLike[] | undefined, 1369 name: PropertyName | string, 1370 questionToken: QuestionToken | undefined, 1371 type: TypeNode | undefined 1372 ): PropertySignature { 1373 const node = createBaseNamedDeclaration<PropertySignature>( 1374 SyntaxKind.PropertySignature, 1375 modifiers, 1376 name 1377 ); 1378 node.type = type; 1379 node.questionToken = questionToken; 1380 node.transformFlags = TransformFlags.ContainsTypeScript; 1381 1382 // The following properties are used only to report grammar errors 1383 node.initializer = undefined; 1384 return node; 1385 } 1386 1387 // @api 1388 function updatePropertySignature( 1389 node: PropertySignature, 1390 modifiers: readonly ModifierLike[] | undefined, 1391 name: PropertyName, 1392 questionToken: QuestionToken | undefined, 1393 type: TypeNode | undefined 1394 ) { 1395 return node.modifiers !== modifiers 1396 || node.name !== name 1397 || node.questionToken !== questionToken 1398 || node.type !== type 1399 ? finishUpdatePropertySignature(createPropertySignature(modifiers, name, questionToken, type), node) 1400 : node; 1401 } 1402 1403 function finishUpdatePropertySignature(updated: Mutable<PropertySignature>, original: PropertySignature) { 1404 if (updated !== original) { 1405 // copy children used only for error reporting 1406 updated.initializer = original.initializer; 1407 } 1408 return update(updated, original); 1409 } 1410 1411 // @api 1412 function createPropertyDeclaration( 1413 modifiers: readonly ModifierLike[] | undefined, 1414 name: string | PropertyName, 1415 questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, 1416 type: TypeNode | undefined, 1417 initializer: Expression | undefined 1418 ) { 1419 const node = createBaseVariableLikeDeclaration<PropertyDeclaration>( 1420 SyntaxKind.PropertyDeclaration, 1421 modifiers, 1422 name, 1423 type, 1424 initializer 1425 ); 1426 node.questionToken = questionOrExclamationToken && isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; 1427 node.exclamationToken = questionOrExclamationToken && isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; 1428 node.transformFlags |= 1429 propagateChildFlags(node.questionToken) | 1430 propagateChildFlags(node.exclamationToken) | 1431 TransformFlags.ContainsClassFields; 1432 if (isComputedPropertyName(node.name) || (hasStaticModifier(node) && node.initializer)) { 1433 node.transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax; 1434 } 1435 if (questionOrExclamationToken || modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { 1436 node.transformFlags |= TransformFlags.ContainsTypeScript; 1437 } 1438 return node; 1439 } 1440 1441 // @api 1442 function updatePropertyDeclaration( 1443 node: PropertyDeclaration, 1444 modifiers: readonly ModifierLike[] | undefined, 1445 name: string | PropertyName, 1446 questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, 1447 type: TypeNode | undefined, 1448 initializer: Expression | undefined 1449 ) { 1450 return node.modifiers !== modifiers 1451 || node.name !== name 1452 || node.questionToken !== (questionOrExclamationToken !== undefined && isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined) 1453 || node.exclamationToken !== (questionOrExclamationToken !== undefined && isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined) 1454 || node.type !== type 1455 || node.initializer !== initializer 1456 ? update(createPropertyDeclaration(modifiers, name, questionOrExclamationToken, type, initializer), node) 1457 : node; 1458 } 1459 1460 // @api 1461 function createAnnotationPropertyDeclaration( 1462 name: string | PropertyName, 1463 type: TypeNode | undefined, 1464 initializer: Expression | undefined, 1465 ) { 1466 const node = createBaseVariableLikeDeclaration<AnnotationPropertyDeclaration>( 1467 SyntaxKind.AnnotationPropertyDeclaration, 1468 undefined, 1469 name, 1470 type, 1471 initializer 1472 ); 1473 node.transformFlags |= TransformFlags.ContainsTypeScript; 1474 return node; 1475 } 1476 1477 // @api 1478 function updateAnnotationPropertyDeclaration( 1479 node: AnnotationPropertyDeclaration, 1480 name: string | PropertyName, 1481 type: TypeNode | undefined, 1482 initializer: Expression | undefined, 1483 ) { 1484 return node.name !== name 1485 || node.type !== type 1486 || node.initializer !== initializer 1487 ? update(createAnnotationPropertyDeclaration(name, type, initializer), node) 1488 : node; 1489 } 1490 1491 // @api 1492 function createMethodSignature( 1493 modifiers: readonly ModifierLike[] | undefined, 1494 name: string | PropertyName, 1495 questionToken: QuestionToken | undefined, 1496 typeParameters: readonly TypeParameterDeclaration[] | undefined, 1497 parameters: readonly ParameterDeclaration[], 1498 type: TypeNode | undefined 1499 ) { 1500 const node = createBaseSignatureDeclaration<MethodSignature>( 1501 SyntaxKind.MethodSignature, 1502 modifiers, 1503 name, 1504 typeParameters, 1505 parameters, 1506 type 1507 ); 1508 node.questionToken = questionToken; 1509 node.transformFlags = TransformFlags.ContainsTypeScript; 1510 return node; 1511 } 1512 1513 // @api 1514 function updateMethodSignature( 1515 node: MethodSignature, 1516 modifiers: readonly ModifierLike[] | undefined, 1517 name: PropertyName, 1518 questionToken: QuestionToken | undefined, 1519 typeParameters: NodeArray<TypeParameterDeclaration> | undefined, 1520 parameters: NodeArray<ParameterDeclaration>, 1521 type: TypeNode | undefined 1522 ) { 1523 return node.modifiers !== modifiers 1524 || node.name !== name 1525 || node.questionToken !== questionToken 1526 || node.typeParameters !== typeParameters 1527 || node.parameters !== parameters 1528 || node.type !== type 1529 ? finishUpdateBaseSignatureDeclaration(createMethodSignature(modifiers, name, questionToken, typeParameters, parameters, type), node) 1530 : node; 1531 } 1532 1533 // @api 1534 function createMethodDeclaration( 1535 modifiers: readonly ModifierLike[] | undefined, 1536 asteriskToken: AsteriskToken | undefined, 1537 name: string | PropertyName, 1538 questionToken: QuestionToken | undefined, 1539 typeParameters: readonly TypeParameterDeclaration[] | undefined, 1540 parameters: readonly ParameterDeclaration[], 1541 type: TypeNode | undefined, 1542 body: Block | undefined 1543 ) { 1544 const node = createBaseFunctionLikeDeclaration<MethodDeclaration>( 1545 SyntaxKind.MethodDeclaration, 1546 modifiers, 1547 name, 1548 typeParameters, 1549 parameters, 1550 type, 1551 body 1552 ); 1553 node.asteriskToken = asteriskToken; 1554 node.questionToken = questionToken; 1555 node.transformFlags |= 1556 propagateChildFlags(node.asteriskToken) | 1557 propagateChildFlags(node.questionToken) | 1558 TransformFlags.ContainsES2015; 1559 if (questionToken) { 1560 node.transformFlags |= TransformFlags.ContainsTypeScript; 1561 } 1562 if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { 1563 if (asteriskToken) { 1564 node.transformFlags |= TransformFlags.ContainsES2018; 1565 } 1566 else { 1567 node.transformFlags |= TransformFlags.ContainsES2017; 1568 } 1569 } 1570 else if (asteriskToken) { 1571 node.transformFlags |= TransformFlags.ContainsGenerator; 1572 } 1573 1574 // The following properties are used only to report grammar errors 1575 node.exclamationToken = undefined; 1576 return node; 1577 } 1578 1579 // @api 1580 function updateMethodDeclaration( 1581 node: MethodDeclaration, 1582 modifiers: readonly ModifierLike[] | undefined, 1583 asteriskToken: AsteriskToken | undefined, 1584 name: PropertyName, 1585 questionToken: QuestionToken | undefined, 1586 typeParameters: readonly TypeParameterDeclaration[] | undefined, 1587 parameters: readonly ParameterDeclaration[], 1588 type: TypeNode | undefined, 1589 body: Block | undefined 1590 ) { 1591 return node.modifiers !== modifiers 1592 || node.asteriskToken !== asteriskToken 1593 || node.name !== name 1594 || node.questionToken !== questionToken 1595 || node.typeParameters !== typeParameters 1596 || node.parameters !== parameters 1597 || node.type !== type 1598 || node.body !== body 1599 ? finishUpdateMethodDeclaration(createMethodDeclaration(modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) 1600 : node; 1601 } 1602 1603 function finishUpdateMethodDeclaration(updated: Mutable<MethodDeclaration>, original: MethodDeclaration) { 1604 if (updated !== original) { 1605 updated.exclamationToken = original.exclamationToken; 1606 } 1607 return update(updated, original); 1608 } 1609 1610 // @api 1611 function createClassStaticBlockDeclaration( 1612 body: Block 1613 ): ClassStaticBlockDeclaration { 1614 const node = createBaseGenericNamedDeclaration<ClassStaticBlockDeclaration>( 1615 SyntaxKind.ClassStaticBlockDeclaration, 1616 /*modifiers*/ undefined, 1617 /*name*/ undefined, 1618 /*typeParameters*/ undefined 1619 ); 1620 node.body = body; 1621 node.transformFlags = propagateChildFlags(body) | TransformFlags.ContainsClassFields; 1622 1623 // The following properties are used only to report grammar errors 1624 node.illegalDecorators = undefined; 1625 node.modifiers = undefined; 1626 return node; 1627 } 1628 1629 // @api 1630 function updateClassStaticBlockDeclaration( 1631 node: ClassStaticBlockDeclaration, 1632 body: Block 1633 ): ClassStaticBlockDeclaration { 1634 return node.body !== body 1635 ? finishUpdateClassStaticBlockDeclaration(createClassStaticBlockDeclaration(body), node) 1636 : node; 1637 } 1638 1639 function finishUpdateClassStaticBlockDeclaration(updated: Mutable<ClassStaticBlockDeclaration>, original: ClassStaticBlockDeclaration) { 1640 if (updated !== original) { 1641 updated.illegalDecorators = original.illegalDecorators; 1642 updated.modifiers = original.modifiers; 1643 } 1644 return update(updated, original); 1645 } 1646 1647 // @api 1648 function createConstructorDeclaration( 1649 modifiers: readonly Modifier[] | undefined, 1650 parameters: readonly ParameterDeclaration[], 1651 body: Block | undefined 1652 ) { 1653 const node = createBaseFunctionLikeDeclaration<ConstructorDeclaration>( 1654 SyntaxKind.Constructor, 1655 modifiers, 1656 /*name*/ undefined, 1657 /*typeParameters*/ undefined, 1658 parameters, 1659 /*type*/ undefined, 1660 body 1661 ); 1662 node.transformFlags |= TransformFlags.ContainsES2015; 1663 1664 // The following properties are used only to report grammar errors 1665 node.illegalDecorators = undefined; 1666 node.typeParameters = undefined; 1667 node.type = undefined; 1668 return node; 1669 } 1670 1671 // @api 1672 function updateConstructorDeclaration( 1673 node: ConstructorDeclaration, 1674 modifiers: readonly Modifier[] | undefined, 1675 parameters: readonly ParameterDeclaration[], 1676 body: Block | undefined 1677 ) { 1678 return node.modifiers !== modifiers 1679 || node.parameters !== parameters 1680 || node.body !== body 1681 ? finishUpdateConstructorDeclaration(createConstructorDeclaration(modifiers, parameters, body), node) 1682 : node; 1683 } 1684 1685 function finishUpdateConstructorDeclaration(updated: Mutable<ConstructorDeclaration>, original: ConstructorDeclaration) { 1686 if (updated !== original) { 1687 updated.illegalDecorators = original.illegalDecorators; 1688 updated.typeParameters = original.typeParameters; 1689 updated.type = original.type; 1690 } 1691 return finishUpdateBaseSignatureDeclaration(updated, original); 1692 } 1693 1694 // @api 1695 function createGetAccessorDeclaration( 1696 modifiers: readonly ModifierLike[] | undefined, 1697 name: string | PropertyName, 1698 parameters: readonly ParameterDeclaration[], 1699 type: TypeNode | undefined, 1700 body: Block | undefined 1701 ) { 1702 const node = createBaseFunctionLikeDeclaration<GetAccessorDeclaration>( 1703 SyntaxKind.GetAccessor, 1704 modifiers, 1705 name, 1706 /*typeParameters*/ undefined, 1707 parameters, 1708 type, 1709 body 1710 ); 1711 1712 // The following properties are used only to report grammar errors 1713 node.typeParameters = undefined; 1714 return node; 1715 } 1716 1717 // @api 1718 function updateGetAccessorDeclaration( 1719 node: GetAccessorDeclaration, 1720 modifiers: readonly ModifierLike[] | undefined, 1721 name: PropertyName, 1722 parameters: readonly ParameterDeclaration[], 1723 type: TypeNode | undefined, 1724 body: Block | undefined 1725 ) { 1726 return node.modifiers !== modifiers 1727 || node.name !== name 1728 || node.parameters !== parameters 1729 || node.type !== type 1730 || node.body !== body 1731 ? finishUpdateGetAccessorDeclaration(createGetAccessorDeclaration(modifiers, name, parameters, type, body), node) 1732 : node; 1733 } 1734 1735 function finishUpdateGetAccessorDeclaration(updated: Mutable<GetAccessorDeclaration>, original: GetAccessorDeclaration) { 1736 if (updated !== original) { 1737 updated.typeParameters = original.typeParameters; 1738 } 1739 return finishUpdateBaseSignatureDeclaration(updated, original); 1740 } 1741 1742 // @api 1743 function createSetAccessorDeclaration( 1744 modifiers: readonly ModifierLike[] | undefined, 1745 name: string | PropertyName, 1746 parameters: readonly ParameterDeclaration[], 1747 body: Block | undefined 1748 ) { 1749 const node = createBaseFunctionLikeDeclaration<SetAccessorDeclaration>( 1750 SyntaxKind.SetAccessor, 1751 modifiers, 1752 name, 1753 /*typeParameters*/ undefined, 1754 parameters, 1755 /*type*/ undefined, 1756 body 1757 ); 1758 1759 // The following properties are used only to report grammar errors 1760 node.typeParameters = undefined; 1761 node.type = undefined; 1762 return node; 1763 } 1764 1765 // @api 1766 function updateSetAccessorDeclaration( 1767 node: SetAccessorDeclaration, 1768 modifiers: readonly ModifierLike[] | undefined, 1769 name: PropertyName, 1770 parameters: readonly ParameterDeclaration[], 1771 body: Block | undefined 1772 ) { 1773 return node.modifiers !== modifiers 1774 || node.name !== name 1775 || node.parameters !== parameters 1776 || node.body !== body 1777 ? finishUpdateSetAccessorDeclaration(createSetAccessorDeclaration(modifiers, name, parameters, body), node) 1778 : node; 1779 } 1780 1781 function finishUpdateSetAccessorDeclaration(updated: Mutable<SetAccessorDeclaration>, original: SetAccessorDeclaration) { 1782 if (updated !== original) { 1783 updated.typeParameters = original.typeParameters; 1784 updated.type = original.type; 1785 } 1786 return finishUpdateBaseSignatureDeclaration(updated, original); 1787 } 1788 1789 // @api 1790 function createCallSignature( 1791 typeParameters: readonly TypeParameterDeclaration[] | undefined, 1792 parameters: readonly ParameterDeclaration[], 1793 type: TypeNode | undefined 1794 ): CallSignatureDeclaration { 1795 const node = createBaseSignatureDeclaration<CallSignatureDeclaration>( 1796 SyntaxKind.CallSignature, 1797 /*modifiers*/ undefined, 1798 /*name*/ undefined, 1799 typeParameters, 1800 parameters, 1801 type 1802 ); 1803 node.transformFlags = TransformFlags.ContainsTypeScript; 1804 return node; 1805 } 1806 1807 // @api 1808 function updateCallSignature( 1809 node: CallSignatureDeclaration, 1810 typeParameters: NodeArray<TypeParameterDeclaration> | undefined, 1811 parameters: NodeArray<ParameterDeclaration>, 1812 type: TypeNode | undefined 1813 ) { 1814 return node.typeParameters !== typeParameters 1815 || node.parameters !== parameters 1816 || node.type !== type 1817 ? finishUpdateBaseSignatureDeclaration(createCallSignature(typeParameters, parameters, type), node) 1818 : node; 1819 } 1820 1821 // @api 1822 function createConstructSignature( 1823 typeParameters: readonly TypeParameterDeclaration[] | undefined, 1824 parameters: readonly ParameterDeclaration[], 1825 type: TypeNode | undefined 1826 ): ConstructSignatureDeclaration { 1827 const node = createBaseSignatureDeclaration<ConstructSignatureDeclaration>( 1828 SyntaxKind.ConstructSignature, 1829 /*modifiers*/ undefined, 1830 /*name*/ undefined, 1831 typeParameters, 1832 parameters, 1833 type 1834 ); 1835 node.transformFlags = TransformFlags.ContainsTypeScript; 1836 return node; 1837 } 1838 1839 // @api 1840 function updateConstructSignature( 1841 node: ConstructSignatureDeclaration, 1842 typeParameters: NodeArray<TypeParameterDeclaration> | undefined, 1843 parameters: NodeArray<ParameterDeclaration>, 1844 type: TypeNode | undefined 1845 ) { 1846 return node.typeParameters !== typeParameters 1847 || node.parameters !== parameters 1848 || node.type !== type 1849 ? finishUpdateBaseSignatureDeclaration(createConstructSignature(typeParameters, parameters, type), node) 1850 : node; 1851 } 1852 1853 // @api 1854 function createIndexSignature( 1855 modifiers: readonly Modifier[] | undefined, 1856 parameters: readonly ParameterDeclaration[], 1857 type: TypeNode | undefined 1858 ): IndexSignatureDeclaration { 1859 const node = createBaseSignatureDeclaration<IndexSignatureDeclaration>( 1860 SyntaxKind.IndexSignature, 1861 modifiers, 1862 /*name*/ undefined, 1863 /*typeParameters*/ undefined, 1864 parameters, 1865 type 1866 ); 1867 node.transformFlags = TransformFlags.ContainsTypeScript; 1868 return node; 1869 } 1870 1871 // @api 1872 function updateIndexSignature( 1873 node: IndexSignatureDeclaration, 1874 modifiers: readonly Modifier[] | undefined, 1875 parameters: readonly ParameterDeclaration[], 1876 type: TypeNode 1877 ) { 1878 return node.parameters !== parameters 1879 || node.type !== type 1880 || node.modifiers !== modifiers 1881 ? finishUpdateBaseSignatureDeclaration(createIndexSignature(modifiers, parameters, type), node) 1882 : node; 1883 } 1884 1885 // @api 1886 function createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle | TemplateTail) { 1887 const node = createBaseNode<TemplateLiteralTypeSpan>(SyntaxKind.TemplateLiteralTypeSpan); 1888 node.type = type; 1889 node.literal = literal; 1890 node.transformFlags = TransformFlags.ContainsTypeScript; 1891 return node; 1892 } 1893 1894 // @api 1895 function updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle | TemplateTail) { 1896 return node.type !== type 1897 || node.literal !== literal 1898 ? update(createTemplateLiteralTypeSpan(type, literal), node) 1899 : node; 1900 } 1901 1902 // 1903 // Types 1904 // 1905 1906 // @api 1907 function createKeywordTypeNode<TKind extends KeywordTypeSyntaxKind>(kind: TKind) { 1908 return createToken(kind); 1909 } 1910 1911 // @api 1912 function createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { 1913 const node = createBaseNode<TypePredicateNode>(SyntaxKind.TypePredicate); 1914 node.assertsModifier = assertsModifier; 1915 node.parameterName = asName(parameterName); 1916 node.type = type; 1917 node.transformFlags = TransformFlags.ContainsTypeScript; 1918 return node; 1919 } 1920 1921 // @api 1922 function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) { 1923 return node.assertsModifier !== assertsModifier 1924 || node.parameterName !== parameterName 1925 || node.type !== type 1926 ? update(createTypePredicateNode(assertsModifier, parameterName, type), node) 1927 : node; 1928 } 1929 1930 // @api 1931 function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined) { 1932 const node = createBaseNode<TypeReferenceNode>(SyntaxKind.TypeReference); 1933 node.typeName = asName(typeName); 1934 node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(createNodeArray(typeArguments)); 1935 node.transformFlags = TransformFlags.ContainsTypeScript; 1936 return node; 1937 } 1938 1939 // @api 1940 function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray<TypeNode> | undefined) { 1941 return node.typeName !== typeName 1942 || node.typeArguments !== typeArguments 1943 ? update(createTypeReferenceNode(typeName, typeArguments), node) 1944 : node; 1945 } 1946 1947 // @api 1948 function createFunctionTypeNode( 1949 typeParameters: readonly TypeParameterDeclaration[] | undefined, 1950 parameters: readonly ParameterDeclaration[], 1951 type: TypeNode | undefined 1952 ): FunctionTypeNode { 1953 const node = createBaseSignatureDeclaration<FunctionTypeNode>( 1954 SyntaxKind.FunctionType, 1955 /*modifiers*/ undefined, 1956 /*name*/ undefined, 1957 typeParameters, 1958 parameters, 1959 type 1960 ); 1961 node.transformFlags = TransformFlags.ContainsTypeScript; 1962 1963 // The following properties are used only to report grammar errors 1964 node.modifiers = undefined; 1965 return node; 1966 } 1967 1968 // @api 1969 function updateFunctionTypeNode( 1970 node: FunctionTypeNode, 1971 typeParameters: NodeArray<TypeParameterDeclaration> | undefined, 1972 parameters: NodeArray<ParameterDeclaration>, 1973 type: TypeNode | undefined 1974 ) { 1975 return node.typeParameters !== typeParameters 1976 || node.parameters !== parameters 1977 || node.type !== type 1978 ? finishUpdateFunctionTypeNode(createFunctionTypeNode(typeParameters, parameters, type), node) 1979 : node; 1980 } 1981 1982 function finishUpdateFunctionTypeNode(updated: Mutable<FunctionTypeNode>, original: FunctionTypeNode) { 1983 if (updated !== original) { 1984 updated.modifiers = original.modifiers; 1985 } 1986 return finishUpdateBaseSignatureDeclaration(updated, original); 1987 } 1988 1989 // @api 1990 function createConstructorTypeNode(...args: Parameters<typeof createConstructorTypeNode1 | typeof createConstructorTypeNode2>) { 1991 return args.length === 4 ? createConstructorTypeNode1(...args) : 1992 args.length === 3 ? createConstructorTypeNode2(...args) : 1993 Debug.fail("Incorrect number of arguments specified."); 1994 } 1995 1996 function createConstructorTypeNode1( 1997 modifiers: readonly Modifier[] | undefined, 1998 typeParameters: readonly TypeParameterDeclaration[] | undefined, 1999 parameters: readonly ParameterDeclaration[], 2000 type: TypeNode | undefined 2001 ): ConstructorTypeNode { 2002 const node = createBaseSignatureDeclaration<ConstructorTypeNode>( 2003 SyntaxKind.ConstructorType, 2004 modifiers, 2005 /*name*/ undefined, 2006 typeParameters, 2007 parameters, 2008 type 2009 ); 2010 node.transformFlags = TransformFlags.ContainsTypeScript; 2011 return node; 2012 } 2013 2014 /** @deprecated */ 2015 function createConstructorTypeNode2( 2016 typeParameters: readonly TypeParameterDeclaration[] | undefined, 2017 parameters: readonly ParameterDeclaration[], 2018 type: TypeNode | undefined 2019 ): ConstructorTypeNode { 2020 return createConstructorTypeNode1(/*modifiers*/ undefined, typeParameters, parameters, type); 2021 } 2022 2023 // @api 2024 function updateConstructorTypeNode(...args: Parameters<typeof updateConstructorTypeNode1 | typeof updateConstructorTypeNode2>) { 2025 return args.length === 5 ? updateConstructorTypeNode1(...args) : 2026 args.length === 4 ? updateConstructorTypeNode2(...args) : 2027 Debug.fail("Incorrect number of arguments specified."); 2028 } 2029 2030 function updateConstructorTypeNode1( 2031 node: ConstructorTypeNode, 2032 modifiers: readonly Modifier[] | undefined, 2033 typeParameters: NodeArray<TypeParameterDeclaration> | undefined, 2034 parameters: NodeArray<ParameterDeclaration>, 2035 type: TypeNode | undefined 2036 ) { 2037 return node.modifiers !== modifiers 2038 || node.typeParameters !== typeParameters 2039 || node.parameters !== parameters 2040 || node.type !== type 2041 ? finishUpdateBaseSignatureDeclaration(createConstructorTypeNode(modifiers, typeParameters, parameters, type), node) 2042 : node; 2043 } 2044 2045 /** @deprecated */ 2046 function updateConstructorTypeNode2( 2047 node: ConstructorTypeNode, 2048 typeParameters: NodeArray<TypeParameterDeclaration> | undefined, 2049 parameters: NodeArray<ParameterDeclaration>, 2050 type: TypeNode | undefined 2051 ) { 2052 return updateConstructorTypeNode1(node, node.modifiers, typeParameters, parameters, type); 2053 } 2054 2055 // @api 2056 function createTypeQueryNode(exprName: EntityName, typeArguments?: readonly TypeNode[]) { 2057 const node = createBaseNode<TypeQueryNode>(SyntaxKind.TypeQuery); 2058 node.exprName = exprName; 2059 node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); 2060 node.transformFlags = TransformFlags.ContainsTypeScript; 2061 return node; 2062 } 2063 2064 // @api 2065 function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName, typeArguments?: readonly TypeNode[]) { 2066 return node.exprName !== exprName 2067 || node.typeArguments !== typeArguments 2068 ? update(createTypeQueryNode(exprName, typeArguments), node) 2069 : node; 2070 } 2071 2072 // @api 2073 function createTypeLiteralNode(members: readonly TypeElement[] | undefined) { 2074 const node = createBaseNode<TypeLiteralNode>(SyntaxKind.TypeLiteral); 2075 node.members = createNodeArray(members); 2076 node.transformFlags = TransformFlags.ContainsTypeScript; 2077 return node; 2078 } 2079 2080 // @api 2081 function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray<TypeElement>) { 2082 return node.members !== members 2083 ? update(createTypeLiteralNode(members), node) 2084 : node; 2085 } 2086 2087 // @api 2088 function createArrayTypeNode(elementType: TypeNode) { 2089 const node = createBaseNode<ArrayTypeNode>(SyntaxKind.ArrayType); 2090 node.elementType = parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(elementType); 2091 node.transformFlags = TransformFlags.ContainsTypeScript; 2092 return node; 2093 } 2094 2095 // @api 2096 function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode { 2097 return node.elementType !== elementType 2098 ? update(createArrayTypeNode(elementType), node) 2099 : node; 2100 } 2101 2102 // @api 2103 function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]) { 2104 const node = createBaseNode<TupleTypeNode>(SyntaxKind.TupleType); 2105 node.elements = createNodeArray(parenthesizerRules().parenthesizeElementTypesOfTupleType(elements)); 2106 node.transformFlags = TransformFlags.ContainsTypeScript; 2107 return node; 2108 } 2109 2110 // @api 2111 function updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]) { 2112 return node.elements !== elements 2113 ? update(createTupleTypeNode(elements), node) 2114 : node; 2115 } 2116 2117 // @api 2118 function createNamedTupleMember(dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode) { 2119 const node = createBaseNode<NamedTupleMember>(SyntaxKind.NamedTupleMember); 2120 node.dotDotDotToken = dotDotDotToken; 2121 node.name = name; 2122 node.questionToken = questionToken; 2123 node.type = type; 2124 node.transformFlags = TransformFlags.ContainsTypeScript; 2125 return node; 2126 } 2127 2128 // @api 2129 function updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode) { 2130 return node.dotDotDotToken !== dotDotDotToken 2131 || node.name !== name 2132 || node.questionToken !== questionToken 2133 || node.type !== type 2134 ? update(createNamedTupleMember(dotDotDotToken, name, questionToken, type), node) 2135 : node; 2136 } 2137 2138 // @api 2139 function createOptionalTypeNode(type: TypeNode) { 2140 const node = createBaseNode<OptionalTypeNode>(SyntaxKind.OptionalType); 2141 node.type = parenthesizerRules().parenthesizeTypeOfOptionalType(type); 2142 node.transformFlags = TransformFlags.ContainsTypeScript; 2143 return node; 2144 } 2145 2146 // @api 2147 function updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode { 2148 return node.type !== type 2149 ? update(createOptionalTypeNode(type), node) 2150 : node; 2151 } 2152 2153 // @api 2154 function createRestTypeNode(type: TypeNode) { 2155 const node = createBaseNode<RestTypeNode>(SyntaxKind.RestType); 2156 node.type = type; 2157 node.transformFlags = TransformFlags.ContainsTypeScript; 2158 return node; 2159 } 2160 2161 // @api 2162 function updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode { 2163 return node.type !== type 2164 ? update(createRestTypeNode(type), node) 2165 : node; 2166 } 2167 2168 function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: readonly TypeNode[], parenthesize: (nodes: readonly TypeNode[]) => readonly TypeNode[]) { 2169 const node = createBaseNode<UnionTypeNode | IntersectionTypeNode>(kind); 2170 node.types = factory.createNodeArray(parenthesize(types)); 2171 node.transformFlags = TransformFlags.ContainsTypeScript; 2172 return node; 2173 } 2174 2175 function updateUnionOrIntersectionTypeNode<T extends UnionOrIntersectionTypeNode>(node: T, types: NodeArray<TypeNode>, parenthesize: (nodes: readonly TypeNode[]) => readonly TypeNode[]): T { 2176 return node.types !== types 2177 ? update(createUnionOrIntersectionTypeNode(node.kind, types, parenthesize) as T, node) 2178 : node; 2179 } 2180 2181 // @api 2182 function createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode { 2183 return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, types, parenthesizerRules().parenthesizeConstituentTypesOfUnionType) as UnionTypeNode; 2184 } 2185 2186 // @api 2187 function updateUnionTypeNode(node: UnionTypeNode, types: NodeArray<TypeNode>) { 2188 return updateUnionOrIntersectionTypeNode(node, types, parenthesizerRules().parenthesizeConstituentTypesOfUnionType); 2189 } 2190 2191 // @api 2192 function createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode { 2193 return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, types, parenthesizerRules().parenthesizeConstituentTypesOfIntersectionType) as IntersectionTypeNode; 2194 } 2195 2196 // @api 2197 function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray<TypeNode>) { 2198 return updateUnionOrIntersectionTypeNode(node, types, parenthesizerRules().parenthesizeConstituentTypesOfIntersectionType); 2199 } 2200 2201 // @api 2202 function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { 2203 const node = createBaseNode<ConditionalTypeNode>(SyntaxKind.ConditionalType); 2204 node.checkType = parenthesizerRules().parenthesizeCheckTypeOfConditionalType(checkType); 2205 node.extendsType = parenthesizerRules().parenthesizeExtendsTypeOfConditionalType(extendsType); 2206 node.trueType = trueType; 2207 node.falseType = falseType; 2208 node.transformFlags = TransformFlags.ContainsTypeScript; 2209 return node; 2210 } 2211 2212 // @api 2213 function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { 2214 return node.checkType !== checkType 2215 || node.extendsType !== extendsType 2216 || node.trueType !== trueType 2217 || node.falseType !== falseType 2218 ? update(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node) 2219 : node; 2220 } 2221 2222 // @api 2223 function createInferTypeNode(typeParameter: TypeParameterDeclaration) { 2224 const node = createBaseNode<InferTypeNode>(SyntaxKind.InferType); 2225 node.typeParameter = typeParameter; 2226 node.transformFlags = TransformFlags.ContainsTypeScript; 2227 return node; 2228 } 2229 2230 // @api 2231 function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration) { 2232 return node.typeParameter !== typeParameter 2233 ? update(createInferTypeNode(typeParameter), node) 2234 : node; 2235 } 2236 2237 // @api 2238 function createTemplateLiteralType(head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]) { 2239 const node = createBaseNode<TemplateLiteralTypeNode>(SyntaxKind.TemplateLiteralType); 2240 node.head = head; 2241 node.templateSpans = createNodeArray(templateSpans); 2242 node.transformFlags = TransformFlags.ContainsTypeScript; 2243 return node; 2244 } 2245 2246 // @api 2247 function updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: readonly TemplateLiteralTypeSpan[]) { 2248 return node.head !== head 2249 || node.templateSpans !== templateSpans 2250 ? update(createTemplateLiteralType(head, templateSpans), node) 2251 : node; 2252 } 2253 2254 // @api 2255 function createImportTypeNode( 2256 argument: TypeNode, 2257 assertions?: ImportTypeAssertionContainer, 2258 qualifier?: EntityName, 2259 typeArguments?: readonly TypeNode[], 2260 isTypeOf = false 2261 ): ImportTypeNode { 2262 const node = createBaseNode<ImportTypeNode>(SyntaxKind.ImportType); 2263 node.argument = argument; 2264 node.assertions = assertions; 2265 node.qualifier = qualifier; 2266 node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); 2267 node.isTypeOf = isTypeOf; 2268 node.transformFlags = TransformFlags.ContainsTypeScript; 2269 return node; 2270 } 2271 2272 // @api 2273 function updateImportTypeNode( 2274 node: ImportTypeNode, 2275 argument: TypeNode, 2276 assertions: ImportTypeAssertionContainer | undefined, 2277 qualifier: EntityName | undefined, 2278 typeArguments: readonly TypeNode[] | undefined, 2279 isTypeOf: boolean = node.isTypeOf 2280 ): ImportTypeNode { 2281 return node.argument !== argument 2282 || node.assertions !== assertions 2283 || node.qualifier !== qualifier 2284 || node.typeArguments !== typeArguments 2285 || node.isTypeOf !== isTypeOf 2286 ? update(createImportTypeNode(argument, assertions, qualifier, typeArguments, isTypeOf), node) 2287 : node; 2288 } 2289 2290 // @api 2291 function createParenthesizedType(type: TypeNode) { 2292 const node = createBaseNode<ParenthesizedTypeNode>(SyntaxKind.ParenthesizedType); 2293 node.type = type; 2294 node.transformFlags = TransformFlags.ContainsTypeScript; 2295 return node; 2296 } 2297 2298 // @api 2299 function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode) { 2300 return node.type !== type 2301 ? update(createParenthesizedType(type), node) 2302 : node; 2303 } 2304 2305 // @api 2306 function createThisTypeNode() { 2307 const node = createBaseNode<ThisTypeNode>(SyntaxKind.ThisType); 2308 node.transformFlags = TransformFlags.ContainsTypeScript; 2309 return node; 2310 } 2311 2312 // @api 2313 function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode { 2314 const node = createBaseNode<TypeOperatorNode>(SyntaxKind.TypeOperator); 2315 node.operator = operator; 2316 node.type = operator === SyntaxKind.ReadonlyKeyword ? 2317 parenthesizerRules().parenthesizeOperandOfReadonlyTypeOperator(type) : 2318 parenthesizerRules().parenthesizeOperandOfTypeOperator(type); 2319 node.transformFlags = TransformFlags.ContainsTypeScript; 2320 return node; 2321 } 2322 2323 // @api 2324 function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) { 2325 return node.type !== type 2326 ? update(createTypeOperatorNode(node.operator, type), node) 2327 : node; 2328 } 2329 2330 // @api 2331 function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) { 2332 const node = createBaseNode<IndexedAccessTypeNode>(SyntaxKind.IndexedAccessType); 2333 node.objectType = parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(objectType); 2334 node.indexType = indexType; 2335 node.transformFlags = TransformFlags.ContainsTypeScript; 2336 return node; 2337 } 2338 2339 // @api 2340 function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) { 2341 return node.objectType !== objectType 2342 || node.indexType !== indexType 2343 ? update(createIndexedAccessTypeNode(objectType, indexType), node) 2344 : node; 2345 } 2346 2347 // @api 2348 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 { 2349 const node = createBaseNode<MappedTypeNode>(SyntaxKind.MappedType); 2350 node.readonlyToken = readonlyToken; 2351 node.typeParameter = typeParameter; 2352 node.nameType = nameType; 2353 node.questionToken = questionToken; 2354 node.type = type; 2355 node.members = members && createNodeArray(members); 2356 node.transformFlags = TransformFlags.ContainsTypeScript; 2357 return node; 2358 } 2359 2360 // @api 2361 function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, nameType: TypeNode | undefined, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined, members: readonly TypeElement[] | undefined): MappedTypeNode { 2362 return node.readonlyToken !== readonlyToken 2363 || node.typeParameter !== typeParameter 2364 || node.nameType !== nameType 2365 || node.questionToken !== questionToken 2366 || node.type !== type 2367 || node.members !== members 2368 ? update(createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type, members), node) 2369 : node; 2370 } 2371 2372 // @api 2373 function createLiteralTypeNode(literal: LiteralTypeNode["literal"]) { 2374 const node = createBaseNode<LiteralTypeNode>(SyntaxKind.LiteralType); 2375 node.literal = literal; 2376 node.transformFlags = TransformFlags.ContainsTypeScript; 2377 return node; 2378 } 2379 2380 // @api 2381 function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]) { 2382 return node.literal !== literal 2383 ? update(createLiteralTypeNode(literal), node) 2384 : node; 2385 } 2386 2387 // 2388 // Binding Patterns 2389 // 2390 2391 // @api 2392 function createObjectBindingPattern(elements: readonly BindingElement[]) { 2393 const node = createBaseNode<ObjectBindingPattern>(SyntaxKind.ObjectBindingPattern); 2394 node.elements = createNodeArray(elements); 2395 node.transformFlags |= 2396 propagateChildrenFlags(node.elements) | 2397 TransformFlags.ContainsES2015 | 2398 TransformFlags.ContainsBindingPattern; 2399 if (node.transformFlags & TransformFlags.ContainsRestOrSpread) { 2400 node.transformFlags |= 2401 TransformFlags.ContainsES2018 | 2402 TransformFlags.ContainsObjectRestOrSpread; 2403 } 2404 return node; 2405 } 2406 2407 // @api 2408 function updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]) { 2409 return node.elements !== elements 2410 ? update(createObjectBindingPattern(elements), node) 2411 : node; 2412 } 2413 2414 // @api 2415 function createArrayBindingPattern(elements: readonly ArrayBindingElement[]) { 2416 const node = createBaseNode<ArrayBindingPattern>(SyntaxKind.ArrayBindingPattern); 2417 node.elements = createNodeArray(elements); 2418 node.transformFlags |= 2419 propagateChildrenFlags(node.elements) | 2420 TransformFlags.ContainsES2015 | 2421 TransformFlags.ContainsBindingPattern; 2422 return node; 2423 } 2424 2425 // @api 2426 function updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]) { 2427 return node.elements !== elements 2428 ? update(createArrayBindingPattern(elements), node) 2429 : node; 2430 } 2431 2432 // @api 2433 function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression) { 2434 const node = createBaseBindingLikeDeclaration<BindingElement>( 2435 SyntaxKind.BindingElement, 2436 /*modifiers*/ undefined, 2437 name, 2438 initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer) 2439 ); 2440 node.propertyName = asName(propertyName); 2441 node.dotDotDotToken = dotDotDotToken; 2442 node.transformFlags |= 2443 propagateChildFlags(node.dotDotDotToken) | 2444 TransformFlags.ContainsES2015; 2445 if (node.propertyName) { 2446 node.transformFlags |= isIdentifier(node.propertyName) ? 2447 propagateIdentifierNameFlags(node.propertyName) : 2448 propagateChildFlags(node.propertyName); 2449 } 2450 if (dotDotDotToken) node.transformFlags |= TransformFlags.ContainsRestOrSpread; 2451 return node; 2452 } 2453 2454 // @api 2455 function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined) { 2456 return node.propertyName !== propertyName 2457 || node.dotDotDotToken !== dotDotDotToken 2458 || node.name !== name 2459 || node.initializer !== initializer 2460 ? update(createBindingElement(dotDotDotToken, propertyName, name, initializer), node) 2461 : node; 2462 } 2463 2464 // 2465 // Expression 2466 // 2467 2468 function createBaseExpression<T extends Expression>(kind: T["kind"]) { 2469 const node = createBaseNode(kind); 2470 // the following properties are commonly set by the checker/binder 2471 return node; 2472 } 2473 2474 // @api 2475 function createArrayLiteralExpression(elements?: readonly Expression[], multiLine?: boolean) { 2476 const node = createBaseExpression<ArrayLiteralExpression>(SyntaxKind.ArrayLiteralExpression); 2477 // Ensure we add a trailing comma for something like `[NumericLiteral(1), NumericLiteral(2), OmittedExpresion]` so that 2478 // we end up with `[1, 2, ,]` instead of `[1, 2, ]` otherwise the `OmittedExpression` will just end up being treated like 2479 // a trailing comma. 2480 const lastElement = elements && lastOrUndefined(elements); 2481 const elementsArray = createNodeArray(elements, lastElement && isOmittedExpression(lastElement) ? true : undefined); 2482 node.elements = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(elementsArray); 2483 node.multiLine = multiLine; 2484 node.transformFlags |= propagateChildrenFlags(node.elements); 2485 return node; 2486 } 2487 2488 // @api 2489 function updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]) { 2490 return node.elements !== elements 2491 ? update(createArrayLiteralExpression(elements, node.multiLine), node) 2492 : node; 2493 } 2494 2495 // @api 2496 function createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean) { 2497 const node = createBaseExpression<ObjectLiteralExpression>(SyntaxKind.ObjectLiteralExpression); 2498 node.properties = createNodeArray(properties); 2499 node.multiLine = multiLine; 2500 node.transformFlags |= propagateChildrenFlags(node.properties); 2501 return node; 2502 } 2503 2504 // @api 2505 function updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]) { 2506 return node.properties !== properties 2507 ? update(createObjectLiteralExpression(properties, node.multiLine), node) 2508 : node; 2509 } 2510 2511 // @api 2512 function createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier) { 2513 const node = createBaseExpression<PropertyAccessExpression>(SyntaxKind.PropertyAccessExpression); 2514 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); 2515 node.name = asName(name); 2516 node.transformFlags = 2517 propagateChildFlags(node.expression) | 2518 (isIdentifier(node.name) ? 2519 propagateIdentifierNameFlags(node.name) : 2520 propagateChildFlags(node.name) | TransformFlags.ContainsPrivateIdentifierInExpression); 2521 if (isSuperKeyword(expression)) { 2522 // super method calls require a lexical 'this' 2523 // super method calls require 'super' hoisting in ES2017 and ES2018 async functions and async generators 2524 node.transformFlags |= 2525 TransformFlags.ContainsES2017 | 2526 TransformFlags.ContainsES2018; 2527 } 2528 return node; 2529 } 2530 2531 // @api 2532 function updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) { 2533 if (isPropertyAccessChain(node)) { 2534 return updatePropertyAccessChain(node, expression, node.questionDotToken, cast(name, isIdentifier)); 2535 } 2536 return node.expression !== expression 2537 || node.name !== name 2538 ? update(createPropertyAccessExpression(expression, name), node) 2539 : node; 2540 } 2541 2542 // @api 2543 function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier) { 2544 const node = createBaseExpression<PropertyAccessChain>(SyntaxKind.PropertyAccessExpression); 2545 node.flags |= NodeFlags.OptionalChain; 2546 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ true); 2547 node.questionDotToken = questionDotToken; 2548 node.name = asName(name); 2549 node.transformFlags |= 2550 TransformFlags.ContainsES2020 | 2551 propagateChildFlags(node.expression) | 2552 propagateChildFlags(node.questionDotToken) | 2553 (isIdentifier(node.name) ? 2554 propagateIdentifierNameFlags(node.name) : 2555 propagateChildFlags(node.name) | TransformFlags.ContainsPrivateIdentifierInExpression); 2556 return node; 2557 } 2558 2559 // @api 2560 function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier) { 2561 Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a PropertyAccessExpression using updatePropertyAccessChain. Use updatePropertyAccess instead."); 2562 // Because we are updating an existing PropertyAccessChain we want to inherit its emitFlags 2563 // instead of using the default from createPropertyAccess 2564 return node.expression !== expression 2565 || node.questionDotToken !== questionDotToken 2566 || node.name !== name 2567 ? update(createPropertyAccessChain(expression, questionDotToken, name), node) 2568 : node; 2569 } 2570 2571 // @api 2572 function createElementAccessExpression(expression: Expression, index: number | Expression) { 2573 const node = createBaseExpression<ElementAccessExpression>(SyntaxKind.ElementAccessExpression); 2574 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); 2575 node.argumentExpression = asExpression(index); 2576 node.transformFlags |= 2577 propagateChildFlags(node.expression) | 2578 propagateChildFlags(node.argumentExpression); 2579 if (isSuperKeyword(expression)) { 2580 // super method calls require a lexical 'this' 2581 // super method calls require 'super' hoisting in ES2017 and ES2018 async functions and async generators 2582 node.transformFlags |= 2583 TransformFlags.ContainsES2017 | 2584 TransformFlags.ContainsES2018; 2585 } 2586 return node; 2587 } 2588 2589 // @api 2590 function updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) { 2591 if (isElementAccessChain(node)) { 2592 return updateElementAccessChain(node, expression, node.questionDotToken, argumentExpression); 2593 } 2594 return node.expression !== expression 2595 || node.argumentExpression !== argumentExpression 2596 ? update(createElementAccessExpression(expression, argumentExpression), node) 2597 : node; 2598 } 2599 2600 // @api 2601 function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression) { 2602 const node = createBaseExpression<ElementAccessChain>(SyntaxKind.ElementAccessExpression); 2603 node.flags |= NodeFlags.OptionalChain; 2604 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ true); 2605 node.questionDotToken = questionDotToken; 2606 node.argumentExpression = asExpression(index); 2607 node.transformFlags |= 2608 propagateChildFlags(node.expression) | 2609 propagateChildFlags(node.questionDotToken) | 2610 propagateChildFlags(node.argumentExpression) | 2611 TransformFlags.ContainsES2020; 2612 return node; 2613 } 2614 2615 // @api 2616 function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression) { 2617 Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a ElementAccessExpression using updateElementAccessChain. Use updateElementAccess instead."); 2618 // Because we are updating an existing ElementAccessChain we want to inherit its emitFlags 2619 // instead of using the default from createElementAccess 2620 return node.expression !== expression 2621 || node.questionDotToken !== questionDotToken 2622 || node.argumentExpression !== argumentExpression 2623 ? update(createElementAccessChain(expression, questionDotToken, argumentExpression), node) 2624 : node; 2625 } 2626 2627 // @api 2628 function createCallExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { 2629 const node = createBaseExpression<CallExpression>(SyntaxKind.CallExpression); 2630 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); 2631 node.typeArguments = asNodeArray(typeArguments); 2632 node.arguments = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(createNodeArray(argumentsArray)); 2633 node.transformFlags |= 2634 propagateChildFlags(node.expression) | 2635 propagateChildrenFlags(node.typeArguments) | 2636 propagateChildrenFlags(node.arguments); 2637 if (node.typeArguments) { 2638 node.transformFlags |= TransformFlags.ContainsTypeScript; 2639 } 2640 if (isImportKeyword(node.expression)) { 2641 node.transformFlags |= TransformFlags.ContainsDynamicImport; 2642 } 2643 else if (isSuperProperty(node.expression)) { 2644 node.transformFlags |= TransformFlags.ContainsLexicalThis; 2645 } 2646 return node; 2647 } 2648 2649 // @api 2650 function updateCallExpression(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) { 2651 if (isCallChain(node)) { 2652 return updateCallChain(node, expression, node.questionDotToken, typeArguments, argumentsArray); 2653 } 2654 return node.expression !== expression 2655 || node.typeArguments !== typeArguments 2656 || node.arguments !== argumentsArray 2657 ? update(createCallExpression(expression, typeArguments, argumentsArray), node) 2658 : node; 2659 } 2660 2661 // @api 2662 function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { 2663 const node = createBaseExpression<CallChain>(SyntaxKind.CallExpression); 2664 node.flags |= NodeFlags.OptionalChain; 2665 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ true); 2666 node.questionDotToken = questionDotToken; 2667 node.typeArguments = asNodeArray(typeArguments); 2668 node.arguments = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(createNodeArray(argumentsArray)); 2669 node.transformFlags |= 2670 propagateChildFlags(node.expression) | 2671 propagateChildFlags(node.questionDotToken) | 2672 propagateChildrenFlags(node.typeArguments) | 2673 propagateChildrenFlags(node.arguments) | 2674 TransformFlags.ContainsES2020; 2675 if (node.typeArguments) { 2676 node.transformFlags |= TransformFlags.ContainsTypeScript; 2677 } 2678 if (isSuperProperty(node.expression)) { 2679 node.transformFlags |= TransformFlags.ContainsLexicalThis; 2680 } 2681 return node; 2682 } 2683 2684 // @api 2685 function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) { 2686 Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a CallExpression using updateCallChain. Use updateCall instead."); 2687 return node.expression !== expression 2688 || node.questionDotToken !== questionDotToken 2689 || node.typeArguments !== typeArguments 2690 || node.arguments !== argumentsArray 2691 ? update(createCallChain(expression, questionDotToken, typeArguments, argumentsArray), node) 2692 : node; 2693 } 2694 2695 // @api 2696 function createNewExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { 2697 const node = createBaseExpression<NewExpression>(SyntaxKind.NewExpression); 2698 node.expression = parenthesizerRules().parenthesizeExpressionOfNew(expression); 2699 node.typeArguments = asNodeArray(typeArguments); 2700 node.arguments = argumentsArray ? parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(argumentsArray) : undefined; 2701 node.transformFlags |= 2702 propagateChildFlags(node.expression) | 2703 propagateChildrenFlags(node.typeArguments) | 2704 propagateChildrenFlags(node.arguments) | 2705 TransformFlags.ContainsES2020; 2706 if (node.typeArguments) { 2707 node.transformFlags |= TransformFlags.ContainsTypeScript; 2708 } 2709 return node; 2710 } 2711 2712 // @api 2713 function updateNewExpression(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { 2714 return node.expression !== expression 2715 || node.typeArguments !== typeArguments 2716 || node.arguments !== argumentsArray 2717 ? update(createNewExpression(expression, typeArguments, argumentsArray), node) 2718 : node; 2719 } 2720 2721 // @api 2722 function createTaggedTemplateExpression(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral) { 2723 const node = createBaseExpression<TaggedTemplateExpression>(SyntaxKind.TaggedTemplateExpression); 2724 node.tag = parenthesizerRules().parenthesizeLeftSideOfAccess(tag, /*optionalChain*/ false); 2725 node.typeArguments = asNodeArray(typeArguments); 2726 node.template = template; 2727 node.transformFlags |= 2728 propagateChildFlags(node.tag) | 2729 propagateChildrenFlags(node.typeArguments) | 2730 propagateChildFlags(node.template) | 2731 TransformFlags.ContainsES2015; 2732 if (node.typeArguments) { 2733 node.transformFlags |= TransformFlags.ContainsTypeScript; 2734 } 2735 if (hasInvalidEscape(node.template)) { 2736 node.transformFlags |= TransformFlags.ContainsES2018; 2737 } 2738 return node; 2739 } 2740 2741 // @api 2742 function updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral) { 2743 return node.tag !== tag 2744 || node.typeArguments !== typeArguments 2745 || node.template !== template 2746 ? update(createTaggedTemplateExpression(tag, typeArguments, template), node) 2747 : node; 2748 } 2749 2750 // @api 2751 function createTypeAssertion(type: TypeNode, expression: Expression) { 2752 const node = createBaseExpression<TypeAssertion>(SyntaxKind.TypeAssertionExpression); 2753 node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); 2754 node.type = type; 2755 node.transformFlags |= 2756 propagateChildFlags(node.expression) | 2757 propagateChildFlags(node.type) | 2758 TransformFlags.ContainsTypeScript; 2759 return node; 2760 } 2761 2762 // @api 2763 function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression) { 2764 return node.type !== type 2765 || node.expression !== expression 2766 ? update(createTypeAssertion(type, expression), node) 2767 : node; 2768 } 2769 2770 // @api 2771 function createParenthesizedExpression(expression: Expression) { 2772 const node = createBaseExpression<ParenthesizedExpression>(SyntaxKind.ParenthesizedExpression); 2773 node.expression = expression; 2774 node.transformFlags = propagateChildFlags(node.expression); 2775 return node; 2776 } 2777 2778 // @api 2779 function updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression) { 2780 return node.expression !== expression 2781 ? update(createParenthesizedExpression(expression), node) 2782 : node; 2783 } 2784 2785 // @api 2786 function createFunctionExpression( 2787 modifiers: readonly ModifierLike[] | undefined, 2788 asteriskToken: AsteriskToken | undefined, 2789 name: string | Identifier | undefined, 2790 typeParameters: readonly TypeParameterDeclaration[] | undefined, 2791 parameters: readonly ParameterDeclaration[] | undefined, 2792 type: TypeNode | undefined, 2793 body: Block 2794 ) { 2795 const node = createBaseFunctionLikeDeclaration<FunctionExpression>( 2796 SyntaxKind.FunctionExpression, 2797 modifiers, 2798 name, 2799 typeParameters, 2800 parameters, 2801 type, 2802 body 2803 ); 2804 node.asteriskToken = asteriskToken; 2805 node.transformFlags |= propagateChildFlags(node.asteriskToken); 2806 if (node.typeParameters) { 2807 node.transformFlags |= TransformFlags.ContainsTypeScript; 2808 } 2809 if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { 2810 if (node.asteriskToken) { 2811 node.transformFlags |= TransformFlags.ContainsES2018; 2812 } 2813 else { 2814 node.transformFlags |= TransformFlags.ContainsES2017; 2815 } 2816 } 2817 else if (node.asteriskToken) { 2818 node.transformFlags |= TransformFlags.ContainsGenerator; 2819 } 2820 return node; 2821 } 2822 2823 // @api 2824 function updateFunctionExpression( 2825 node: FunctionExpression, 2826 modifiers: readonly ModifierLike[] | undefined, 2827 asteriskToken: AsteriskToken | undefined, 2828 name: Identifier | undefined, 2829 typeParameters: readonly TypeParameterDeclaration[] | undefined, 2830 parameters: readonly ParameterDeclaration[], 2831 type: TypeNode | undefined, 2832 body: Block 2833 ) { 2834 return node.name !== name 2835 || node.modifiers !== modifiers 2836 || node.asteriskToken !== asteriskToken 2837 || node.typeParameters !== typeParameters 2838 || node.parameters !== parameters 2839 || node.type !== type 2840 || node.body !== body 2841 ? finishUpdateBaseSignatureDeclaration(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) 2842 : node; 2843 } 2844 2845 // @api 2846 function createEtsComponentExpression( 2847 name: Expression, 2848 argumentsArray: readonly Expression[] | undefined, 2849 body: Block | undefined 2850 ) { 2851 const node = createBaseExpression<EtsComponentExpression>(SyntaxKind.EtsComponentExpression); 2852 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(name); 2853 node.arguments = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(createNodeArray(argumentsArray)); 2854 node.body = body; 2855 return node; 2856 } 2857 2858 // @api 2859 function updateEtsComponentExpression( 2860 node: EtsComponentExpression, 2861 name: Expression, 2862 argumentsArray: readonly Expression[] | undefined, 2863 body: Block | undefined 2864 ) { 2865 return node.expression !== name 2866 || node.arguments !== argumentsArray 2867 || node.body !== body 2868 ? createEtsComponentExpression(name, argumentsArray, body) 2869 : node; 2870 } 2871 2872 // @api 2873 function createArrowFunction( 2874 modifiers: readonly ModifierLike[] | undefined, 2875 typeParameters: readonly TypeParameterDeclaration[] | undefined, 2876 parameters: readonly ParameterDeclaration[], 2877 type: TypeNode | undefined, 2878 equalsGreaterThanToken: EqualsGreaterThanToken | undefined, 2879 body: ConciseBody 2880 ) { 2881 const node = createBaseFunctionLikeDeclaration<ArrowFunction>( 2882 SyntaxKind.ArrowFunction, 2883 modifiers, 2884 /*name*/ undefined, 2885 typeParameters, 2886 parameters, 2887 type, 2888 parenthesizerRules().parenthesizeConciseBodyOfArrowFunction(body) 2889 ); 2890 node.equalsGreaterThanToken = equalsGreaterThanToken ?? createToken(SyntaxKind.EqualsGreaterThanToken); 2891 node.transformFlags |= 2892 propagateChildFlags(node.equalsGreaterThanToken) | 2893 TransformFlags.ContainsES2015; 2894 if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { 2895 node.transformFlags |= TransformFlags.ContainsES2017 | TransformFlags.ContainsLexicalThis; 2896 } 2897 return node; 2898 } 2899 2900 // @api 2901 function updateArrowFunction( 2902 node: ArrowFunction, 2903 modifiers: readonly ModifierLike[] | undefined, 2904 typeParameters: readonly TypeParameterDeclaration[] | undefined, 2905 parameters: readonly ParameterDeclaration[], 2906 type: TypeNode | undefined, 2907 equalsGreaterThanToken: EqualsGreaterThanToken, 2908 body: ConciseBody 2909 ): ArrowFunction { 2910 return node.modifiers !== modifiers 2911 || node.typeParameters !== typeParameters 2912 || node.parameters !== parameters 2913 || node.type !== type 2914 || node.equalsGreaterThanToken !== equalsGreaterThanToken 2915 || node.body !== body 2916 ? finishUpdateBaseSignatureDeclaration(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) 2917 : node; 2918 } 2919 2920 // @api 2921 function createDeleteExpression(expression: Expression) { 2922 const node = createBaseExpression<DeleteExpression>(SyntaxKind.DeleteExpression); 2923 node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); 2924 node.transformFlags |= propagateChildFlags(node.expression); 2925 return node; 2926 } 2927 2928 // @api 2929 function updateDeleteExpression(node: DeleteExpression, expression: Expression) { 2930 return node.expression !== expression 2931 ? update(createDeleteExpression(expression), node) 2932 : node; 2933 } 2934 2935 // @api 2936 function createTypeOfExpression(expression: Expression) { 2937 const node = createBaseExpression<TypeOfExpression>(SyntaxKind.TypeOfExpression); 2938 node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); 2939 node.transformFlags |= propagateChildFlags(node.expression); 2940 return node; 2941 } 2942 2943 // @api 2944 function updateTypeOfExpression(node: TypeOfExpression, expression: Expression) { 2945 return node.expression !== expression 2946 ? update(createTypeOfExpression(expression), node) 2947 : node; 2948 } 2949 2950 // @api 2951 function createVoidExpression(expression: Expression) { 2952 const node = createBaseExpression<VoidExpression>(SyntaxKind.VoidExpression); 2953 node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); 2954 node.transformFlags |= propagateChildFlags(node.expression); 2955 return node; 2956 } 2957 2958 // @api 2959 function updateVoidExpression(node: VoidExpression, expression: Expression) { 2960 return node.expression !== expression 2961 ? update(createVoidExpression(expression), node) 2962 : node; 2963 } 2964 2965 // @api 2966 function createAwaitExpression(expression: Expression) { 2967 const node = createBaseExpression<AwaitExpression>(SyntaxKind.AwaitExpression); 2968 node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); 2969 node.transformFlags |= 2970 propagateChildFlags(node.expression) | 2971 TransformFlags.ContainsES2017 | 2972 TransformFlags.ContainsES2018 | 2973 TransformFlags.ContainsAwait; 2974 return node; 2975 } 2976 2977 // @api 2978 function updateAwaitExpression(node: AwaitExpression, expression: Expression) { 2979 return node.expression !== expression 2980 ? update(createAwaitExpression(expression), node) 2981 : node; 2982 } 2983 2984 // @api 2985 function createPrefixUnaryExpression(operator: PrefixUnaryOperator, operand: Expression) { 2986 const node = createBaseExpression<PrefixUnaryExpression>(SyntaxKind.PrefixUnaryExpression); 2987 node.operator = operator; 2988 node.operand = parenthesizerRules().parenthesizeOperandOfPrefixUnary(operand); 2989 node.transformFlags |= propagateChildFlags(node.operand); 2990 // Only set this flag for non-generated identifiers and non-"local" names. See the 2991 // comment in `visitPreOrPostfixUnaryExpression` in module.ts 2992 if ((operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken) && 2993 isIdentifier(node.operand) && 2994 !isGeneratedIdentifier(node.operand) && 2995 !isLocalName(node.operand)) { 2996 node.transformFlags |= TransformFlags.ContainsUpdateExpressionForIdentifier; 2997 } 2998 return node; 2999 } 3000 3001 // @api 3002 function updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression) { 3003 return node.operand !== operand 3004 ? update(createPrefixUnaryExpression(node.operator, operand), node) 3005 : node; 3006 } 3007 3008 // @api 3009 function createPostfixUnaryExpression(operand: Expression, operator: PostfixUnaryOperator) { 3010 const node = createBaseExpression<PostfixUnaryExpression>(SyntaxKind.PostfixUnaryExpression); 3011 node.operator = operator; 3012 node.operand = parenthesizerRules().parenthesizeOperandOfPostfixUnary(operand); 3013 node.transformFlags |= propagateChildFlags(node.operand); 3014 // Only set this flag for non-generated identifiers and non-"local" names. See the 3015 // comment in `visitPreOrPostfixUnaryExpression` in module.ts 3016 if (isIdentifier(node.operand) && 3017 !isGeneratedIdentifier(node.operand) && 3018 !isLocalName(node.operand)) { 3019 node.transformFlags |= TransformFlags.ContainsUpdateExpressionForIdentifier; 3020 } 3021 return node; 3022 } 3023 3024 // @api 3025 function updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression) { 3026 return node.operand !== operand 3027 ? update(createPostfixUnaryExpression(operand, node.operator), node) 3028 : node; 3029 } 3030 3031 // @api 3032 function createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression) { 3033 const node = createBaseExpression<BinaryExpression>(SyntaxKind.BinaryExpression); 3034 const operatorToken = asToken(operator); 3035 const operatorKind = operatorToken.kind; 3036 node.left = parenthesizerRules().parenthesizeLeftSideOfBinary(operatorKind, left); 3037 node.operatorToken = operatorToken; 3038 node.right = parenthesizerRules().parenthesizeRightSideOfBinary(operatorKind, node.left, right); 3039 node.transformFlags |= 3040 propagateChildFlags(node.left) | 3041 propagateChildFlags(node.operatorToken) | 3042 propagateChildFlags(node.right); 3043 if (operatorKind === SyntaxKind.QuestionQuestionToken) { 3044 node.transformFlags |= TransformFlags.ContainsES2020; 3045 } 3046 else if (operatorKind === SyntaxKind.EqualsToken) { 3047 if (isObjectLiteralExpression(node.left)) { 3048 node.transformFlags |= 3049 TransformFlags.ContainsES2015 | 3050 TransformFlags.ContainsES2018 | 3051 TransformFlags.ContainsDestructuringAssignment | 3052 propagateAssignmentPatternFlags(node.left); 3053 } 3054 else if (isArrayLiteralExpression(node.left)) { 3055 node.transformFlags |= 3056 TransformFlags.ContainsES2015 | 3057 TransformFlags.ContainsDestructuringAssignment | 3058 propagateAssignmentPatternFlags(node.left); 3059 } 3060 } 3061 else if (operatorKind === SyntaxKind.AsteriskAsteriskToken || operatorKind === SyntaxKind.AsteriskAsteriskEqualsToken) { 3062 node.transformFlags |= TransformFlags.ContainsES2016; 3063 } 3064 else if (isLogicalOrCoalescingAssignmentOperator(operatorKind)) { 3065 node.transformFlags |= TransformFlags.ContainsES2021; 3066 } 3067 if (operatorKind === SyntaxKind.InKeyword && isPrivateIdentifier(node.left)) { 3068 node.transformFlags |= TransformFlags.ContainsPrivateIdentifierInExpression; 3069 } 3070 return node; 3071 } 3072 3073 function propagateAssignmentPatternFlags(node: AssignmentPattern): TransformFlags { 3074 if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) return TransformFlags.ContainsObjectRestOrSpread; 3075 if (node.transformFlags & TransformFlags.ContainsES2018) { 3076 // check for nested spread assignments, otherwise '{ x: { a, ...b } = foo } = c' 3077 // will not be correctly interpreted by the ES2018 transformer 3078 for (const element of getElementsOfBindingOrAssignmentPattern(node)) { 3079 const target = getTargetOfBindingOrAssignmentElement(element); 3080 if (target && isAssignmentPattern(target)) { 3081 if (target.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { 3082 return TransformFlags.ContainsObjectRestOrSpread; 3083 } 3084 if (target.transformFlags & TransformFlags.ContainsES2018) { 3085 const flags = propagateAssignmentPatternFlags(target); 3086 if (flags) return flags; 3087 } 3088 } 3089 } 3090 } 3091 return TransformFlags.None; 3092 } 3093 3094 // @api 3095 function updateBinaryExpression(node: BinaryExpression, left: Expression, operator: BinaryOperatorToken, right: Expression) { 3096 return node.left !== left 3097 || node.operatorToken !== operator 3098 || node.right !== right 3099 ? update(createBinaryExpression(left, operator, right), node) 3100 : node; 3101 } 3102 3103 // @api 3104 function createConditionalExpression(condition: Expression, questionToken: QuestionToken | undefined, whenTrue: Expression, colonToken: ColonToken | undefined, whenFalse: Expression) { 3105 const node = createBaseExpression<ConditionalExpression>(SyntaxKind.ConditionalExpression); 3106 node.condition = parenthesizerRules().parenthesizeConditionOfConditionalExpression(condition); 3107 node.questionToken = questionToken ?? createToken(SyntaxKind.QuestionToken); 3108 node.whenTrue = parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenTrue); 3109 node.colonToken = colonToken ?? createToken(SyntaxKind.ColonToken); 3110 node.whenFalse = parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenFalse); 3111 node.transformFlags |= 3112 propagateChildFlags(node.condition) | 3113 propagateChildFlags(node.questionToken) | 3114 propagateChildFlags(node.whenTrue) | 3115 propagateChildFlags(node.colonToken) | 3116 propagateChildFlags(node.whenFalse); 3117 return node; 3118 } 3119 3120 // @api 3121 function updateConditionalExpression( 3122 node: ConditionalExpression, 3123 condition: Expression, 3124 questionToken: Token<SyntaxKind.QuestionToken>, 3125 whenTrue: Expression, 3126 colonToken: Token<SyntaxKind.ColonToken>, 3127 whenFalse: Expression 3128 ): ConditionalExpression { 3129 return node.condition !== condition 3130 || node.questionToken !== questionToken 3131 || node.whenTrue !== whenTrue 3132 || node.colonToken !== colonToken 3133 || node.whenFalse !== whenFalse 3134 ? update(createConditionalExpression(condition, questionToken, whenTrue, colonToken, whenFalse), node) 3135 : node; 3136 } 3137 3138 // @api 3139 function createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]) { 3140 const node = createBaseExpression<TemplateExpression>(SyntaxKind.TemplateExpression); 3141 node.head = head; 3142 node.templateSpans = createNodeArray(templateSpans); 3143 node.transformFlags |= 3144 propagateChildFlags(node.head) | 3145 propagateChildrenFlags(node.templateSpans) | 3146 TransformFlags.ContainsES2015; 3147 return node; 3148 } 3149 3150 // @api 3151 function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]) { 3152 return node.head !== head 3153 || node.templateSpans !== templateSpans 3154 ? update(createTemplateExpression(head, templateSpans), node) 3155 : node; 3156 } 3157 3158 function createTemplateLiteralLikeNodeChecked(kind: TemplateLiteralToken["kind"], text: string | undefined, rawText: string | undefined, templateFlags = TokenFlags.None) { 3159 Debug.assert(!(templateFlags & ~TokenFlags.TemplateLiteralLikeFlags), "Unsupported template flags."); 3160 // NOTE: without the assignment to `undefined`, we don't narrow the initial type of `cooked`. 3161 // eslint-disable-next-line no-undef-init 3162 let cooked: string | object | undefined = undefined; 3163 if (rawText !== undefined && rawText !== text) { 3164 cooked = getCookedText(kind, rawText); 3165 if (typeof cooked === "object") { 3166 return Debug.fail("Invalid raw text"); 3167 } 3168 } 3169 if (text === undefined) { 3170 if (cooked === undefined) { 3171 return Debug.fail("Arguments 'text' and 'rawText' may not both be undefined."); 3172 } 3173 text = cooked; 3174 } 3175 else if (cooked !== undefined) { 3176 Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'."); 3177 } 3178 return createTemplateLiteralLikeNode(kind, text, rawText, templateFlags); 3179 } 3180 3181 // @api 3182 function createTemplateLiteralLikeNode(kind: TemplateLiteralToken["kind"], text: string, rawText: string | undefined, templateFlags: TokenFlags | undefined) { 3183 const node = createBaseToken<TemplateLiteralLikeNode>(kind); 3184 node.text = text; 3185 node.rawText = rawText; 3186 node.templateFlags = templateFlags! & TokenFlags.TemplateLiteralLikeFlags; 3187 node.transformFlags |= TransformFlags.ContainsES2015; 3188 if (node.templateFlags) { 3189 node.transformFlags |= TransformFlags.ContainsES2018; 3190 } 3191 return node; 3192 } 3193 3194 // @api 3195 function createTemplateHead(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { 3196 return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateHead, text, rawText, templateFlags) as TemplateHead; 3197 } 3198 3199 // @api 3200 function createTemplateMiddle(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { 3201 return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateMiddle, text, rawText, templateFlags) as TemplateMiddle; 3202 } 3203 3204 // @api 3205 function createTemplateTail(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { 3206 return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateTail, text, rawText, templateFlags) as TemplateTail; 3207 } 3208 3209 // @api 3210 function createNoSubstitutionTemplateLiteral(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { 3211 return createTemplateLiteralLikeNodeChecked(SyntaxKind.NoSubstitutionTemplateLiteral, text, rawText, templateFlags) as NoSubstitutionTemplateLiteral; 3212 } 3213 3214 // @api 3215 function createYieldExpression(asteriskToken: AsteriskToken | undefined, expression: Expression | undefined): YieldExpression { 3216 Debug.assert(!asteriskToken || !!expression, "A `YieldExpression` with an asteriskToken must have an expression."); 3217 const node = createBaseExpression<YieldExpression>(SyntaxKind.YieldExpression); 3218 node.expression = expression && parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); 3219 node.asteriskToken = asteriskToken; 3220 node.transformFlags |= 3221 propagateChildFlags(node.expression) | 3222 propagateChildFlags(node.asteriskToken) | 3223 TransformFlags.ContainsES2015 | 3224 TransformFlags.ContainsES2018 | 3225 TransformFlags.ContainsYield; 3226 return node; 3227 } 3228 3229 // @api 3230 function updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression) { 3231 return node.expression !== expression 3232 || node.asteriskToken !== asteriskToken 3233 ? update(createYieldExpression(asteriskToken, expression), node) 3234 : node; 3235 } 3236 3237 // @api 3238 function createSpreadElement(expression: Expression) { 3239 const node = createBaseExpression<SpreadElement>(SyntaxKind.SpreadElement); 3240 node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); 3241 node.transformFlags |= 3242 propagateChildFlags(node.expression) | 3243 TransformFlags.ContainsES2015 | 3244 TransformFlags.ContainsRestOrSpread; 3245 return node; 3246 } 3247 3248 // @api 3249 function updateSpreadElement(node: SpreadElement, expression: Expression) { 3250 return node.expression !== expression 3251 ? update(createSpreadElement(expression), node) 3252 : node; 3253 } 3254 3255 // @api 3256 function createClassExpression( 3257 modifiers: readonly ModifierLike[] | undefined, 3258 name: string | Identifier | undefined, 3259 typeParameters: readonly TypeParameterDeclaration[] | undefined, 3260 heritageClauses: readonly HeritageClause[] | undefined, 3261 members: readonly ClassElement[] 3262 ) { 3263 const node = createBaseClassLikeDeclaration<ClassExpression>( 3264 SyntaxKind.ClassExpression, 3265 modifiers, 3266 name, 3267 typeParameters, 3268 heritageClauses, 3269 members 3270 ); 3271 node.transformFlags |= TransformFlags.ContainsES2015; 3272 return node; 3273 } 3274 3275 // @api 3276 function updateClassExpression( 3277 node: ClassExpression, 3278 modifiers: readonly ModifierLike[] | undefined, 3279 name: Identifier | undefined, 3280 typeParameters: readonly TypeParameterDeclaration[] | undefined, 3281 heritageClauses: readonly HeritageClause[] | undefined, 3282 members: readonly ClassElement[] 3283 ) { 3284 return node.modifiers !== modifiers 3285 || node.name !== name 3286 || node.typeParameters !== typeParameters 3287 || node.heritageClauses !== heritageClauses 3288 || node.members !== members 3289 ? update(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node) 3290 : node; 3291 } 3292 3293 // @api 3294 function createOmittedExpression() { 3295 return createBaseExpression<OmittedExpression>(SyntaxKind.OmittedExpression); 3296 } 3297 3298 // @api 3299 function createExpressionWithTypeArguments(expression: Expression, typeArguments: readonly TypeNode[] | undefined) { 3300 const node = createBaseNode<ExpressionWithTypeArguments>(SyntaxKind.ExpressionWithTypeArguments); 3301 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); 3302 node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); 3303 node.transformFlags |= 3304 propagateChildFlags(node.expression) | 3305 propagateChildrenFlags(node.typeArguments) | 3306 TransformFlags.ContainsES2015; 3307 return node; 3308 } 3309 3310 // @api 3311 function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: readonly TypeNode[] | undefined) { 3312 return node.expression !== expression 3313 || node.typeArguments !== typeArguments 3314 ? update(createExpressionWithTypeArguments(expression, typeArguments), node) 3315 : node; 3316 } 3317 3318 // @api 3319 function createAsExpression(expression: Expression, type: TypeNode) { 3320 const node = createBaseExpression<AsExpression>(SyntaxKind.AsExpression); 3321 node.expression = expression; 3322 node.type = type; 3323 node.transformFlags |= 3324 propagateChildFlags(node.expression) | 3325 propagateChildFlags(node.type) | 3326 TransformFlags.ContainsTypeScript; 3327 return node; 3328 } 3329 3330 // @api 3331 function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode) { 3332 return node.expression !== expression 3333 || node.type !== type 3334 ? update(createAsExpression(expression, type), node) 3335 : node; 3336 } 3337 3338 // @api 3339 function createNonNullExpression(expression: Expression) { 3340 const node = createBaseExpression<NonNullExpression>(SyntaxKind.NonNullExpression); 3341 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); 3342 node.transformFlags |= 3343 propagateChildFlags(node.expression) | 3344 TransformFlags.ContainsTypeScript; 3345 return node; 3346 } 3347 3348 // @api 3349 function updateNonNullExpression(node: NonNullExpression, expression: Expression) { 3350 if (isNonNullChain(node)) { 3351 return updateNonNullChain(node, expression); 3352 } 3353 return node.expression !== expression 3354 ? update(createNonNullExpression(expression), node) 3355 : node; 3356 } 3357 3358 // @api 3359 function createSatisfiesExpression(expression: Expression, type: TypeNode) { 3360 const node = createBaseExpression<SatisfiesExpression>(SyntaxKind.SatisfiesExpression); 3361 node.expression = expression; 3362 node.type = type; 3363 node.transformFlags |= 3364 propagateChildFlags(node.expression) | 3365 propagateChildFlags(node.type) | 3366 TransformFlags.ContainsTypeScript; 3367 return node; 3368 } 3369 3370 // @api 3371 function updateSatisfiesExpression(node: SatisfiesExpression, expression: Expression, type: TypeNode) { 3372 return node.expression !== expression 3373 || node.type !== type 3374 ? update(createSatisfiesExpression(expression, type), node) 3375 : node; 3376 } 3377 3378 // @api 3379 function createNonNullChain(expression: Expression) { 3380 const node = createBaseExpression<NonNullChain>(SyntaxKind.NonNullExpression); 3381 node.flags |= NodeFlags.OptionalChain; 3382 node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ true); 3383 node.transformFlags |= 3384 propagateChildFlags(node.expression) | 3385 TransformFlags.ContainsTypeScript; 3386 return node; 3387 } 3388 3389 // @api 3390 function updateNonNullChain(node: NonNullChain, expression: Expression) { 3391 Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a NonNullExpression using updateNonNullChain. Use updateNonNullExpression instead."); 3392 return node.expression !== expression 3393 ? update(createNonNullChain(expression), node) 3394 : node; 3395 } 3396 3397 // @api 3398 function createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier) { 3399 const node = createBaseExpression<MetaProperty>(SyntaxKind.MetaProperty); 3400 node.keywordToken = keywordToken; 3401 node.name = name; 3402 node.transformFlags |= propagateChildFlags(node.name); 3403 switch (keywordToken) { 3404 case SyntaxKind.NewKeyword: 3405 node.transformFlags |= TransformFlags.ContainsES2015; 3406 break; 3407 case SyntaxKind.ImportKeyword: 3408 node.transformFlags |= TransformFlags.ContainsESNext; 3409 break; 3410 default: 3411 return Debug.assertNever(keywordToken); 3412 } 3413 return node; 3414 } 3415 3416 // @api 3417 function updateMetaProperty(node: MetaProperty, name: Identifier) { 3418 return node.name !== name 3419 ? update(createMetaProperty(node.keywordToken, name), node) 3420 : node; 3421 } 3422 3423 // 3424 // Misc 3425 // 3426 3427 // @api 3428 function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail) { 3429 const node = createBaseNode<TemplateSpan>(SyntaxKind.TemplateSpan); 3430 node.expression = expression; 3431 node.literal = literal; 3432 node.transformFlags |= 3433 propagateChildFlags(node.expression) | 3434 propagateChildFlags(node.literal) | 3435 TransformFlags.ContainsES2015; 3436 return node; 3437 } 3438 3439 // @api 3440 function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) { 3441 return node.expression !== expression 3442 || node.literal !== literal 3443 ? update(createTemplateSpan(expression, literal), node) 3444 : node; 3445 } 3446 3447 // @api 3448 function createSemicolonClassElement() { 3449 const node = createBaseNode<SemicolonClassElement>(SyntaxKind.SemicolonClassElement); 3450 node.transformFlags |= TransformFlags.ContainsES2015; 3451 return node; 3452 } 3453 3454 // 3455 // Element 3456 // 3457 3458 // @api 3459 function createBlock(statements: readonly Statement[], multiLine?: boolean): Block { 3460 const node = createBaseNode<Block>(SyntaxKind.Block); 3461 node.statements = createNodeArray(statements); 3462 node.multiLine = multiLine; 3463 node.transformFlags |= propagateChildrenFlags(node.statements); 3464 return node; 3465 } 3466 3467 // @api 3468 function updateBlock(node: Block, statements: readonly Statement[]) { 3469 return node.statements !== statements 3470 ? update(createBlock(statements, node.multiLine), node) 3471 : node; 3472 } 3473 3474 // @api 3475 function createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]) { 3476 const node = createBaseDeclaration<VariableStatement>(SyntaxKind.VariableStatement); 3477 node.modifiers = asNodeArray(modifiers); 3478 node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; 3479 node.transformFlags |= 3480 propagateChildrenFlags(node.modifiers) | 3481 propagateChildFlags(node.declarationList); 3482 if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { 3483 node.transformFlags = TransformFlags.ContainsTypeScript; 3484 } 3485 return node; 3486 } 3487 3488 // @api 3489 function updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList) { 3490 return node.modifiers !== modifiers 3491 || node.declarationList !== declarationList 3492 ? update(createVariableStatement(modifiers, declarationList), node) 3493 : node; 3494 } 3495 3496 // @api 3497 function createEmptyStatement() { 3498 return createBaseNode<EmptyStatement>(SyntaxKind.EmptyStatement); 3499 } 3500 3501 // @api 3502 function createExpressionStatement(expression: Expression): ExpressionStatement { 3503 const node = createBaseNode<ExpressionStatement>(SyntaxKind.ExpressionStatement); 3504 node.expression = parenthesizerRules().parenthesizeExpressionOfExpressionStatement(expression); 3505 node.transformFlags |= propagateChildFlags(node.expression); 3506 return node; 3507 } 3508 3509 // @api 3510 function updateExpressionStatement(node: ExpressionStatement, expression: Expression) { 3511 return node.expression !== expression 3512 ? update(createExpressionStatement(expression), node) 3513 : node; 3514 } 3515 3516 // @api 3517 function createIfStatement(expression: Expression, thenStatement: Statement, elseStatement?: Statement) { 3518 const node = createBaseNode<IfStatement>(SyntaxKind.IfStatement); 3519 node.expression = expression; 3520 node.thenStatement = asEmbeddedStatement(thenStatement); 3521 node.elseStatement = asEmbeddedStatement(elseStatement); 3522 node.transformFlags |= 3523 propagateChildFlags(node.expression) | 3524 propagateChildFlags(node.thenStatement) | 3525 propagateChildFlags(node.elseStatement); 3526 return node; 3527 } 3528 3529 // @api 3530 function updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined) { 3531 return node.expression !== expression 3532 || node.thenStatement !== thenStatement 3533 || node.elseStatement !== elseStatement 3534 ? update(createIfStatement(expression, thenStatement, elseStatement), node) 3535 : node; 3536 } 3537 3538 // @api 3539 function createDoStatement(statement: Statement, expression: Expression) { 3540 const node = createBaseNode<DoStatement>(SyntaxKind.DoStatement); 3541 node.statement = asEmbeddedStatement(statement); 3542 node.expression = expression; 3543 node.transformFlags |= 3544 propagateChildFlags(node.statement) | 3545 propagateChildFlags(node.expression); 3546 return node; 3547 } 3548 3549 // @api 3550 function updateDoStatement(node: DoStatement, statement: Statement, expression: Expression) { 3551 return node.statement !== statement 3552 || node.expression !== expression 3553 ? update(createDoStatement(statement, expression), node) 3554 : node; 3555 } 3556 3557 // @api 3558 function createWhileStatement(expression: Expression, statement: Statement) { 3559 const node = createBaseNode<WhileStatement>(SyntaxKind.WhileStatement); 3560 node.expression = expression; 3561 node.statement = asEmbeddedStatement(statement); 3562 node.transformFlags |= 3563 propagateChildFlags(node.expression) | 3564 propagateChildFlags(node.statement); 3565 return node; 3566 } 3567 3568 // @api 3569 function updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement) { 3570 return node.expression !== expression 3571 || node.statement !== statement 3572 ? update(createWhileStatement(expression, statement), node) 3573 : node; 3574 } 3575 3576 // @api 3577 function createForStatement(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { 3578 const node = createBaseNode<ForStatement>(SyntaxKind.ForStatement); 3579 node.initializer = initializer; 3580 node.condition = condition; 3581 node.incrementor = incrementor; 3582 node.statement = asEmbeddedStatement(statement); 3583 node.transformFlags |= 3584 propagateChildFlags(node.initializer) | 3585 propagateChildFlags(node.condition) | 3586 propagateChildFlags(node.incrementor) | 3587 propagateChildFlags(node.statement); 3588 return node; 3589 } 3590 3591 // @api 3592 function updateForStatement(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { 3593 return node.initializer !== initializer 3594 || node.condition !== condition 3595 || node.incrementor !== incrementor 3596 || node.statement !== statement 3597 ? update(createForStatement(initializer, condition, incrementor, statement), node) 3598 : node; 3599 } 3600 3601 // @api 3602 function createForInStatement(initializer: ForInitializer, expression: Expression, statement: Statement) { 3603 const node = createBaseNode<ForInStatement>(SyntaxKind.ForInStatement); 3604 node.initializer = initializer; 3605 node.expression = expression; 3606 node.statement = asEmbeddedStatement(statement); 3607 node.transformFlags |= 3608 propagateChildFlags(node.initializer) | 3609 propagateChildFlags(node.expression) | 3610 propagateChildFlags(node.statement); 3611 return node; 3612 } 3613 3614 // @api 3615 function updateForInStatement(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { 3616 return node.initializer !== initializer 3617 || node.expression !== expression 3618 || node.statement !== statement 3619 ? update(createForInStatement(initializer, expression, statement), node) 3620 : node; 3621 } 3622 3623 // @api 3624 function createForOfStatement(awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { 3625 const node = createBaseNode<ForOfStatement>(SyntaxKind.ForOfStatement); 3626 node.awaitModifier = awaitModifier; 3627 node.initializer = initializer; 3628 node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); 3629 node.statement = asEmbeddedStatement(statement); 3630 node.transformFlags |= 3631 propagateChildFlags(node.awaitModifier) | 3632 propagateChildFlags(node.initializer) | 3633 propagateChildFlags(node.expression) | 3634 propagateChildFlags(node.statement) | 3635 TransformFlags.ContainsES2015; 3636 if (awaitModifier) node.transformFlags |= TransformFlags.ContainsES2018; 3637 return node; 3638 } 3639 3640 // @api 3641 function updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { 3642 return node.awaitModifier !== awaitModifier 3643 || node.initializer !== initializer 3644 || node.expression !== expression 3645 || node.statement !== statement 3646 ? update(createForOfStatement(awaitModifier, initializer, expression, statement), node) 3647 : node; 3648 } 3649 3650 // @api 3651 function createContinueStatement(label?: string | Identifier): ContinueStatement { 3652 const node = createBaseNode<ContinueStatement>(SyntaxKind.ContinueStatement); 3653 node.label = asName(label); 3654 node.transformFlags |= 3655 propagateChildFlags(node.label) | 3656 TransformFlags.ContainsHoistedDeclarationOrCompletion; 3657 return node; 3658 } 3659 3660 // @api 3661 function updateContinueStatement(node: ContinueStatement, label: Identifier | undefined) { 3662 return node.label !== label 3663 ? update(createContinueStatement(label), node) 3664 : node; 3665 } 3666 3667 // @api 3668 function createBreakStatement(label?: string | Identifier): BreakStatement { 3669 const node = createBaseNode<BreakStatement>(SyntaxKind.BreakStatement); 3670 node.label = asName(label); 3671 node.transformFlags |= 3672 propagateChildFlags(node.label) | 3673 TransformFlags.ContainsHoistedDeclarationOrCompletion; 3674 return node; 3675 } 3676 3677 // @api 3678 function updateBreakStatement(node: BreakStatement, label: Identifier | undefined) { 3679 return node.label !== label 3680 ? update(createBreakStatement(label), node) 3681 : node; 3682 } 3683 3684 // @api 3685 function createReturnStatement(expression?: Expression): ReturnStatement { 3686 const node = createBaseNode<ReturnStatement>(SyntaxKind.ReturnStatement); 3687 node.expression = expression; 3688 // return in an ES2018 async generator must be awaited 3689 node.transformFlags |= 3690 propagateChildFlags(node.expression) | 3691 TransformFlags.ContainsES2018 | 3692 TransformFlags.ContainsHoistedDeclarationOrCompletion; 3693 return node; 3694 } 3695 3696 // @api 3697 function updateReturnStatement(node: ReturnStatement, expression: Expression | undefined) { 3698 return node.expression !== expression 3699 ? update(createReturnStatement(expression), node) 3700 : node; 3701 } 3702 3703 // @api 3704 function createWithStatement(expression: Expression, statement: Statement) { 3705 const node = createBaseNode<WithStatement>(SyntaxKind.WithStatement); 3706 node.expression = expression; 3707 node.statement = asEmbeddedStatement(statement); 3708 node.transformFlags |= 3709 propagateChildFlags(node.expression) | 3710 propagateChildFlags(node.statement); 3711 return node; 3712 } 3713 3714 // @api 3715 function updateWithStatement(node: WithStatement, expression: Expression, statement: Statement) { 3716 return node.expression !== expression 3717 || node.statement !== statement 3718 ? update(createWithStatement(expression, statement), node) 3719 : node; 3720 } 3721 3722 // @api 3723 function createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement { 3724 const node = createBaseNode<SwitchStatement>(SyntaxKind.SwitchStatement); 3725 node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); 3726 node.caseBlock = caseBlock; 3727 node.transformFlags |= 3728 propagateChildFlags(node.expression) | 3729 propagateChildFlags(node.caseBlock); 3730 return node; 3731 } 3732 3733 // @api 3734 function updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) { 3735 return node.expression !== expression 3736 || node.caseBlock !== caseBlock 3737 ? update(createSwitchStatement(expression, caseBlock), node) 3738 : node; 3739 } 3740 3741 // @api 3742 function createLabeledStatement(label: string | Identifier, statement: Statement) { 3743 const node = createBaseNode<LabeledStatement>(SyntaxKind.LabeledStatement); 3744 node.label = asName(label); 3745 node.statement = asEmbeddedStatement(statement); 3746 node.transformFlags |= 3747 propagateChildFlags(node.label) | 3748 propagateChildFlags(node.statement); 3749 return node; 3750 } 3751 3752 // @api 3753 function updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement) { 3754 return node.label !== label 3755 || node.statement !== statement 3756 ? update(createLabeledStatement(label, statement), node) 3757 : node; 3758 } 3759 3760 // @api 3761 function createThrowStatement(expression: Expression) { 3762 const node = createBaseNode<ThrowStatement>(SyntaxKind.ThrowStatement); 3763 node.expression = expression; 3764 node.transformFlags |= propagateChildFlags(node.expression); 3765 return node; 3766 } 3767 3768 // @api 3769 function updateThrowStatement(node: ThrowStatement, expression: Expression) { 3770 return node.expression !== expression 3771 ? update(createThrowStatement(expression), node) 3772 : node; 3773 } 3774 3775 // @api 3776 function createTryStatement(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { 3777 const node = createBaseNode<TryStatement>(SyntaxKind.TryStatement); 3778 node.tryBlock = tryBlock; 3779 node.catchClause = catchClause; 3780 node.finallyBlock = finallyBlock; 3781 node.transformFlags |= 3782 propagateChildFlags(node.tryBlock) | 3783 propagateChildFlags(node.catchClause) | 3784 propagateChildFlags(node.finallyBlock); 3785 return node; 3786 } 3787 3788 // @api 3789 function updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { 3790 return node.tryBlock !== tryBlock 3791 || node.catchClause !== catchClause 3792 || node.finallyBlock !== finallyBlock 3793 ? update(createTryStatement(tryBlock, catchClause, finallyBlock), node) 3794 : node; 3795 } 3796 3797 // @api 3798 function createDebuggerStatement() { 3799 return createBaseNode<DebuggerStatement>(SyntaxKind.DebuggerStatement); 3800 } 3801 3802 // @api 3803 function createVariableDeclaration(name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { 3804 const node = createBaseVariableLikeDeclaration<VariableDeclaration>( 3805 SyntaxKind.VariableDeclaration, 3806 /*modifiers*/ undefined, 3807 name, 3808 type, 3809 initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer) 3810 ); 3811 node.exclamationToken = exclamationToken; 3812 node.transformFlags |= propagateChildFlags(node.exclamationToken); 3813 if (exclamationToken) { 3814 node.transformFlags |= TransformFlags.ContainsTypeScript; 3815 } 3816 return node; 3817 } 3818 3819 // @api 3820 function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { 3821 return node.name !== name 3822 || node.type !== type 3823 || node.exclamationToken !== exclamationToken 3824 || node.initializer !== initializer 3825 ? update(createVariableDeclaration(name, exclamationToken, type, initializer), node) 3826 : node; 3827 } 3828 3829 // @api 3830 function createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags = NodeFlags.None) { 3831 const node = createBaseNode<VariableDeclarationList>(SyntaxKind.VariableDeclarationList); 3832 node.flags |= flags & NodeFlags.BlockScoped; 3833 node.declarations = createNodeArray(declarations); 3834 node.transformFlags |= 3835 propagateChildrenFlags(node.declarations) | 3836 TransformFlags.ContainsHoistedDeclarationOrCompletion; 3837 if (flags & NodeFlags.BlockScoped) { 3838 node.transformFlags |= 3839 TransformFlags.ContainsES2015 | 3840 TransformFlags.ContainsBlockScopedBinding; 3841 } 3842 return node; 3843 } 3844 3845 // @api 3846 function updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]) { 3847 return node.declarations !== declarations 3848 ? update(createVariableDeclarationList(declarations, node.flags), node) 3849 : node; 3850 } 3851 3852 // @api 3853 function createFunctionDeclaration( 3854 modifiers: readonly ModifierLike[] | undefined, 3855 asteriskToken: AsteriskToken | undefined, 3856 name: string | Identifier | undefined, 3857 typeParameters: readonly TypeParameterDeclaration[] | undefined, 3858 parameters: readonly ParameterDeclaration[], 3859 type: TypeNode | undefined, 3860 body: Block | undefined 3861 ) { 3862 const node = createBaseFunctionLikeDeclaration<FunctionDeclaration>( 3863 SyntaxKind.FunctionDeclaration, 3864 modifiers, 3865 name, 3866 typeParameters, 3867 parameters, 3868 type, 3869 body 3870 ); 3871 node.asteriskToken = asteriskToken; 3872 if (!node.body || modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { 3873 node.transformFlags = TransformFlags.ContainsTypeScript; 3874 } 3875 else { 3876 node.transformFlags |= 3877 propagateChildFlags(node.asteriskToken) | 3878 TransformFlags.ContainsHoistedDeclarationOrCompletion; 3879 if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { 3880 if (node.asteriskToken) { 3881 node.transformFlags |= TransformFlags.ContainsES2018; 3882 } 3883 else { 3884 node.transformFlags |= TransformFlags.ContainsES2017; 3885 } 3886 } 3887 else if (node.asteriskToken) { 3888 node.transformFlags |= TransformFlags.ContainsGenerator; 3889 } 3890 } 3891 3892 // The following properties are used only to report grammar errors 3893 node.illegalDecorators = undefined; 3894 return node; 3895 } 3896 3897 // @api 3898 function updateFunctionDeclaration( 3899 node: FunctionDeclaration, 3900 modifiers: readonly ModifierLike[] | undefined, 3901 asteriskToken: AsteriskToken | undefined, 3902 name: Identifier | undefined, 3903 typeParameters: readonly TypeParameterDeclaration[] | undefined, 3904 parameters: readonly ParameterDeclaration[], 3905 type: TypeNode | undefined, 3906 body: Block | undefined 3907 ) { 3908 return node.modifiers !== modifiers 3909 || node.asteriskToken !== asteriskToken 3910 || node.name !== name 3911 || node.typeParameters !== typeParameters 3912 || node.parameters !== parameters 3913 || node.type !== type 3914 || node.body !== body 3915 ? finishUpdateFunctionDeclaration(createFunctionDeclaration(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) 3916 : node; 3917 } 3918 3919 function finishUpdateFunctionDeclaration(updated: Mutable<FunctionDeclaration>, original: FunctionDeclaration) { 3920 if (updated !== original) { 3921 // copy children used only for error reporting 3922 updated.illegalDecorators = original.illegalDecorators; 3923 } 3924 return finishUpdateBaseSignatureDeclaration(updated, original); 3925 } 3926 3927 // @api 3928 function createClassDeclaration( 3929 modifiers: readonly ModifierLike[] | undefined, 3930 name: string | Identifier | undefined, 3931 typeParameters: readonly TypeParameterDeclaration[] | undefined, 3932 heritageClauses: readonly HeritageClause[] | undefined, 3933 members: readonly ClassElement[] 3934 ) { 3935 const node = createBaseClassLikeDeclaration<ClassDeclaration>( 3936 SyntaxKind.ClassDeclaration, 3937 modifiers, 3938 name, 3939 typeParameters, 3940 heritageClauses, 3941 members 3942 ); 3943 if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { 3944 node.transformFlags = TransformFlags.ContainsTypeScript; 3945 } 3946 else { 3947 node.transformFlags |= TransformFlags.ContainsES2015; 3948 if (node.transformFlags & TransformFlags.ContainsTypeScriptClassSyntax) { 3949 node.transformFlags |= TransformFlags.ContainsTypeScript; 3950 } 3951 } 3952 return node; 3953 } 3954 3955 // @api 3956 function updateClassDeclaration( 3957 node: ClassDeclaration, 3958 modifiers: readonly ModifierLike[] | undefined, 3959 name: Identifier | undefined, 3960 typeParameters: readonly TypeParameterDeclaration[] | undefined, 3961 heritageClauses: readonly HeritageClause[] | undefined, 3962 members: readonly ClassElement[] 3963 ) { 3964 return node.modifiers !== modifiers 3965 || node.name !== name 3966 || node.typeParameters !== typeParameters 3967 || node.heritageClauses !== heritageClauses 3968 || node.members !== members 3969 ? update(createClassDeclaration(modifiers, name, typeParameters, heritageClauses, members), node) 3970 : node; 3971 } 3972 3973 // @api 3974 function createStructDeclaration( 3975 modifiers: readonly Modifier[] | undefined, 3976 name: string | Identifier | undefined, 3977 typeParameters: readonly TypeParameterDeclaration[] | undefined, 3978 heritageClauses: readonly HeritageClause[] | undefined, 3979 members: readonly ClassElement[] 3980 ) { 3981 const node = createBaseClassLikeDeclaration<StructDeclaration>( 3982 SyntaxKind.StructDeclaration, 3983 modifiers, 3984 name, 3985 typeParameters, 3986 heritageClauses, 3987 members 3988 ); 3989 if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { 3990 node.transformFlags = TransformFlags.ContainsTypeScript; 3991 } 3992 else { 3993 node.transformFlags |= TransformFlags.ContainsES2015; 3994 if (node.transformFlags & TransformFlags.ContainsTypeScriptClassSyntax) { 3995 node.transformFlags |= TransformFlags.ContainsTypeScript; 3996 } 3997 } 3998 return node; 3999 } 4000 4001 // @api 4002 function updateStructDeclaration( 4003 node: StructDeclaration, 4004 modifiers: readonly Modifier[] | undefined, 4005 name: Identifier | undefined, 4006 typeParameters: readonly TypeParameterDeclaration[] | undefined, 4007 heritageClauses: readonly HeritageClause[] | undefined, 4008 members: readonly ClassElement[] 4009 ) { 4010 return node.modifiers !== modifiers 4011 || node.name !== name 4012 || node.typeParameters !== typeParameters 4013 || node.heritageClauses !== heritageClauses 4014 || node.members !== members 4015 ? update(createStructDeclaration(modifiers, name, typeParameters, heritageClauses, members), node) 4016 : node; 4017 } 4018 4019 // @api 4020 function createAnnotationDeclaration( 4021 modifiers: readonly Modifier[] | undefined, 4022 name: string | Identifier | undefined, 4023 members: readonly AnnotationElement[] 4024 ) { 4025 const node = createBaseNamedDeclaration<AnnotationDeclaration>( 4026 SyntaxKind.AnnotationDeclaration, 4027 modifiers, 4028 name 4029 ); 4030 node.members = createNodeArray(members); 4031 node.transformFlags |= propagateChildrenFlags(node.members); 4032 if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { 4033 node.transformFlags = TransformFlags.ContainsTypeScript; 4034 } 4035 else { 4036 node.transformFlags |= TransformFlags.ContainsES2015; 4037 node.transformFlags |= TransformFlags.ContainsTypeScript; 4038 } 4039 return node; 4040 } 4041 4042 // @api 4043 function updateAnnotationDeclaration( 4044 node: AnnotationDeclaration, 4045 modifiers: readonly Modifier[] | undefined, 4046 name: Identifier | undefined, 4047 members: readonly AnnotationElement[] 4048 ) { 4049 return node.modifiers !== modifiers 4050 || node.name !== name 4051 || node.members !== members 4052 ? update(createAnnotationDeclaration(modifiers, name, members), node) 4053 : node; 4054 } 4055 4056 // @api 4057 function createInterfaceDeclaration( 4058 modifiers: readonly Modifier[] | undefined, 4059 name: string | Identifier, 4060 typeParameters: readonly TypeParameterDeclaration[] | undefined, 4061 heritageClauses: readonly HeritageClause[] | undefined, 4062 members: readonly TypeElement[] 4063 ) { 4064 const node = createBaseInterfaceOrClassLikeDeclaration<InterfaceDeclaration>( 4065 SyntaxKind.InterfaceDeclaration, 4066 modifiers, 4067 name, 4068 typeParameters, 4069 heritageClauses 4070 ); 4071 node.members = createNodeArray(members); 4072 node.transformFlags = TransformFlags.ContainsTypeScript; 4073 4074 // The following properties are used only to report grammar errors 4075 node.illegalDecorators = undefined; 4076 return node; 4077 } 4078 4079 // @api 4080 function updateInterfaceDeclaration( 4081 node: InterfaceDeclaration, 4082 modifiers: readonly Modifier[] | undefined, 4083 name: Identifier, 4084 typeParameters: readonly TypeParameterDeclaration[] | undefined, 4085 heritageClauses: readonly HeritageClause[] | undefined, 4086 members: readonly TypeElement[] 4087 ) { 4088 return node.modifiers !== modifiers 4089 || node.name !== name 4090 || node.typeParameters !== typeParameters 4091 || node.heritageClauses !== heritageClauses 4092 || node.members !== members 4093 ? finishUpdateInterfaceDeclaration(createInterfaceDeclaration(modifiers, name, typeParameters, heritageClauses, members), node) 4094 : node; 4095 } 4096 4097 function finishUpdateInterfaceDeclaration(updated: Mutable<InterfaceDeclaration>, original: InterfaceDeclaration) { 4098 if (updated !== original) { 4099 updated.illegalDecorators = original.illegalDecorators; 4100 } 4101 return update(updated, original); 4102 } 4103 4104 // @api 4105 function createTypeAliasDeclaration( 4106 modifiers: readonly Modifier[] | undefined, 4107 name: string | Identifier, 4108 typeParameters: readonly TypeParameterDeclaration[] | undefined, 4109 type: TypeNode 4110 ) { 4111 const node = createBaseGenericNamedDeclaration<TypeAliasDeclaration>( 4112 SyntaxKind.TypeAliasDeclaration, 4113 modifiers, 4114 name, 4115 typeParameters 4116 ); 4117 node.type = type; 4118 node.transformFlags = TransformFlags.ContainsTypeScript; 4119 4120 // The following properties are used only to report grammar errors 4121 node.illegalDecorators = undefined; 4122 return node; 4123 } 4124 4125 // @api 4126 function updateTypeAliasDeclaration( 4127 node: TypeAliasDeclaration, 4128 modifiers: readonly Modifier[] | undefined, 4129 name: Identifier, 4130 typeParameters: readonly TypeParameterDeclaration[] | undefined, 4131 type: TypeNode 4132 ) { 4133 return node.modifiers !== modifiers 4134 || node.name !== name 4135 || node.typeParameters !== typeParameters 4136 || node.type !== type 4137 ? finishUpdateTypeAliasDeclaration(createTypeAliasDeclaration(modifiers, name, typeParameters, type), node) 4138 : node; 4139 } 4140 4141 function finishUpdateTypeAliasDeclaration(updated: Mutable<TypeAliasDeclaration>, original: TypeAliasDeclaration) { 4142 if (updated !== original) { 4143 updated.illegalDecorators = original.illegalDecorators; 4144 } 4145 return update(updated, original); 4146 } 4147 4148 // @api 4149 function createEnumDeclaration( 4150 modifiers: readonly Modifier[] | undefined, 4151 name: string | Identifier, 4152 members: readonly EnumMember[] 4153 ) { 4154 const node = createBaseNamedDeclaration<EnumDeclaration>( 4155 SyntaxKind.EnumDeclaration, 4156 modifiers, 4157 name 4158 ); 4159 node.members = createNodeArray(members); 4160 node.transformFlags |= 4161 propagateChildrenFlags(node.members) | 4162 TransformFlags.ContainsTypeScript; 4163 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Enum declarations cannot contain `await` 4164 4165 // The following properties are used only to report grammar errors 4166 node.illegalDecorators = undefined; 4167 return node; 4168 } 4169 4170 // @api 4171 function updateEnumDeclaration( 4172 node: EnumDeclaration, 4173 modifiers: readonly Modifier[] | undefined, 4174 name: Identifier, 4175 members: readonly EnumMember[]) { 4176 return node.modifiers !== modifiers 4177 || node.name !== name 4178 || node.members !== members 4179 ? finishUpdateEnumDeclaration(createEnumDeclaration(modifiers, name, members), node) 4180 : node; 4181 } 4182 4183 function finishUpdateEnumDeclaration(updated: Mutable<EnumDeclaration>, original: EnumDeclaration) { 4184 if (updated !== original) { 4185 updated.illegalDecorators = original.illegalDecorators; 4186 } 4187 return update(updated, original); 4188 } 4189 4190 // @api 4191 function createModuleDeclaration( 4192 modifiers: readonly Modifier[] | undefined, 4193 name: ModuleName, 4194 body: ModuleBody | undefined, 4195 flags = NodeFlags.None 4196 ) { 4197 const node = createBaseDeclaration<ModuleDeclaration>(SyntaxKind.ModuleDeclaration); 4198 node.modifiers = asNodeArray(modifiers); 4199 node.flags |= flags & (NodeFlags.Namespace | NodeFlags.NestedNamespace | NodeFlags.GlobalAugmentation); 4200 node.name = name; 4201 node.body = body; 4202 if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { 4203 node.transformFlags = TransformFlags.ContainsTypeScript; 4204 } 4205 else { 4206 node.transformFlags |= 4207 propagateChildrenFlags(node.modifiers) | 4208 propagateChildFlags(node.name) | 4209 propagateChildFlags(node.body) | 4210 TransformFlags.ContainsTypeScript; 4211 } 4212 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Module declarations cannot contain `await`. 4213 4214 // The following properties are used only to report grammar errors 4215 node.illegalDecorators = undefined; 4216 return node; 4217 } 4218 4219 // @api 4220 function updateModuleDeclaration( 4221 node: ModuleDeclaration, 4222 modifiers: readonly Modifier[] | undefined, 4223 name: ModuleName, 4224 body: ModuleBody | undefined 4225 ) { 4226 return node.modifiers !== modifiers 4227 || node.name !== name 4228 || node.body !== body 4229 ? finishUpdateModuleDeclaration(createModuleDeclaration(modifiers, name, body, node.flags), node) 4230 : node; 4231 } 4232 4233 function finishUpdateModuleDeclaration(updated: Mutable<ModuleDeclaration>, original: ModuleDeclaration) { 4234 if (updated !== original) { 4235 updated.illegalDecorators = original.illegalDecorators; 4236 } 4237 return update(updated, original); 4238 } 4239 4240 // @api 4241 function createModuleBlock(statements: readonly Statement[]) { 4242 const node = createBaseNode<ModuleBlock>(SyntaxKind.ModuleBlock); 4243 node.statements = createNodeArray(statements); 4244 node.transformFlags |= propagateChildrenFlags(node.statements); 4245 return node; 4246 } 4247 4248 // @api 4249 function updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]) { 4250 return node.statements !== statements 4251 ? update(createModuleBlock(statements), node) 4252 : node; 4253 } 4254 4255 // @api 4256 function createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock { 4257 const node = createBaseNode<CaseBlock>(SyntaxKind.CaseBlock); 4258 node.clauses = createNodeArray(clauses); 4259 node.transformFlags |= propagateChildrenFlags(node.clauses); 4260 return node; 4261 } 4262 4263 // @api 4264 function updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]) { 4265 return node.clauses !== clauses 4266 ? update(createCaseBlock(clauses), node) 4267 : node; 4268 } 4269 4270 // @api 4271 function createNamespaceExportDeclaration(name: string | Identifier) { 4272 const node = createBaseNamedDeclaration<NamespaceExportDeclaration>( 4273 SyntaxKind.NamespaceExportDeclaration, 4274 /*modifiers*/ undefined, 4275 name 4276 ); 4277 node.transformFlags = TransformFlags.ContainsTypeScript; 4278 4279 // The following properties are used only to report grammar errors 4280 node.illegalDecorators = undefined; 4281 node.modifiers = undefined; 4282 return node; 4283 } 4284 4285 // @api 4286 function updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier) { 4287 return node.name !== name 4288 ? finishUpdateNamespaceExportDeclaration(createNamespaceExportDeclaration(name), node) 4289 : node; 4290 } 4291 4292 function finishUpdateNamespaceExportDeclaration(updated: Mutable<NamespaceExportDeclaration>, original: NamespaceExportDeclaration) { 4293 if (updated !== original) { 4294 updated.illegalDecorators = original.illegalDecorators; 4295 updated.modifiers = original.modifiers; 4296 } 4297 return update(updated, original); 4298 } 4299 4300 // @api 4301 function createImportEqualsDeclaration( 4302 modifiers: readonly Modifier[] | undefined, 4303 isTypeOnly: boolean, 4304 name: string | Identifier, 4305 moduleReference: ModuleReference 4306 ) { 4307 const node = createBaseNamedDeclaration<ImportEqualsDeclaration>( 4308 SyntaxKind.ImportEqualsDeclaration, 4309 modifiers, 4310 name 4311 ); 4312 node.isTypeOnly = isTypeOnly; 4313 node.moduleReference = moduleReference; 4314 node.transformFlags |= propagateChildFlags(node.moduleReference); 4315 if (!isExternalModuleReference(node.moduleReference)) node.transformFlags |= TransformFlags.ContainsTypeScript; 4316 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // Import= declaration is always parsed in an Await context 4317 4318 // The following properties are used only to report grammar errors 4319 node.illegalDecorators = undefined; 4320 return node; 4321 } 4322 4323 // @api 4324 function updateImportEqualsDeclaration( 4325 node: ImportEqualsDeclaration, 4326 modifiers: readonly Modifier[] | undefined, 4327 isTypeOnly: boolean, 4328 name: Identifier, 4329 moduleReference: ModuleReference 4330 ) { 4331 return node.modifiers !== modifiers 4332 || node.isTypeOnly !== isTypeOnly 4333 || node.name !== name 4334 || node.moduleReference !== moduleReference 4335 ? finishUpdateImportEqualsDeclaration(createImportEqualsDeclaration(modifiers, isTypeOnly, name, moduleReference), node) 4336 : node; 4337 } 4338 4339 function finishUpdateImportEqualsDeclaration(updated: Mutable<ImportEqualsDeclaration>, original: ImportEqualsDeclaration) { 4340 if (updated !== original) { 4341 updated.illegalDecorators = original.illegalDecorators; 4342 } 4343 return update(updated, original); 4344 } 4345 4346 // @api 4347 function createImportDeclaration( 4348 modifiers: readonly Modifier[] | undefined, 4349 importClause: ImportClause | undefined, 4350 moduleSpecifier: Expression, 4351 assertClause: AssertClause | undefined 4352 ): ImportDeclaration { 4353 const node = createBaseDeclaration<ImportDeclaration>(SyntaxKind.ImportDeclaration); 4354 node.modifiers = asNodeArray(modifiers); 4355 node.importClause = importClause; 4356 node.moduleSpecifier = moduleSpecifier; 4357 node.assertClause = assertClause; 4358 node.transformFlags |= 4359 propagateChildFlags(node.importClause) | 4360 propagateChildFlags(node.moduleSpecifier); 4361 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4362 4363 // The following properties are used only to report grammar errors 4364 node.illegalDecorators = undefined; 4365 return node; 4366 } 4367 4368 // @api 4369 function updateImportDeclaration( 4370 node: ImportDeclaration, 4371 modifiers: readonly Modifier[] | undefined, 4372 importClause: ImportClause | undefined, 4373 moduleSpecifier: Expression, 4374 assertClause: AssertClause | undefined 4375 ) { 4376 return node.modifiers !== modifiers 4377 || node.importClause !== importClause 4378 || node.moduleSpecifier !== moduleSpecifier 4379 || node.assertClause !== assertClause 4380 ? finishUpdateImportDeclaration(createImportDeclaration(modifiers, importClause, moduleSpecifier, assertClause), node) 4381 : node; 4382 } 4383 4384 function finishUpdateImportDeclaration(updated: Mutable<ImportDeclaration>, original: ImportDeclaration) { 4385 if (updated !== original) { 4386 updated.illegalDecorators = original.illegalDecorators; 4387 } 4388 return update(updated, original); 4389 } 4390 4391 // @api 4392 function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { 4393 const node = createBaseNode<ImportClause>(SyntaxKind.ImportClause); 4394 node.isTypeOnly = isTypeOnly; 4395 node.name = name; 4396 node.namedBindings = namedBindings; 4397 node.transformFlags |= 4398 propagateChildFlags(node.name) | 4399 propagateChildFlags(node.namedBindings); 4400 if (isTypeOnly) { 4401 node.transformFlags |= TransformFlags.ContainsTypeScript; 4402 } 4403 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4404 4405 node.isLazy = undefined; 4406 return node; 4407 } 4408 4409 // @api 4410 function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { 4411 return node.isTypeOnly !== isTypeOnly 4412 || node.name !== name 4413 || node.namedBindings !== namedBindings 4414 ? finishUpdateImportClause(createImportClause(isTypeOnly, name, namedBindings), node) 4415 : node; 4416 } 4417 4418 function finishUpdateImportClause(updated: Mutable<ImportClause>, original: ImportClause) { 4419 if (updated !== original) { 4420 updated.isLazy = original.isLazy; 4421 } 4422 return update(updated, original); 4423 } 4424 4425 // @api 4426 function createAssertClause(elements: readonly AssertEntry[], multiLine?: boolean): AssertClause { 4427 const node = createBaseNode<AssertClause>(SyntaxKind.AssertClause); 4428 node.elements = createNodeArray(elements); 4429 node.multiLine = multiLine; 4430 node.transformFlags |= TransformFlags.ContainsESNext; 4431 return node; 4432 } 4433 4434 // @api 4435 function updateAssertClause(node: AssertClause, elements: readonly AssertEntry[], multiLine?: boolean): AssertClause { 4436 return node.elements !== elements 4437 || node.multiLine !== multiLine 4438 ? update(createAssertClause(elements, multiLine), node) 4439 : node; 4440 } 4441 4442 // @api 4443 function createAssertEntry(name: AssertionKey, value: Expression): AssertEntry { 4444 const node = createBaseNode<AssertEntry>(SyntaxKind.AssertEntry); 4445 node.name = name; 4446 node.value = value; 4447 node.transformFlags |= TransformFlags.ContainsESNext; 4448 return node; 4449 } 4450 4451 // @api 4452 function updateAssertEntry(node: AssertEntry, name: AssertionKey, value: Expression): AssertEntry { 4453 return node.name !== name 4454 || node.value !== value 4455 ? update(createAssertEntry(name, value), node) 4456 : node; 4457 } 4458 4459 // @api 4460 function createImportTypeAssertionContainer(clause: AssertClause, multiLine?: boolean): ImportTypeAssertionContainer { 4461 const node = createBaseNode<ImportTypeAssertionContainer>(SyntaxKind.ImportTypeAssertionContainer); 4462 node.assertClause = clause; 4463 node.multiLine = multiLine; 4464 return node; 4465 } 4466 4467 // @api 4468 function updateImportTypeAssertionContainer(node: ImportTypeAssertionContainer, clause: AssertClause, multiLine?: boolean): ImportTypeAssertionContainer { 4469 return node.assertClause !== clause 4470 || node.multiLine !== multiLine 4471 ? update(createImportTypeAssertionContainer(clause, multiLine), node) 4472 : node; 4473 } 4474 4475 // @api 4476 function createNamespaceImport(name: Identifier): NamespaceImport { 4477 const node = createBaseNode<NamespaceImport>(SyntaxKind.NamespaceImport); 4478 node.name = name; 4479 node.transformFlags |= propagateChildFlags(node.name); 4480 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4481 return node; 4482 } 4483 4484 // @api 4485 function updateNamespaceImport(node: NamespaceImport, name: Identifier) { 4486 return node.name !== name 4487 ? update(createNamespaceImport(name), node) 4488 : node; 4489 } 4490 4491 // @api 4492 function createNamespaceExport(name: Identifier): NamespaceExport { 4493 const node = createBaseNode<NamespaceExport>(SyntaxKind.NamespaceExport); 4494 node.name = name; 4495 node.transformFlags |= 4496 propagateChildFlags(node.name) | 4497 TransformFlags.ContainsESNext; 4498 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4499 return node; 4500 } 4501 4502 // @api 4503 function updateNamespaceExport(node: NamespaceExport, name: Identifier) { 4504 return node.name !== name 4505 ? update(createNamespaceExport(name), node) 4506 : node; 4507 } 4508 4509 // @api 4510 function createNamedImports(elements: readonly ImportSpecifier[]): NamedImports { 4511 const node = createBaseNode<NamedImports>(SyntaxKind.NamedImports); 4512 node.elements = createNodeArray(elements); 4513 node.transformFlags |= propagateChildrenFlags(node.elements); 4514 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4515 return node; 4516 } 4517 4518 // @api 4519 function updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]) { 4520 return node.elements !== elements 4521 ? update(createNamedImports(elements), node) 4522 : node; 4523 } 4524 4525 // @api 4526 function createImportSpecifier(isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { 4527 const node = createBaseNode<ImportSpecifier>(SyntaxKind.ImportSpecifier); 4528 node.isTypeOnly = isTypeOnly; 4529 node.propertyName = propertyName; 4530 node.name = name; 4531 node.transformFlags |= 4532 propagateChildFlags(node.propertyName) | 4533 propagateChildFlags(node.name); 4534 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4535 return node; 4536 } 4537 4538 // @api 4539 function updateImportSpecifier(node: ImportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { 4540 return node.isTypeOnly !== isTypeOnly 4541 || node.propertyName !== propertyName 4542 || node.name !== name 4543 ? update(createImportSpecifier(isTypeOnly, propertyName, name), node) 4544 : node; 4545 } 4546 4547 // @api 4548 function createExportAssignment( 4549 modifiers: readonly Modifier[] | undefined, 4550 isExportEquals: boolean | undefined, 4551 expression: Expression 4552 ) { 4553 const node = createBaseDeclaration<ExportAssignment>(SyntaxKind.ExportAssignment); 4554 node.modifiers = asNodeArray(modifiers); 4555 node.isExportEquals = isExportEquals; 4556 node.expression = isExportEquals 4557 ? parenthesizerRules().parenthesizeRightSideOfBinary(SyntaxKind.EqualsToken, /*leftSide*/ undefined, expression) 4558 : parenthesizerRules().parenthesizeExpressionOfExportDefault(expression); 4559 node.transformFlags |= propagateChildrenFlags(node.modifiers) | propagateChildFlags(node.expression); 4560 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4561 4562 // The following properties are used only to report grammar errors 4563 node.illegalDecorators = undefined; 4564 return node; 4565 } 4566 4567 // @api 4568 function updateExportAssignment( 4569 node: ExportAssignment, 4570 modifiers: readonly Modifier[] | undefined, 4571 expression: Expression 4572 ) { 4573 return node.modifiers !== modifiers 4574 || node.expression !== expression 4575 ? finishUpdateExportAssignment(createExportAssignment(modifiers, node.isExportEquals, expression), node) 4576 : node; 4577 } 4578 4579 function finishUpdateExportAssignment(updated: Mutable<ExportAssignment>, original: ExportAssignment) { 4580 if (updated !== original) { 4581 updated.illegalDecorators = original.illegalDecorators; 4582 } 4583 return update(updated, original); 4584 } 4585 4586 // @api 4587 function createExportDeclaration( 4588 modifiers: readonly Modifier[] | undefined, 4589 isTypeOnly: boolean, 4590 exportClause: NamedExportBindings | undefined, 4591 moduleSpecifier?: Expression, 4592 assertClause?: AssertClause 4593 ) { 4594 const node = createBaseDeclaration<ExportDeclaration>(SyntaxKind.ExportDeclaration); 4595 node.modifiers = asNodeArray(modifiers); 4596 node.isTypeOnly = isTypeOnly; 4597 node.exportClause = exportClause; 4598 node.moduleSpecifier = moduleSpecifier; 4599 node.assertClause = assertClause; 4600 node.transformFlags |= 4601 propagateChildrenFlags(node.modifiers) | 4602 propagateChildFlags(node.exportClause) | 4603 propagateChildFlags(node.moduleSpecifier); 4604 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4605 4606 // The following properties are used only to report grammar errors 4607 node.illegalDecorators = undefined; 4608 return node; 4609 } 4610 4611 // @api 4612 function updateExportDeclaration( 4613 node: ExportDeclaration, 4614 modifiers: readonly Modifier[] | undefined, 4615 isTypeOnly: boolean, 4616 exportClause: NamedExportBindings | undefined, 4617 moduleSpecifier: Expression | undefined, 4618 assertClause: AssertClause | undefined 4619 ) { 4620 return node.modifiers !== modifiers 4621 || node.isTypeOnly !== isTypeOnly 4622 || node.exportClause !== exportClause 4623 || node.moduleSpecifier !== moduleSpecifier 4624 || node.assertClause !== assertClause 4625 ? finishUpdateExportDeclaration(createExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause), node) 4626 : node; 4627 } 4628 4629 function finishUpdateExportDeclaration(updated: Mutable<ExportDeclaration>, original: ExportDeclaration) { 4630 if (updated !== original) { 4631 updated.illegalDecorators = original.illegalDecorators; 4632 } 4633 return update(updated, original); 4634 } 4635 4636 // @api 4637 function createNamedExports(elements: readonly ExportSpecifier[]) { 4638 const node = createBaseNode<NamedExports>(SyntaxKind.NamedExports); 4639 node.elements = createNodeArray(elements); 4640 node.transformFlags |= propagateChildrenFlags(node.elements); 4641 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4642 return node; 4643 } 4644 4645 // @api 4646 function updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]) { 4647 return node.elements !== elements 4648 ? update(createNamedExports(elements), node) 4649 : node; 4650 } 4651 4652 // @api 4653 function createExportSpecifier(isTypeOnly: boolean, propertyName: string | Identifier | undefined, name: string | Identifier) { 4654 const node = createBaseNode<ExportSpecifier>(SyntaxKind.ExportSpecifier); 4655 node.isTypeOnly = isTypeOnly; 4656 node.propertyName = asName(propertyName); 4657 node.name = asName(name); 4658 node.transformFlags |= 4659 propagateChildFlags(node.propertyName) | 4660 propagateChildFlags(node.name); 4661 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4662 return node; 4663 } 4664 4665 // @api 4666 function updateExportSpecifier(node: ExportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { 4667 return node.isTypeOnly !== isTypeOnly 4668 || node.propertyName !== propertyName 4669 || node.name !== name 4670 ? update(createExportSpecifier(isTypeOnly, propertyName, name), node) 4671 : node; 4672 } 4673 4674 // @api 4675 function createMissingDeclaration(): MissingDeclaration { 4676 const node = createBaseDeclaration<MissingDeclaration>(SyntaxKind.MissingDeclaration); 4677 return node; 4678 } 4679 4680 // 4681 // Module references 4682 // 4683 4684 // @api 4685 function createExternalModuleReference(expression: Expression) { 4686 const node = createBaseNode<ExternalModuleReference>(SyntaxKind.ExternalModuleReference); 4687 node.expression = expression; 4688 node.transformFlags |= propagateChildFlags(node.expression); 4689 node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context 4690 return node; 4691 } 4692 4693 // @api 4694 function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression) { 4695 return node.expression !== expression 4696 ? update(createExternalModuleReference(expression), node) 4697 : node; 4698 } 4699 4700 // 4701 // JSDoc 4702 // 4703 4704 // @api 4705 // createJSDocAllType 4706 // createJSDocUnknownType 4707 function createJSDocPrimaryTypeWorker<T extends JSDocType>(kind: T["kind"]) { 4708 return createBaseNode(kind); 4709 } 4710 4711 // @api 4712 // createJSDocNullableType 4713 // createJSDocNonNullableType 4714 function createJSDocPrePostfixUnaryTypeWorker<T extends JSDocType & { readonly type: TypeNode | undefined; readonly postfix: boolean }>(kind: T["kind"], type: T["type"], postfix = false): T { 4715 const node = createJSDocUnaryTypeWorker( 4716 kind, 4717 postfix ? type && parenthesizerRules().parenthesizeNonArrayTypeOfPostfixType(type) : type 4718 ) as Mutable<T>; 4719 node.postfix = postfix; 4720 return node; 4721 } 4722 4723 // @api 4724 // createJSDocOptionalType 4725 // createJSDocVariadicType 4726 // createJSDocNamepathType 4727 function createJSDocUnaryTypeWorker<T extends JSDocType & { readonly type: TypeNode | undefined; }>(kind: T["kind"], type: T["type"]): T { 4728 const node = createBaseNode<T>(kind); 4729 node.type = type; 4730 return node; 4731 } 4732 4733 // @api 4734 // updateJSDocNonNullableType 4735 // updateJSDocNullableType 4736 function updateJSDocPrePostfixUnaryTypeWorker<T extends JSDocType & { readonly type: TypeNode | undefined; readonly postfix: boolean; }>(kind: T["kind"], node: T, type: T["type"]): T { 4737 return node.type !== type 4738 ? update(createJSDocPrePostfixUnaryTypeWorker(kind, type, node.postfix), node) 4739 : node; 4740 } 4741 4742 // @api 4743 // updateJSDocOptionalType 4744 // updateJSDocVariadicType 4745 // updateJSDocNamepathType 4746 function updateJSDocUnaryTypeWorker<T extends JSDocType & { readonly type: TypeNode | undefined; }>(kind: T["kind"], node: T, type: T["type"]): T { 4747 return node.type !== type 4748 ? update(createJSDocUnaryTypeWorker(kind, type), node) 4749 : node; 4750 } 4751 4752 // @api 4753 function createJSDocFunctionType(parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType { 4754 const node = createBaseSignatureDeclaration<JSDocFunctionType>( 4755 SyntaxKind.JSDocFunctionType, 4756 /*modifiers*/ undefined, 4757 /*name*/ undefined, 4758 /*typeParameters*/ undefined, 4759 parameters, 4760 type 4761 ); 4762 return node; 4763 } 4764 4765 // @api 4766 function updateJSDocFunctionType(node: JSDocFunctionType, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType { 4767 return node.parameters !== parameters 4768 || node.type !== type 4769 ? update(createJSDocFunctionType(parameters, type), node) 4770 : node; 4771 } 4772 4773 // @api 4774 function createJSDocTypeLiteral(propertyTags?: readonly JSDocPropertyLikeTag[], isArrayType = false): JSDocTypeLiteral { 4775 const node = createBaseNode<JSDocTypeLiteral>(SyntaxKind.JSDocTypeLiteral); 4776 node.jsDocPropertyTags = asNodeArray(propertyTags); 4777 node.isArrayType = isArrayType; 4778 return node; 4779 } 4780 4781 // @api 4782 function updateJSDocTypeLiteral(node: JSDocTypeLiteral, propertyTags: readonly JSDocPropertyLikeTag[] | undefined, isArrayType: boolean): JSDocTypeLiteral { 4783 return node.jsDocPropertyTags !== propertyTags 4784 || node.isArrayType !== isArrayType 4785 ? update(createJSDocTypeLiteral(propertyTags, isArrayType), node) 4786 : node; 4787 } 4788 4789 // @api 4790 function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression { 4791 const node = createBaseNode<JSDocTypeExpression>(SyntaxKind.JSDocTypeExpression); 4792 node.type = type; 4793 return node; 4794 } 4795 4796 // @api 4797 function updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression { 4798 return node.type !== type 4799 ? update(createJSDocTypeExpression(type), node) 4800 : node; 4801 } 4802 4803 // @api 4804 function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature { 4805 const node = createBaseNode<JSDocSignature>(SyntaxKind.JSDocSignature); 4806 node.typeParameters = asNodeArray(typeParameters); 4807 node.parameters = createNodeArray(parameters); 4808 node.type = type; 4809 return node; 4810 } 4811 4812 // @api 4813 function updateJSDocSignature(node: JSDocSignature, typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type: JSDocReturnTag | undefined): JSDocSignature { 4814 return node.typeParameters !== typeParameters 4815 || node.parameters !== parameters 4816 || node.type !== type 4817 ? update(createJSDocSignature(typeParameters, parameters, type), node) 4818 : node; 4819 } 4820 4821 function getDefaultTagName(node: JSDocTag) { 4822 const defaultTagName = getDefaultTagNameForKind(node.kind); 4823 return node.tagName.escapedText === escapeLeadingUnderscores(defaultTagName) 4824 ? node.tagName 4825 : createIdentifier(defaultTagName); 4826 } 4827 4828 // @api 4829 function createBaseJSDocTag<T extends JSDocTag>(kind: T["kind"], tagName: Identifier, comment: string | NodeArray<JSDocComment> | undefined) { 4830 const node = createBaseNode<T>(kind); 4831 node.tagName = tagName; 4832 node.comment = comment; 4833 return node; 4834 } 4835 4836 // @api 4837 function createJSDocTemplateTag(tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string | NodeArray<JSDocComment>): JSDocTemplateTag { 4838 const node = createBaseJSDocTag<JSDocTemplateTag>(SyntaxKind.JSDocTemplateTag, tagName ?? createIdentifier("template"), comment); 4839 node.constraint = constraint; 4840 node.typeParameters = createNodeArray(typeParameters); 4841 return node; 4842 } 4843 4844 // @api 4845 function updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier = getDefaultTagName(node), constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | NodeArray<JSDocComment> | undefined): JSDocTemplateTag { 4846 return node.tagName !== tagName 4847 || node.constraint !== constraint 4848 || node.typeParameters !== typeParameters 4849 || node.comment !== comment 4850 ? update(createJSDocTemplateTag(tagName, constraint, typeParameters, comment), node) 4851 : node; 4852 } 4853 4854 // @api 4855 function createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string | NodeArray<JSDocComment>): JSDocTypedefTag { 4856 const node = createBaseJSDocTag<JSDocTypedefTag>(SyntaxKind.JSDocTypedefTag, tagName ?? createIdentifier("typedef"), comment); 4857 node.typeExpression = typeExpression; 4858 node.fullName = fullName; 4859 node.name = getJSDocTypeAliasName(fullName); 4860 return node; 4861 } 4862 4863 // @api 4864 function updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocTypeExpression | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | NodeArray<JSDocComment> | undefined): JSDocTypedefTag { 4865 return node.tagName !== tagName 4866 || node.typeExpression !== typeExpression 4867 || node.fullName !== fullName 4868 || node.comment !== comment 4869 ? update(createJSDocTypedefTag(tagName, typeExpression, fullName, comment), node) 4870 : node; 4871 } 4872 4873 // @api 4874 function createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string | NodeArray<JSDocComment>): JSDocParameterTag { 4875 const node = createBaseJSDocTag<JSDocParameterTag>(SyntaxKind.JSDocParameterTag, tagName ?? createIdentifier("param"), comment); 4876 node.typeExpression = typeExpression; 4877 node.name = name; 4878 node.isNameFirst = !!isNameFirst; 4879 node.isBracketed = isBracketed; 4880 return node; 4881 } 4882 4883 // @api 4884 function updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier = getDefaultTagName(node), name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | NodeArray<JSDocComment> | undefined): JSDocParameterTag { 4885 return node.tagName !== tagName 4886 || node.name !== name 4887 || node.isBracketed !== isBracketed 4888 || node.typeExpression !== typeExpression 4889 || node.isNameFirst !== isNameFirst 4890 || node.comment !== comment 4891 ? update(createJSDocParameterTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment), node) 4892 : node; 4893 } 4894 4895 // @api 4896 function createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string | NodeArray<JSDocComment>): JSDocPropertyTag { 4897 const node = createBaseJSDocTag<JSDocPropertyTag>(SyntaxKind.JSDocPropertyTag, tagName ?? createIdentifier("prop"), comment); 4898 node.typeExpression = typeExpression; 4899 node.name = name; 4900 node.isNameFirst = !!isNameFirst; 4901 node.isBracketed = isBracketed; 4902 return node; 4903 } 4904 4905 // @api 4906 function updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier = getDefaultTagName(node), name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | NodeArray<JSDocComment> | undefined): JSDocPropertyTag { 4907 return node.tagName !== tagName 4908 || node.name !== name 4909 || node.isBracketed !== isBracketed 4910 || node.typeExpression !== typeExpression 4911 || node.isNameFirst !== isNameFirst 4912 || node.comment !== comment 4913 ? update(createJSDocPropertyTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment), node) 4914 : node; 4915 } 4916 4917 // @api 4918 function createJSDocCallbackTag(tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string | NodeArray<JSDocComment>): JSDocCallbackTag { 4919 const node = createBaseJSDocTag<JSDocCallbackTag>(SyntaxKind.JSDocCallbackTag, tagName ?? createIdentifier("callback"), comment); 4920 node.typeExpression = typeExpression; 4921 node.fullName = fullName; 4922 node.name = getJSDocTypeAliasName(fullName); 4923 return node; 4924 } 4925 4926 // @api 4927 function updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocSignature, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | NodeArray<JSDocComment> | undefined): JSDocCallbackTag { 4928 return node.tagName !== tagName 4929 || node.typeExpression !== typeExpression 4930 || node.fullName !== fullName 4931 || node.comment !== comment 4932 ? update(createJSDocCallbackTag(tagName, typeExpression, fullName, comment), node) 4933 : node; 4934 } 4935 4936 // @api 4937 function createJSDocAugmentsTag(tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment?: string | NodeArray<JSDocComment>): JSDocAugmentsTag { 4938 const node = createBaseJSDocTag<JSDocAugmentsTag>(SyntaxKind.JSDocAugmentsTag, tagName ?? createIdentifier("augments"), comment); 4939 node.class = className; 4940 return node; 4941 } 4942 4943 // @api 4944 function updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier = getDefaultTagName(node), className: JSDocAugmentsTag["class"], comment: string | NodeArray<JSDocComment> | undefined): JSDocAugmentsTag { 4945 return node.tagName !== tagName 4946 || node.class !== className 4947 || node.comment !== comment 4948 ? update(createJSDocAugmentsTag(tagName, className, comment), node) 4949 : node; 4950 } 4951 4952 // @api 4953 function createJSDocImplementsTag(tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment?: string | NodeArray<JSDocComment>): JSDocImplementsTag { 4954 const node = createBaseJSDocTag<JSDocImplementsTag>(SyntaxKind.JSDocImplementsTag, tagName ?? createIdentifier("implements"), comment); 4955 node.class = className; 4956 return node; 4957 } 4958 4959 // @api 4960 function createJSDocSeeTag(tagName: Identifier | undefined, name: JSDocNameReference | undefined, comment?: string | NodeArray<JSDocComment>): JSDocSeeTag { 4961 const node = createBaseJSDocTag<JSDocSeeTag>(SyntaxKind.JSDocSeeTag, tagName ?? createIdentifier("see"), comment); 4962 node.name = name; 4963 return node; 4964 } 4965 4966 // @api 4967 function updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier | undefined, name: JSDocNameReference | undefined, comment?: string | NodeArray<JSDocComment>): JSDocSeeTag { 4968 return node.tagName !== tagName 4969 || node.name !== name 4970 || node.comment !== comment 4971 ? update(createJSDocSeeTag(tagName, name, comment), node) 4972 : node; 4973 } 4974 4975 // @api 4976 function createJSDocNameReference(name: EntityName | JSDocMemberName): JSDocNameReference { 4977 const node = createBaseNode<JSDocNameReference>(SyntaxKind.JSDocNameReference); 4978 node.name = name; 4979 return node; 4980 } 4981 4982 // @api 4983 function updateJSDocNameReference(node: JSDocNameReference, name: EntityName | JSDocMemberName): JSDocNameReference { 4984 return node.name !== name 4985 ? update(createJSDocNameReference(name), node) 4986 : node; 4987 } 4988 4989 // @api 4990 function createJSDocMemberName(left: EntityName | JSDocMemberName, right: Identifier) { 4991 const node = createBaseNode<JSDocMemberName>(SyntaxKind.JSDocMemberName); 4992 node.left = left; 4993 node.right = right; 4994 node.transformFlags |= 4995 propagateChildFlags(node.left) | 4996 propagateChildFlags(node.right); 4997 return node; 4998 } 4999 5000 // @api 5001 function updateJSDocMemberName(node: JSDocMemberName, left: EntityName | JSDocMemberName, right: Identifier) { 5002 return node.left !== left 5003 || node.right !== right 5004 ? update(createJSDocMemberName(left, right), node) 5005 : node; 5006 } 5007 5008 // @api 5009 function createJSDocLink(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLink { 5010 const node = createBaseNode<JSDocLink>(SyntaxKind.JSDocLink); 5011 node.name = name; 5012 node.text = text; 5013 return node; 5014 } 5015 5016 // @api 5017 function updateJSDocLink(node: JSDocLink, name: EntityName | JSDocMemberName | undefined, text: string): JSDocLink { 5018 return node.name !== name 5019 ? update(createJSDocLink(name, text), node) 5020 : node; 5021 } 5022 5023 // @api 5024 function createJSDocLinkCode(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkCode { 5025 const node = createBaseNode<JSDocLinkCode>(SyntaxKind.JSDocLinkCode); 5026 node.name = name; 5027 node.text = text; 5028 return node; 5029 } 5030 5031 // @api 5032 function updateJSDocLinkCode(node: JSDocLinkCode, name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkCode { 5033 return node.name !== name 5034 ? update(createJSDocLinkCode(name, text), node) 5035 : node; 5036 } 5037 5038 // @api 5039 function createJSDocLinkPlain(name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkPlain { 5040 const node = createBaseNode<JSDocLinkPlain>(SyntaxKind.JSDocLinkPlain); 5041 node.name = name; 5042 node.text = text; 5043 return node; 5044 } 5045 5046 // @api 5047 function updateJSDocLinkPlain(node: JSDocLinkPlain, name: EntityName | JSDocMemberName | undefined, text: string): JSDocLinkPlain { 5048 return node.name !== name 5049 ? update(createJSDocLinkPlain(name, text), node) 5050 : node; 5051 } 5052 5053 // @api 5054 function updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier = getDefaultTagName(node), className: JSDocImplementsTag["class"], comment: string | NodeArray<JSDocComment> | undefined): JSDocImplementsTag { 5055 return node.tagName !== tagName 5056 || node.class !== className 5057 || node.comment !== comment 5058 ? update(createJSDocImplementsTag(tagName, className, comment), node) 5059 : node; 5060 } 5061 5062 // @api 5063 // createJSDocAuthorTag 5064 // createJSDocClassTag 5065 // createJSDocPublicTag 5066 // createJSDocPrivateTag 5067 // createJSDocProtectedTag 5068 // createJSDocReadonlyTag 5069 // createJSDocDeprecatedTag 5070 function createJSDocSimpleTagWorker<T extends JSDocTag>(kind: T["kind"], tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>) { 5071 const node = createBaseJSDocTag<T>(kind, tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), comment); 5072 return node; 5073 } 5074 5075 // @api 5076 // updateJSDocAuthorTag 5077 // updateJSDocClassTag 5078 // updateJSDocPublicTag 5079 // updateJSDocPrivateTag 5080 // updateJSDocProtectedTag 5081 // updateJSDocReadonlyTag 5082 // updateJSDocDeprecatedTag 5083 function updateJSDocSimpleTagWorker<T extends JSDocTag>(kind: T["kind"], node: T, tagName: Identifier = getDefaultTagName(node), comment: string | NodeArray<JSDocComment> | undefined) { 5084 return node.tagName !== tagName 5085 || node.comment !== comment 5086 ? update(createJSDocSimpleTagWorker(kind, tagName, comment), node) : 5087 node; 5088 } 5089 5090 // @api 5091 // createJSDocTypeTag 5092 // createJSDocReturnTag 5093 // createJSDocThisTag 5094 // createJSDocEnumTag 5095 function createJSDocTypeLikeTagWorker<T extends JSDocTag & { typeExpression?: JSDocTypeExpression }>(kind: T["kind"], tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string | NodeArray<JSDocComment>) { 5096 const node = createBaseJSDocTag<T>(kind, tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), comment); 5097 node.typeExpression = typeExpression; 5098 return node; 5099 } 5100 5101 // @api 5102 // updateJSDocTypeTag 5103 // updateJSDocReturnTag 5104 // updateJSDocThisTag 5105 // updateJSDocEnumTag 5106 function updateJSDocTypeLikeTagWorker<T extends JSDocTag & { typeExpression?: JSDocTypeExpression }>(kind: T["kind"], node: T, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocTypeExpression | undefined, comment: string | NodeArray<JSDocComment> | undefined) { 5107 return node.tagName !== tagName 5108 || node.typeExpression !== typeExpression 5109 || node.comment !== comment 5110 ? update(createJSDocTypeLikeTagWorker(kind, tagName, typeExpression, comment), node) 5111 : node; 5112 } 5113 5114 // @api 5115 function createJSDocUnknownTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocUnknownTag { 5116 const node = createBaseJSDocTag<JSDocUnknownTag>(SyntaxKind.JSDocTag, tagName, comment); 5117 return node; 5118 } 5119 5120 // @api 5121 function updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | NodeArray<JSDocComment> | undefined): JSDocUnknownTag { 5122 return node.tagName !== tagName 5123 || node.comment !== comment 5124 ? update(createJSDocUnknownTag(tagName, comment), node) 5125 : node; 5126 } 5127 5128 // @api 5129 function createJSDocText(text: string): JSDocText { 5130 const node = createBaseNode<JSDocText>(SyntaxKind.JSDocText); 5131 node.text = text; 5132 return node; 5133 } 5134 5135 // @api 5136 function updateJSDocText(node: JSDocText, text: string): JSDocText { 5137 return node.text !== text 5138 ? update(createJSDocText(text), node) 5139 : node; 5140 } 5141 5142 // @api 5143 function createJSDocComment(comment?: string | NodeArray<JSDocComment> | undefined, tags?: readonly JSDocTag[] | undefined) { 5144 const node = createBaseNode<JSDoc>(SyntaxKind.JSDoc); 5145 node.comment = comment; 5146 node.tags = asNodeArray(tags); 5147 return node; 5148 } 5149 5150 // @api 5151 function updateJSDocComment(node: JSDoc, comment: string | NodeArray<JSDocComment> | undefined, tags: readonly JSDocTag[] | undefined) { 5152 return node.comment !== comment 5153 || node.tags !== tags 5154 ? update(createJSDocComment(comment, tags), node) 5155 : node; 5156 } 5157 5158 // 5159 // JSX 5160 // 5161 5162 // @api 5163 function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { 5164 const node = createBaseNode<JsxElement>(SyntaxKind.JsxElement); 5165 node.openingElement = openingElement; 5166 node.children = createNodeArray(children); 5167 node.closingElement = closingElement; 5168 node.transformFlags |= 5169 propagateChildFlags(node.openingElement) | 5170 propagateChildrenFlags(node.children) | 5171 propagateChildFlags(node.closingElement) | 5172 TransformFlags.ContainsJsx; 5173 return node; 5174 } 5175 5176 // @api 5177 function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { 5178 return node.openingElement !== openingElement 5179 || node.children !== children 5180 || node.closingElement !== closingElement 5181 ? update(createJsxElement(openingElement, children, closingElement), node) 5182 : node; 5183 } 5184 5185 // @api 5186 function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { 5187 const node = createBaseNode<JsxSelfClosingElement>(SyntaxKind.JsxSelfClosingElement); 5188 node.tagName = tagName; 5189 node.typeArguments = asNodeArray(typeArguments); 5190 node.attributes = attributes; 5191 node.transformFlags |= 5192 propagateChildFlags(node.tagName) | 5193 propagateChildrenFlags(node.typeArguments) | 5194 propagateChildFlags(node.attributes) | 5195 TransformFlags.ContainsJsx; 5196 if (node.typeArguments) { 5197 node.transformFlags |= TransformFlags.ContainsTypeScript; 5198 } 5199 return node; 5200 } 5201 5202 // @api 5203 function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { 5204 return node.tagName !== tagName 5205 || node.typeArguments !== typeArguments 5206 || node.attributes !== attributes 5207 ? update(createJsxSelfClosingElement(tagName, typeArguments, attributes), node) 5208 : node; 5209 } 5210 5211 // @api 5212 function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { 5213 const node = createBaseNode<JsxOpeningElement>(SyntaxKind.JsxOpeningElement); 5214 node.tagName = tagName; 5215 node.typeArguments = asNodeArray(typeArguments); 5216 node.attributes = attributes; 5217 node.transformFlags |= 5218 propagateChildFlags(node.tagName) | 5219 propagateChildrenFlags(node.typeArguments) | 5220 propagateChildFlags(node.attributes) | 5221 TransformFlags.ContainsJsx; 5222 if (typeArguments) { 5223 node.transformFlags |= TransformFlags.ContainsTypeScript; 5224 } 5225 return node; 5226 } 5227 5228 // @api 5229 function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { 5230 return node.tagName !== tagName 5231 || node.typeArguments !== typeArguments 5232 || node.attributes !== attributes 5233 ? update(createJsxOpeningElement(tagName, typeArguments, attributes), node) 5234 : node; 5235 } 5236 5237 // @api 5238 function createJsxClosingElement(tagName: JsxTagNameExpression) { 5239 const node = createBaseNode<JsxClosingElement>(SyntaxKind.JsxClosingElement); 5240 node.tagName = tagName; 5241 node.transformFlags |= 5242 propagateChildFlags(node.tagName) | 5243 TransformFlags.ContainsJsx; 5244 return node; 5245 } 5246 5247 // @api 5248 function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression) { 5249 return node.tagName !== tagName 5250 ? update(createJsxClosingElement(tagName), node) 5251 : node; 5252 } 5253 5254 // @api 5255 function createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { 5256 const node = createBaseNode<JsxFragment>(SyntaxKind.JsxFragment); 5257 node.openingFragment = openingFragment; 5258 node.children = createNodeArray(children); 5259 node.closingFragment = closingFragment; 5260 node.transformFlags |= 5261 propagateChildFlags(node.openingFragment) | 5262 propagateChildrenFlags(node.children) | 5263 propagateChildFlags(node.closingFragment) | 5264 TransformFlags.ContainsJsx; 5265 return node; 5266 } 5267 5268 // @api 5269 function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { 5270 return node.openingFragment !== openingFragment 5271 || node.children !== children 5272 || node.closingFragment !== closingFragment 5273 ? update(createJsxFragment(openingFragment, children, closingFragment), node) 5274 : node; 5275 } 5276 5277 // @api 5278 function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean) { 5279 const node = createBaseNode<JsxText>(SyntaxKind.JsxText); 5280 node.text = text; 5281 node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces; 5282 node.transformFlags |= TransformFlags.ContainsJsx; 5283 return node; 5284 } 5285 5286 // @api 5287 function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean) { 5288 return node.text !== text 5289 || node.containsOnlyTriviaWhiteSpaces !== containsOnlyTriviaWhiteSpaces 5290 ? update(createJsxText(text, containsOnlyTriviaWhiteSpaces), node) 5291 : node; 5292 } 5293 5294 // @api 5295 function createJsxOpeningFragment() { 5296 const node = createBaseNode<JsxOpeningFragment>(SyntaxKind.JsxOpeningFragment); 5297 node.transformFlags |= TransformFlags.ContainsJsx; 5298 return node; 5299 } 5300 5301 // @api 5302 function createJsxJsxClosingFragment() { 5303 const node = createBaseNode<JsxClosingFragment>(SyntaxKind.JsxClosingFragment); 5304 node.transformFlags |= TransformFlags.ContainsJsx; 5305 return node; 5306 } 5307 5308 // @api 5309 function createJsxAttribute(name: Identifier, initializer: JsxAttributeValue | undefined) { 5310 const node = createBaseNode<JsxAttribute>(SyntaxKind.JsxAttribute); 5311 node.name = name; 5312 node.initializer = initializer; 5313 node.transformFlags |= 5314 propagateChildFlags(node.name) | 5315 propagateChildFlags(node.initializer) | 5316 TransformFlags.ContainsJsx; 5317 return node; 5318 } 5319 5320 // @api 5321 function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxAttributeValue | undefined) { 5322 return node.name !== name 5323 || node.initializer !== initializer 5324 ? update(createJsxAttribute(name, initializer), node) 5325 : node; 5326 } 5327 5328 // @api 5329 function createJsxAttributes(properties: readonly JsxAttributeLike[]) { 5330 const node = createBaseNode<JsxAttributes>(SyntaxKind.JsxAttributes); 5331 node.properties = createNodeArray(properties); 5332 node.transformFlags |= 5333 propagateChildrenFlags(node.properties) | 5334 TransformFlags.ContainsJsx; 5335 return node; 5336 } 5337 5338 // @api 5339 function updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]) { 5340 return node.properties !== properties 5341 ? update(createJsxAttributes(properties), node) 5342 : node; 5343 } 5344 5345 // @api 5346 function createJsxSpreadAttribute(expression: Expression) { 5347 const node = createBaseNode<JsxSpreadAttribute>(SyntaxKind.JsxSpreadAttribute); 5348 node.expression = expression; 5349 node.transformFlags |= 5350 propagateChildFlags(node.expression) | 5351 TransformFlags.ContainsJsx; 5352 return node; 5353 } 5354 5355 // @api 5356 function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression) { 5357 return node.expression !== expression 5358 ? update(createJsxSpreadAttribute(expression), node) 5359 : node; 5360 } 5361 5362 // @api 5363 function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) { 5364 const node = createBaseNode<JsxExpression>(SyntaxKind.JsxExpression); 5365 node.dotDotDotToken = dotDotDotToken; 5366 node.expression = expression; 5367 node.transformFlags |= 5368 propagateChildFlags(node.dotDotDotToken) | 5369 propagateChildFlags(node.expression) | 5370 TransformFlags.ContainsJsx; 5371 return node; 5372 } 5373 5374 // @api 5375 function updateJsxExpression(node: JsxExpression, expression: Expression | undefined) { 5376 return node.expression !== expression 5377 ? update(createJsxExpression(node.dotDotDotToken, expression), node) 5378 : node; 5379 } 5380 5381 // 5382 // Clauses 5383 // 5384 5385 // @api 5386 function createCaseClause(expression: Expression, statements: readonly Statement[]) { 5387 const node = createBaseNode<CaseClause>(SyntaxKind.CaseClause); 5388 node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); 5389 node.statements = createNodeArray(statements); 5390 node.transformFlags |= 5391 propagateChildFlags(node.expression) | 5392 propagateChildrenFlags(node.statements); 5393 return node; 5394 } 5395 5396 // @api 5397 function updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]) { 5398 return node.expression !== expression 5399 || node.statements !== statements 5400 ? update(createCaseClause(expression, statements), node) 5401 : node; 5402 } 5403 5404 // @api 5405 function createDefaultClause(statements: readonly Statement[]) { 5406 const node = createBaseNode<DefaultClause>(SyntaxKind.DefaultClause); 5407 node.statements = createNodeArray(statements); 5408 node.transformFlags = propagateChildrenFlags(node.statements); 5409 return node; 5410 } 5411 5412 // @api 5413 function updateDefaultClause(node: DefaultClause, statements: readonly Statement[]) { 5414 return node.statements !== statements 5415 ? update(createDefaultClause(statements), node) 5416 : node; 5417 } 5418 5419 // @api 5420 function createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]) { 5421 const node = createBaseNode<HeritageClause>(SyntaxKind.HeritageClause); 5422 node.token = token; 5423 node.types = createNodeArray(types); 5424 node.transformFlags |= propagateChildrenFlags(node.types); 5425 switch (token) { 5426 case SyntaxKind.ExtendsKeyword: 5427 node.transformFlags |= TransformFlags.ContainsES2015; 5428 break; 5429 case SyntaxKind.ImplementsKeyword: 5430 node.transformFlags |= TransformFlags.ContainsTypeScript; 5431 break; 5432 default: 5433 return Debug.assertNever(token); 5434 } 5435 return node; 5436 } 5437 5438 // @api 5439 function updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]) { 5440 return node.types !== types 5441 ? update(createHeritageClause(node.token, types), node) 5442 : node; 5443 } 5444 5445 // @api 5446 function createCatchClause(variableDeclaration: string | BindingName | VariableDeclaration | undefined, block: Block) { 5447 const node = createBaseNode<CatchClause>(SyntaxKind.CatchClause); 5448 if (typeof variableDeclaration === "string" || variableDeclaration && !isVariableDeclaration(variableDeclaration)) { 5449 variableDeclaration = createVariableDeclaration( 5450 variableDeclaration, 5451 /*exclamationToken*/ undefined, 5452 /*type*/ undefined, 5453 /*initializer*/ undefined 5454 ); 5455 } 5456 node.variableDeclaration = variableDeclaration; 5457 node.block = block; 5458 node.transformFlags |= 5459 propagateChildFlags(node.variableDeclaration) | 5460 propagateChildFlags(node.block); 5461 if (!variableDeclaration) node.transformFlags |= TransformFlags.ContainsES2019; 5462 return node; 5463 } 5464 5465 // @api 5466 function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block) { 5467 return node.variableDeclaration !== variableDeclaration 5468 || node.block !== block 5469 ? update(createCatchClause(variableDeclaration, block), node) 5470 : node; 5471 } 5472 5473 // 5474 // Property assignments 5475 // 5476 5477 // @api 5478 function createPropertyAssignment(name: string | PropertyName, initializer: Expression) { 5479 const node = createBaseNamedDeclaration<PropertyAssignment>( 5480 SyntaxKind.PropertyAssignment, 5481 /*modifiers*/ undefined, 5482 name 5483 ); 5484 node.initializer = parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer); 5485 node.transformFlags |= 5486 propagateChildFlags(node.name) | 5487 propagateChildFlags(node.initializer); 5488 5489 // The following properties are used only to report grammar errors 5490 node.illegalDecorators = undefined; 5491 node.modifiers = undefined; 5492 node.questionToken = undefined; 5493 node.exclamationToken = undefined; 5494 return node; 5495 } 5496 5497 // @api 5498 function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression) { 5499 return node.name !== name 5500 || node.initializer !== initializer 5501 ? finishUpdatePropertyAssignment(createPropertyAssignment(name, initializer), node) 5502 : node; 5503 } 5504 5505 function finishUpdatePropertyAssignment(updated: Mutable<PropertyAssignment>, original: PropertyAssignment) { 5506 // copy children used only for error reporting 5507 if (updated !== original) { 5508 updated.illegalDecorators = original.illegalDecorators; 5509 updated.modifiers = original.modifiers; 5510 updated.questionToken = original.questionToken; 5511 updated.exclamationToken = original.exclamationToken; 5512 } 5513 return update(updated, original); 5514 } 5515 5516 // @api 5517 function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression) { 5518 const node = createBaseNamedDeclaration<ShorthandPropertyAssignment>( 5519 SyntaxKind.ShorthandPropertyAssignment, 5520 /*modifiers*/ undefined, 5521 name 5522 ); 5523 node.objectAssignmentInitializer = objectAssignmentInitializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(objectAssignmentInitializer); 5524 node.transformFlags |= 5525 propagateChildFlags(node.objectAssignmentInitializer) | 5526 TransformFlags.ContainsES2015; 5527 5528 // The following properties are used only to report grammar errors 5529 node.equalsToken = undefined; 5530 node.illegalDecorators = undefined; 5531 node.modifiers = undefined; 5532 node.questionToken = undefined; 5533 node.exclamationToken = undefined; 5534 return node; 5535 } 5536 5537 // @api 5538 function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) { 5539 return node.name !== name 5540 || node.objectAssignmentInitializer !== objectAssignmentInitializer 5541 ? finishUpdateShorthandPropertyAssignment(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node) 5542 : node; 5543 } 5544 5545 function finishUpdateShorthandPropertyAssignment(updated: Mutable<ShorthandPropertyAssignment>, original: ShorthandPropertyAssignment) { 5546 if (updated !== original) { 5547 // copy children used only for error reporting 5548 updated.equalsToken = original.equalsToken; 5549 updated.illegalDecorators = original.illegalDecorators; 5550 updated.modifiers = original.modifiers; 5551 updated.questionToken = original.questionToken; 5552 updated.exclamationToken = original.exclamationToken; 5553 } 5554 return update(updated, original); 5555 } 5556 5557 // @api 5558 function createSpreadAssignment(expression: Expression) { 5559 const node = createBaseNode<SpreadAssignment>(SyntaxKind.SpreadAssignment); 5560 node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); 5561 node.transformFlags |= 5562 propagateChildFlags(node.expression) | 5563 TransformFlags.ContainsES2018 | 5564 TransformFlags.ContainsObjectRestOrSpread; 5565 return node; 5566 } 5567 5568 // @api 5569 function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) { 5570 return node.expression !== expression 5571 ? update(createSpreadAssignment(expression), node) 5572 : node; 5573 } 5574 5575 // 5576 // Enum 5577 // 5578 5579 // @api 5580 function createEnumMember(name: string | PropertyName, initializer?: Expression) { 5581 const node = createBaseNode<EnumMember>(SyntaxKind.EnumMember); 5582 node.name = asName(name); 5583 node.initializer = initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer); 5584 node.transformFlags |= 5585 propagateChildFlags(node.name) | 5586 propagateChildFlags(node.initializer) | 5587 TransformFlags.ContainsTypeScript; 5588 return node; 5589 } 5590 5591 // @api 5592 function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined) { 5593 return node.name !== name 5594 || node.initializer !== initializer 5595 ? update(createEnumMember(name, initializer), node) 5596 : node; 5597 } 5598 5599 // 5600 // Top-level nodes 5601 // 5602 5603 // @api 5604 function createSourceFile( 5605 statements: readonly Statement[], 5606 endOfFileToken: EndOfFileToken, 5607 flags: NodeFlags 5608 ) { 5609 const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as Mutable<SourceFile>; 5610 node.statements = createNodeArray(statements); 5611 node.endOfFileToken = endOfFileToken; 5612 node.flags |= flags; 5613 node.fileName = ""; 5614 node.text = ""; 5615 node.languageVersion = 0; 5616 node.languageVariant = 0; 5617 node.scriptKind = 0; 5618 node.isDeclarationFile = false; 5619 node.hasNoDefaultLib = false; 5620 node.transformFlags |= 5621 propagateChildrenFlags(node.statements) | 5622 propagateChildFlags(node.endOfFileToken); 5623 return node; 5624 } 5625 5626 function cloneSourceFileWithChanges( 5627 source: SourceFile, 5628 statements: readonly Statement[], 5629 isDeclarationFile: boolean, 5630 referencedFiles: readonly FileReference[], 5631 typeReferences: readonly FileReference[], 5632 hasNoDefaultLib: boolean, 5633 libReferences: readonly FileReference[] 5634 ) { 5635 const node = (source.redirectInfo ? Object.create(source.redirectInfo.redirectTarget) : baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile)) as Mutable<SourceFile>; 5636 for (const p in source) { 5637 if (p === "emitNode" || hasProperty(node, p) || !hasProperty(source, p)) continue; 5638 (node as any)[p] = (source as any)[p]; 5639 } 5640 node.flags |= source.flags; 5641 node.statements = createNodeArray(statements); 5642 node.endOfFileToken = source.endOfFileToken; 5643 node.isDeclarationFile = isDeclarationFile; 5644 node.referencedFiles = referencedFiles; 5645 node.typeReferenceDirectives = typeReferences; 5646 node.hasNoDefaultLib = hasNoDefaultLib; 5647 node.libReferenceDirectives = libReferences; 5648 node.transformFlags = 5649 propagateChildrenFlags(node.statements) | 5650 propagateChildFlags(node.endOfFileToken); 5651 node.impliedNodeFormat = source.impliedNodeFormat; 5652 return node; 5653 } 5654 5655 // @api 5656 function updateSourceFile( 5657 node: SourceFile, 5658 statements: readonly Statement[], 5659 isDeclarationFile = node.isDeclarationFile, 5660 referencedFiles = node.referencedFiles, 5661 typeReferenceDirectives = node.typeReferenceDirectives, 5662 hasNoDefaultLib = node.hasNoDefaultLib, 5663 libReferenceDirectives = node.libReferenceDirectives 5664 ) { 5665 return node.statements !== statements 5666 || node.isDeclarationFile !== isDeclarationFile 5667 || node.referencedFiles !== referencedFiles 5668 || node.typeReferenceDirectives !== typeReferenceDirectives 5669 || node.hasNoDefaultLib !== hasNoDefaultLib 5670 || node.libReferenceDirectives !== libReferenceDirectives 5671 ? update(cloneSourceFileWithChanges(node, statements, isDeclarationFile, referencedFiles, typeReferenceDirectives, hasNoDefaultLib, libReferenceDirectives), node) 5672 : node; 5673 } 5674 5675 // @api 5676 function createBundle(sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) { 5677 const node = createBaseNode<Bundle>(SyntaxKind.Bundle); 5678 node.prepends = prepends; 5679 node.sourceFiles = sourceFiles; 5680 return node; 5681 } 5682 5683 // @api 5684 function updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) { 5685 return node.sourceFiles !== sourceFiles 5686 || node.prepends !== prepends 5687 ? update(createBundle(sourceFiles, prepends), node) 5688 : node; 5689 } 5690 5691 // @api 5692 function createUnparsedSource(prologues: readonly UnparsedPrologue[], syntheticReferences: readonly UnparsedSyntheticReference[] | undefined, texts: readonly UnparsedSourceText[]) { 5693 const node = createBaseNode<UnparsedSource>(SyntaxKind.UnparsedSource); 5694 node.prologues = prologues; 5695 node.syntheticReferences = syntheticReferences; 5696 node.texts = texts; 5697 node.fileName = ""; 5698 node.text = ""; 5699 node.referencedFiles = emptyArray; 5700 node.libReferenceDirectives = emptyArray; 5701 node.getLineAndCharacterOfPosition = pos => getLineAndCharacterOfPosition(node, pos); 5702 return node; 5703 } 5704 5705 function createBaseUnparsedNode<T extends UnparsedNode>(kind: T["kind"], data?: string) { 5706 const node = createBaseNode(kind); 5707 node.data = data; 5708 return node; 5709 } 5710 5711 // @api 5712 function createUnparsedPrologue(data?: string): UnparsedPrologue { 5713 return createBaseUnparsedNode(SyntaxKind.UnparsedPrologue, data); 5714 } 5715 5716 // @api 5717 function createUnparsedPrepend(data: string | undefined, texts: readonly UnparsedTextLike[]): UnparsedPrepend { 5718 const node = createBaseUnparsedNode<UnparsedPrepend>(SyntaxKind.UnparsedPrepend, data); 5719 node.texts = texts; 5720 return node; 5721 } 5722 5723 // @api 5724 function createUnparsedTextLike(data: string | undefined, internal: boolean): UnparsedTextLike { 5725 return createBaseUnparsedNode(internal ? SyntaxKind.UnparsedInternalText : SyntaxKind.UnparsedText, data); 5726 } 5727 5728 // @api 5729 function createUnparsedSyntheticReference(section: BundleFileHasNoDefaultLib | BundleFileReference): UnparsedSyntheticReference { 5730 const node = createBaseNode<UnparsedSyntheticReference>(SyntaxKind.UnparsedSyntheticReference); 5731 node.data = section.data; 5732 node.section = section; 5733 return node; 5734 } 5735 5736 // @api 5737 function createInputFiles(): InputFiles { 5738 const node = createBaseNode<InputFiles>(SyntaxKind.InputFiles); 5739 node.javascriptText = ""; 5740 node.declarationText = ""; 5741 return node; 5742 } 5743 5744 // 5745 // Synthetic Nodes (used by checker) 5746 // 5747 5748 // @api 5749 function createSyntheticExpression(type: Type, isSpread = false, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { 5750 const node = createBaseNode<SyntheticExpression>(SyntaxKind.SyntheticExpression); 5751 node.type = type; 5752 node.isSpread = isSpread; 5753 node.tupleNameSource = tupleNameSource; 5754 return node; 5755 } 5756 5757 // @api 5758 function createSyntaxList(children: Node[]) { 5759 const node = createBaseNode<SyntaxList>(SyntaxKind.SyntaxList); 5760 node._children = children; 5761 return node; 5762 } 5763 5764 // 5765 // Transformation nodes 5766 // 5767 5768 /** 5769 * Creates a synthetic statement to act as a placeholder for a not-emitted statement in 5770 * order to preserve comments. 5771 * 5772 * @param original The original statement. 5773 */ 5774 // @api 5775 function createNotEmittedStatement(original: Node) { 5776 const node = createBaseNode<NotEmittedStatement>(SyntaxKind.NotEmittedStatement); 5777 node.original = original; 5778 setTextRange(node, original); 5779 return node; 5780 } 5781 5782 /** 5783 * Creates a synthetic expression to act as a placeholder for a not-emitted expression in 5784 * order to preserve comments or sourcemap positions. 5785 * 5786 * @param expression The inner expression to emit. 5787 * @param original The original outer expression. 5788 */ 5789 // @api 5790 function createPartiallyEmittedExpression(expression: Expression, original?: Node) { 5791 const node = createBaseNode<PartiallyEmittedExpression>(SyntaxKind.PartiallyEmittedExpression); 5792 node.expression = expression; 5793 node.original = original; 5794 node.transformFlags |= 5795 propagateChildFlags(node.expression) | 5796 TransformFlags.ContainsTypeScript; 5797 setTextRange(node, original); 5798 return node; 5799 } 5800 5801 // @api 5802 function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression) { 5803 return node.expression !== expression 5804 ? update(createPartiallyEmittedExpression(expression, node.original), node) 5805 : node; 5806 } 5807 5808 function flattenCommaElements(node: Expression): Expression | readonly Expression[] { 5809 if (nodeIsSynthesized(node) && !isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) { 5810 if (isCommaListExpression(node)) { 5811 return node.elements; 5812 } 5813 if (isBinaryExpression(node) && isCommaToken(node.operatorToken)) { 5814 return [node.left, node.right]; 5815 } 5816 } 5817 return node; 5818 } 5819 5820 // @api 5821 function createCommaListExpression(elements: readonly Expression[]) { 5822 const node = createBaseNode<CommaListExpression>(SyntaxKind.CommaListExpression); 5823 node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements)); 5824 node.transformFlags |= propagateChildrenFlags(node.elements); 5825 return node; 5826 } 5827 5828 // @api 5829 function updateCommaListExpression(node: CommaListExpression, elements: readonly Expression[]) { 5830 return node.elements !== elements 5831 ? update(createCommaListExpression(elements), node) 5832 : node; 5833 } 5834 5835 /** 5836 * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in 5837 * order to properly emit exports. 5838 */ 5839 // @api 5840 function createEndOfDeclarationMarker(original: Node) { 5841 const node = createBaseNode<EndOfDeclarationMarker>(SyntaxKind.EndOfDeclarationMarker); 5842 node.emitNode = {} as EmitNode; 5843 node.original = original; 5844 return node; 5845 } 5846 5847 /** 5848 * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in 5849 * order to properly emit exports. 5850 */ 5851 // @api 5852 function createMergeDeclarationMarker(original: Node) { 5853 const node = createBaseNode<MergeDeclarationMarker>(SyntaxKind.MergeDeclarationMarker); 5854 node.emitNode = {} as EmitNode; 5855 node.original = original; 5856 return node; 5857 } 5858 5859 // @api 5860 function createSyntheticReferenceExpression(expression: Expression, thisArg: Expression) { 5861 const node = createBaseNode<SyntheticReferenceExpression>(SyntaxKind.SyntheticReferenceExpression); 5862 node.expression = expression; 5863 node.thisArg = thisArg; 5864 node.transformFlags |= 5865 propagateChildFlags(node.expression) | 5866 propagateChildFlags(node.thisArg); 5867 return node; 5868 } 5869 5870 // @api 5871 function updateSyntheticReferenceExpression(node: SyntheticReferenceExpression, expression: Expression, thisArg: Expression) { 5872 return node.expression !== expression 5873 || node.thisArg !== thisArg 5874 ? update(createSyntheticReferenceExpression(expression, thisArg), node) 5875 : node; 5876 } 5877 5878 // @api 5879 function cloneNode<T extends Node | undefined>(node: T): T; 5880 function cloneNode<T extends Node>(node: T) { 5881 // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of 5882 // the original node. We also need to exclude specific properties and only include own- 5883 // properties (to skip members already defined on the shared prototype). 5884 if (node === undefined) { 5885 return node; 5886 } 5887 5888 const clone = 5889 isSourceFile(node) ? baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as T : 5890 isIdentifier(node) ? baseFactory.createBaseIdentifierNode(SyntaxKind.Identifier) as T : 5891 isPrivateIdentifier(node) ? baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as T : 5892 !isNodeKind(node.kind) ? baseFactory.createBaseTokenNode(node.kind) as T : 5893 baseFactory.createBaseNode(node.kind) as T; 5894 5895 (clone as Mutable<T>).flags |= (node.flags & ~NodeFlags.Synthesized); 5896 (clone as Mutable<T>).transformFlags = node.transformFlags; 5897 setOriginalNode(clone, node); 5898 5899 for (const key in node) { 5900 if (hasProperty(clone, key) || !hasProperty(node, key)) { 5901 continue; 5902 } 5903 5904 clone[key] = node[key]; 5905 } 5906 5907 return clone; 5908 } 5909 5910 // compound nodes 5911 function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; 5912 function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; 5913 function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { 5914 return createCallExpression( 5915 createFunctionExpression( 5916 /*modifiers*/ undefined, 5917 /*asteriskToken*/ undefined, 5918 /*name*/ undefined, 5919 /*typeParameters*/ undefined, 5920 /*parameters*/ param ? [param] : [], 5921 /*type*/ undefined, 5922 createBlock(statements, /*multiLine*/ true) 5923 ), 5924 /*typeArguments*/ undefined, 5925 /*argumentsArray*/ paramValue ? [paramValue] : [] 5926 ); 5927 } 5928 5929 function createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; 5930 function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; 5931 function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { 5932 return createCallExpression( 5933 createArrowFunction( 5934 /*modifiers*/ undefined, 5935 /*typeParameters*/ undefined, 5936 /*parameters*/ param ? [param] : [], 5937 /*type*/ undefined, 5938 /*equalsGreaterThanToken*/ undefined, 5939 createBlock(statements, /*multiLine*/ true) 5940 ), 5941 /*typeArguments*/ undefined, 5942 /*argumentsArray*/ paramValue ? [paramValue] : [] 5943 ); 5944 } 5945 5946 function createVoidZero() { 5947 return createVoidExpression(createNumericLiteral("0")); 5948 } 5949 5950 function createExportDefault(expression: Expression) { 5951 return createExportAssignment( 5952 /*modifiers*/ undefined, 5953 /*isExportEquals*/ false, 5954 expression); 5955 } 5956 5957 function createExternalModuleExport(exportName: Identifier) { 5958 return createExportDeclaration( 5959 /*modifiers*/ undefined, 5960 /*isTypeOnly*/ false, 5961 createNamedExports([ 5962 createExportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, exportName) 5963 ]) 5964 ); 5965 } 5966 5967 // 5968 // Utilities 5969 // 5970 5971 function createTypeCheck(value: Expression, tag: TypeOfTag) { 5972 return tag === "undefined" 5973 ? factory.createStrictEquality(value, createVoidZero()) 5974 : factory.createStrictEquality(createTypeOfExpression(value), createStringLiteral(tag)); 5975 } 5976 5977 function createMethodCall(object: Expression, methodName: string | Identifier, argumentsList: readonly Expression[]) { 5978 // Preserve the optionality of `object`. 5979 if (isCallChain(object)) { 5980 return createCallChain( 5981 createPropertyAccessChain(object, /*questionDotToken*/ undefined, methodName), 5982 /*questionDotToken*/ undefined, 5983 /*typeArguments*/ undefined, 5984 argumentsList 5985 ); 5986 } 5987 return createCallExpression( 5988 createPropertyAccessExpression(object, methodName), 5989 /*typeArguments*/ undefined, 5990 argumentsList 5991 ); 5992 } 5993 5994 function createFunctionBindCall(target: Expression, thisArg: Expression, argumentsList: readonly Expression[]) { 5995 return createMethodCall(target, "bind", [thisArg, ...argumentsList]); 5996 } 5997 5998 function createFunctionCallCall(target: Expression, thisArg: Expression, argumentsList: readonly Expression[]) { 5999 return createMethodCall(target, "call", [thisArg, ...argumentsList]); 6000 } 6001 6002 function createFunctionApplyCall(target: Expression, thisArg: Expression, argumentsExpression: Expression) { 6003 return createMethodCall(target, "apply", [thisArg, argumentsExpression]); 6004 } 6005 6006 function createGlobalMethodCall(globalObjectName: string, methodName: string, argumentsList: readonly Expression[]) { 6007 return createMethodCall(createIdentifier(globalObjectName), methodName, argumentsList); 6008 } 6009 6010 function createArraySliceCall(array: Expression, start?: number | Expression) { 6011 return createMethodCall(array, "slice", start === undefined ? [] : [asExpression(start)]); 6012 } 6013 6014 function createArrayConcatCall(array: Expression, argumentsList: readonly Expression[]) { 6015 return createMethodCall(array, "concat", argumentsList); 6016 } 6017 6018 function createObjectDefinePropertyCall(target: Expression, propertyName: string | Expression, attributes: Expression) { 6019 return createGlobalMethodCall("Object", "defineProperty", [target, asExpression(propertyName), attributes]); 6020 } 6021 6022 function createReflectGetCall(target: Expression, propertyKey: Expression, receiver?: Expression): CallExpression { 6023 return createGlobalMethodCall("Reflect", "get", receiver ? [target, propertyKey, receiver] : [target, propertyKey]); 6024 } 6025 6026 function createReflectSetCall(target: Expression, propertyKey: Expression, value: Expression, receiver?: Expression): CallExpression { 6027 return createGlobalMethodCall("Reflect", "set", receiver ? [target, propertyKey, value, receiver] : [target, propertyKey, value]); 6028 } 6029 6030 function tryAddPropertyAssignment(properties: Push<PropertyAssignment>, propertyName: string, expression: Expression | undefined) { 6031 if (expression) { 6032 properties.push(createPropertyAssignment(propertyName, expression)); 6033 return true; 6034 } 6035 return false; 6036 } 6037 6038 function createPropertyDescriptor(attributes: PropertyDescriptorAttributes, singleLine?: boolean) { 6039 const properties: PropertyAssignment[] = []; 6040 tryAddPropertyAssignment(properties, "enumerable", asExpression(attributes.enumerable)); 6041 tryAddPropertyAssignment(properties, "configurable", asExpression(attributes.configurable)); 6042 6043 let isData = tryAddPropertyAssignment(properties, "writable", asExpression(attributes.writable)); 6044 isData = tryAddPropertyAssignment(properties, "value", attributes.value) || isData; 6045 6046 let isAccessor = tryAddPropertyAssignment(properties, "get", attributes.get); 6047 isAccessor = tryAddPropertyAssignment(properties, "set", attributes.set) || isAccessor; 6048 6049 Debug.assert(!(isData && isAccessor), "A PropertyDescriptor may not be both an accessor descriptor and a data descriptor."); 6050 return createObjectLiteralExpression(properties, !singleLine); 6051 } 6052 6053 function updateOuterExpression(outerExpression: OuterExpression, expression: Expression) { 6054 switch (outerExpression.kind) { 6055 case SyntaxKind.ParenthesizedExpression: return updateParenthesizedExpression(outerExpression, expression); 6056 case SyntaxKind.TypeAssertionExpression: return updateTypeAssertion(outerExpression, outerExpression.type, expression); 6057 case SyntaxKind.AsExpression: return updateAsExpression(outerExpression, expression, outerExpression.type); 6058 case SyntaxKind.SatisfiesExpression: return updateSatisfiesExpression(outerExpression, expression, outerExpression.type); 6059 case SyntaxKind.NonNullExpression: return updateNonNullExpression(outerExpression, expression); 6060 case SyntaxKind.PartiallyEmittedExpression: return updatePartiallyEmittedExpression(outerExpression, expression); 6061 } 6062 } 6063 6064 /** 6065 * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions. 6066 * 6067 * A parenthesized expression can be ignored when all of the following are true: 6068 * 6069 * - It's `pos` and `end` are not -1 6070 * - It does not have a custom source map range 6071 * - It does not have a custom comment range 6072 * - It does not have synthetic leading or trailing comments 6073 * 6074 * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around 6075 * the expression to maintain precedence, a new parenthesized expression should be created automatically when 6076 * the containing expression is created/updated. 6077 */ 6078 function isIgnorableParen(node: Expression) { 6079 return isParenthesizedExpression(node) 6080 && nodeIsSynthesized(node) 6081 && nodeIsSynthesized(getSourceMapRange(node)) 6082 && nodeIsSynthesized(getCommentRange(node)) 6083 && !some(getSyntheticLeadingComments(node)) 6084 && !some(getSyntheticTrailingComments(node)); 6085 } 6086 6087 function restoreOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression { 6088 if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { 6089 return updateOuterExpression( 6090 outerExpression, 6091 restoreOuterExpressions(outerExpression.expression, innerExpression) 6092 ); 6093 } 6094 return innerExpression; 6095 } 6096 6097 function restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement | undefined, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement { 6098 if (!outermostLabeledStatement) { 6099 return node; 6100 } 6101 const updated = updateLabeledStatement( 6102 outermostLabeledStatement, 6103 outermostLabeledStatement.label, 6104 isLabeledStatement(outermostLabeledStatement.statement) 6105 ? restoreEnclosingLabel(node, outermostLabeledStatement.statement) 6106 : node 6107 ); 6108 if (afterRestoreLabelCallback) { 6109 afterRestoreLabelCallback(outermostLabeledStatement); 6110 } 6111 return updated; 6112 } 6113 6114 function shouldBeCapturedInTempVariable(node: Expression, cacheIdentifiers: boolean): boolean { 6115 const target = skipParentheses(node); 6116 switch (target.kind) { 6117 case SyntaxKind.Identifier: 6118 return cacheIdentifiers; 6119 case SyntaxKind.ThisKeyword: 6120 case SyntaxKind.NumericLiteral: 6121 case SyntaxKind.BigIntLiteral: 6122 case SyntaxKind.StringLiteral: 6123 return false; 6124 case SyntaxKind.ArrayLiteralExpression: 6125 const elements = (target as ArrayLiteralExpression).elements; 6126 if (elements.length === 0) { 6127 return false; 6128 } 6129 return true; 6130 case SyntaxKind.ObjectLiteralExpression: 6131 return (target as ObjectLiteralExpression).properties.length > 0; 6132 default: 6133 return true; 6134 } 6135 } 6136 6137 function createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers = false): CallBinding { 6138 const callee = skipOuterExpressions(expression, OuterExpressionKinds.All); 6139 let thisArg: Expression; 6140 let target: LeftHandSideExpression; 6141 if (isSuperProperty(callee)) { 6142 thisArg = createThis(); 6143 target = callee; 6144 } 6145 else if (isSuperKeyword(callee)) { 6146 thisArg = createThis(); 6147 target = languageVersion !== undefined && languageVersion < ScriptTarget.ES2015 6148 ? setTextRange(createIdentifier("_super"), callee) 6149 : callee as PrimaryExpression; 6150 } 6151 else if (getEmitFlags(callee) & EmitFlags.HelperName) { 6152 thisArg = createVoidZero(); 6153 target = parenthesizerRules().parenthesizeLeftSideOfAccess(callee, /*optionalChain*/ false); 6154 } 6155 else if (isPropertyAccessExpression(callee)) { 6156 if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) { 6157 // for `a.b()` target is `(_a = a).b` and thisArg is `_a` 6158 thisArg = createTempVariable(recordTempVariable); 6159 target = createPropertyAccessExpression( 6160 setTextRange( 6161 factory.createAssignment( 6162 thisArg, 6163 callee.expression 6164 ), 6165 callee.expression 6166 ), 6167 callee.name 6168 ); 6169 setTextRange(target, callee); 6170 } 6171 else { 6172 thisArg = callee.expression; 6173 target = callee; 6174 } 6175 } 6176 else if (isElementAccessExpression(callee)) { 6177 if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) { 6178 // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a` 6179 thisArg = createTempVariable(recordTempVariable); 6180 target = createElementAccessExpression( 6181 setTextRange( 6182 factory.createAssignment( 6183 thisArg, 6184 callee.expression 6185 ), 6186 callee.expression 6187 ), 6188 callee.argumentExpression 6189 ); 6190 setTextRange(target, callee); 6191 } 6192 else { 6193 thisArg = callee.expression; 6194 target = callee; 6195 } 6196 } 6197 else { 6198 // for `a()` target is `a` and thisArg is `void 0` 6199 thisArg = createVoidZero(); 6200 target = parenthesizerRules().parenthesizeLeftSideOfAccess(expression, /*optionalChain*/ false); 6201 } 6202 6203 return { target, thisArg }; 6204 } 6205 6206 function createAssignmentTargetWrapper(paramName: Identifier, expression: Expression): LeftHandSideExpression { 6207 return createPropertyAccessExpression( 6208 // Explicit parens required because of v8 regression (https://bugs.chromium.org/p/v8/issues/detail?id=9560) 6209 createParenthesizedExpression( 6210 createObjectLiteralExpression([ 6211 createSetAccessorDeclaration( 6212 /*modifiers*/ undefined, 6213 "value", 6214 [createParameterDeclaration( 6215 /*modifiers*/ undefined, 6216 /*dotDotDotToken*/ undefined, 6217 paramName, 6218 /*questionToken*/ undefined, 6219 /*type*/ undefined, 6220 /*initializer*/ undefined 6221 )], 6222 createBlock([ 6223 createExpressionStatement(expression) 6224 ]) 6225 ) 6226 ]) 6227 ), 6228 "value" 6229 ); 6230 } 6231 6232 function inlineExpressions(expressions: readonly Expression[]) { 6233 // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call 6234 // stack size exceeded" errors. 6235 return expressions.length > 10 6236 ? createCommaListExpression(expressions) 6237 : reduceLeft(expressions, factory.createComma)!; 6238 } 6239 6240 function getName(node: Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags: EmitFlags = 0) { 6241 const nodeName = getNameOfDeclaration(node); 6242 if (nodeName && isIdentifier(nodeName) && !isGeneratedIdentifier(nodeName)) { 6243 // TODO(rbuckton): Does this need to be parented? 6244 const name = setParent(setTextRange(cloneNode(nodeName), nodeName), nodeName.parent); 6245 emitFlags |= getEmitFlags(nodeName); 6246 if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; 6247 if (!allowComments) emitFlags |= EmitFlags.NoComments; 6248 if (emitFlags) setEmitFlags(name, emitFlags); 6249 return name; 6250 } 6251 return getGeneratedNameForNode(node); 6252 } 6253 6254 /** 6255 * Gets the internal name of a declaration. This is primarily used for declarations that can be 6256 * referred to by name in the body of an ES5 class function body. An internal name will *never* 6257 * be prefixed with an module or namespace export modifier like "exports." when emitted as an 6258 * expression. An internal name will also *never* be renamed due to a collision with a block 6259 * scoped variable. 6260 * 6261 * @param node The declaration. 6262 * @param allowComments A value indicating whether comments may be emitted for the name. 6263 * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. 6264 */ 6265 function getInternalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { 6266 return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName | EmitFlags.InternalName); 6267 } 6268 6269 /** 6270 * Gets the local name of a declaration. This is primarily used for declarations that can be 6271 * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A 6272 * local name will *never* be prefixed with an module or namespace export modifier like 6273 * "exports." when emitted as an expression. 6274 * 6275 * @param node The declaration. 6276 * @param allowComments A value indicating whether comments may be emitted for the name. 6277 * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. 6278 */ 6279 function getLocalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { 6280 return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName); 6281 } 6282 6283 /** 6284 * Gets the export name of a declaration. This is primarily used for declarations that can be 6285 * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An 6286 * export name will *always* be prefixed with an module or namespace export modifier like 6287 * `"exports."` when emitted as an expression if the name points to an exported symbol. 6288 * 6289 * @param node The declaration. 6290 * @param allowComments A value indicating whether comments may be emitted for the name. 6291 * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. 6292 */ 6293 function getExportName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier { 6294 return getName(node, allowComments, allowSourceMaps, EmitFlags.ExportName); 6295 } 6296 6297 /** 6298 * Gets the name of a declaration for use in declarations. 6299 * 6300 * @param node The declaration. 6301 * @param allowComments A value indicating whether comments may be emitted for the name. 6302 * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. 6303 */ 6304 function getDeclarationName(node: Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean) { 6305 return getName(node, allowComments, allowSourceMaps); 6306 } 6307 6308 /** 6309 * Gets a namespace-qualified name for use in expressions. 6310 * 6311 * @param ns The namespace identifier. 6312 * @param name The name. 6313 * @param allowComments A value indicating whether comments may be emitted for the name. 6314 * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. 6315 */ 6316 function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression { 6317 const qualifiedName = createPropertyAccessExpression(ns, nodeIsSynthesized(name) ? name : cloneNode(name)); 6318 setTextRange(qualifiedName, name); 6319 let emitFlags: EmitFlags = 0; 6320 if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; 6321 if (!allowComments) emitFlags |= EmitFlags.NoComments; 6322 if (emitFlags) setEmitFlags(qualifiedName, emitFlags); 6323 return qualifiedName; 6324 } 6325 6326 /** 6327 * Gets the exported name of a declaration for use in expressions. 6328 * 6329 * An exported name will *always* be prefixed with an module or namespace export modifier like 6330 * "exports." if the name points to an exported symbol. 6331 * 6332 * @param ns The namespace identifier. 6333 * @param node The declaration. 6334 * @param allowComments A value indicating whether comments may be emitted for the name. 6335 * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. 6336 */ 6337 function getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression { 6338 if (ns && hasSyntacticModifier(node, ModifierFlags.Export)) { 6339 return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps); 6340 } 6341 return getExportName(node, allowComments, allowSourceMaps); 6342 } 6343 6344 /** 6345 * Copies any necessary standard and custom prologue-directives into target array. 6346 * @param source origin statements array 6347 * @param target result statements array 6348 * @param ensureUseStrict boolean determining whether the function need to add prologue-directives 6349 * @param visitor Optional callback used to visit any custom prologue directives. 6350 */ 6351 function copyPrologue(source: readonly Statement[], target: Push<Statement>, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number { 6352 const offset = copyStandardPrologue(source, target, 0, ensureUseStrict); 6353 return copyCustomPrologue(source, target, offset, visitor); 6354 } 6355 6356 function isUseStrictPrologue(node: ExpressionStatement): boolean { 6357 return isStringLiteral(node.expression) && node.expression.text === "use strict"; 6358 } 6359 6360 function createUseStrictPrologue() { 6361 return startOnNewLine(createExpressionStatement(createStringLiteral("use strict"))) as PrologueDirective; 6362 } 6363 6364 /** 6365 * Copies only the standard (string-expression) prologue-directives into the target statement-array. 6366 * @param source origin statements array 6367 * @param target result statements array 6368 * @param statementOffset The offset at which to begin the copy. 6369 * @param ensureUseStrict boolean determining whether the function need to add prologue-directives 6370 * @returns Count of how many directive statements were copied. 6371 */ 6372 function copyStandardPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset = 0, ensureUseStrict?: boolean): number { 6373 Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array"); 6374 let foundUseStrict = false; 6375 const numStatements = source.length; 6376 while (statementOffset < numStatements) { 6377 const statement = source[statementOffset]; 6378 if (isPrologueDirective(statement)) { 6379 if (isUseStrictPrologue(statement)) { 6380 foundUseStrict = true; 6381 } 6382 target.push(statement); 6383 } 6384 else { 6385 break; 6386 } 6387 statementOffset++; 6388 } 6389 if (ensureUseStrict && !foundUseStrict) { 6390 target.push(createUseStrictPrologue()); 6391 } 6392 return statementOffset; 6393 } 6394 6395 /** 6396 * Copies only the custom prologue-directives into target statement-array. 6397 * @param source origin statements array 6398 * @param target result statements array 6399 * @param statementOffset The offset at which to begin the copy. 6400 * @param visitor Optional callback used to visit any custom prologue directives. 6401 */ 6402 function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Node) => boolean): number; 6403 function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Node) => boolean): number | undefined; 6404 function copyCustomPrologue(source: readonly Statement[], target: Push<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter: (node: Node) => boolean = returnTrue): number | undefined { 6405 const numStatements = source.length; 6406 while (statementOffset !== undefined && statementOffset < numStatements) { 6407 const statement = source[statementOffset]; 6408 if (getEmitFlags(statement) & EmitFlags.CustomPrologue && filter(statement)) { 6409 append(target, visitor ? visitNode(statement, visitor, isStatement) : statement); 6410 } 6411 else { 6412 break; 6413 } 6414 statementOffset++; 6415 } 6416 return statementOffset; 6417 } 6418 6419 /** 6420 * Ensures "use strict" directive is added 6421 * 6422 * @param statements An array of statements 6423 */ 6424 function ensureUseStrict(statements: NodeArray<Statement>): NodeArray<Statement> { 6425 const foundUseStrict = findUseStrictPrologue(statements); 6426 6427 if (!foundUseStrict) { 6428 return setTextRange(createNodeArray<Statement>([createUseStrictPrologue(), ...statements]), statements); 6429 } 6430 6431 return statements; 6432 } 6433 6434 /** 6435 * Lifts a NodeArray containing only Statement nodes to a block. 6436 * 6437 * @param nodes The NodeArray. 6438 */ 6439 function liftToBlock(nodes: readonly Node[]): Statement { 6440 Debug.assert(every(nodes, isStatementOrBlock), "Cannot lift nodes to a Block."); 6441 return singleOrUndefined(nodes) as Statement || createBlock(nodes as readonly Statement[]); 6442 } 6443 6444 function findSpanEnd<T>(array: readonly T[], test: (value: T) => boolean, start: number) { 6445 let i = start; 6446 while (i < array.length && test(array[i])) { 6447 i++; 6448 } 6449 return i; 6450 } 6451 6452 function mergeLexicalEnvironment(statements: NodeArray<Statement>, declarations: readonly Statement[] | undefined): NodeArray<Statement>; 6453 function mergeLexicalEnvironment(statements: Statement[], declarations: readonly Statement[] | undefined): Statement[]; 6454 function mergeLexicalEnvironment(statements: Statement[] | NodeArray<Statement>, declarations: readonly Statement[] | undefined) { 6455 if (!some(declarations)) { 6456 return statements; 6457 } 6458 6459 // When we merge new lexical statements into an existing statement list, we merge them in the following manner: 6460 // 6461 // Given: 6462 // 6463 // | Left | Right | 6464 // |------------------------------------|-------------------------------------| 6465 // | [standard prologues (left)] | [standard prologues (right)] | 6466 // | [hoisted functions (left)] | [hoisted functions (right)] | 6467 // | [hoisted variables (left)] | [hoisted variables (right)] | 6468 // | [lexical init statements (left)] | [lexical init statements (right)] | 6469 // | [other statements (left)] | | 6470 // 6471 // The resulting statement list will be: 6472 // 6473 // | Result | 6474 // |-------------------------------------| 6475 // | [standard prologues (right)] | 6476 // | [standard prologues (left)] | 6477 // | [hoisted functions (right)] | 6478 // | [hoisted functions (left)] | 6479 // | [hoisted variables (right)] | 6480 // | [hoisted variables (left)] | 6481 // | [lexical init statements (right)] | 6482 // | [lexical init statements (left)] | 6483 // | [other statements (left)] | 6484 // 6485 // NOTE: It is expected that new lexical init statements must be evaluated before existing lexical init statements, 6486 // as the prior transformation may depend on the evaluation of the lexical init statements to be in the correct state. 6487 6488 // find standard prologues on left in the following order: standard directives, hoisted functions, hoisted variables, other custom 6489 const leftStandardPrologueEnd = findSpanEnd(statements, isPrologueDirective, 0); 6490 const leftHoistedFunctionsEnd = findSpanEnd(statements, isHoistedFunction, leftStandardPrologueEnd); 6491 const leftHoistedVariablesEnd = findSpanEnd(statements, isHoistedVariableStatement, leftHoistedFunctionsEnd); 6492 6493 // find standard prologues on right in the following order: standard directives, hoisted functions, hoisted variables, other custom 6494 const rightStandardPrologueEnd = findSpanEnd(declarations, isPrologueDirective, 0); 6495 const rightHoistedFunctionsEnd = findSpanEnd(declarations, isHoistedFunction, rightStandardPrologueEnd); 6496 const rightHoistedVariablesEnd = findSpanEnd(declarations, isHoistedVariableStatement, rightHoistedFunctionsEnd); 6497 const rightCustomPrologueEnd = findSpanEnd(declarations, isCustomPrologue, rightHoistedVariablesEnd); 6498 Debug.assert(rightCustomPrologueEnd === declarations.length, "Expected declarations to be valid standard or custom prologues"); 6499 6500 // splice prologues from the right into the left. We do this in reverse order 6501 // so that we don't need to recompute the index on the left when we insert items. 6502 const left = isNodeArray(statements) ? statements.slice() : statements; 6503 6504 // splice other custom prologues from right into left 6505 if (rightCustomPrologueEnd > rightHoistedVariablesEnd) { 6506 left.splice(leftHoistedVariablesEnd, 0, ...declarations.slice(rightHoistedVariablesEnd, rightCustomPrologueEnd)); 6507 } 6508 6509 // splice hoisted variables from right into left 6510 if (rightHoistedVariablesEnd > rightHoistedFunctionsEnd) { 6511 left.splice(leftHoistedFunctionsEnd, 0, ...declarations.slice(rightHoistedFunctionsEnd, rightHoistedVariablesEnd)); 6512 } 6513 6514 // splice hoisted functions from right into left 6515 if (rightHoistedFunctionsEnd > rightStandardPrologueEnd) { 6516 left.splice(leftStandardPrologueEnd, 0, ...declarations.slice(rightStandardPrologueEnd, rightHoistedFunctionsEnd)); 6517 } 6518 6519 // splice standard prologues from right into left (that are not already in left) 6520 if (rightStandardPrologueEnd > 0) { 6521 if (leftStandardPrologueEnd === 0) { 6522 left.splice(0, 0, ...declarations.slice(0, rightStandardPrologueEnd)); 6523 } 6524 else { 6525 const leftPrologues = new Map<string, boolean>(); 6526 for (let i = 0; i < leftStandardPrologueEnd; i++) { 6527 const leftPrologue = statements[i] as PrologueDirective; 6528 leftPrologues.set(leftPrologue.expression.text, true); 6529 } 6530 for (let i = rightStandardPrologueEnd - 1; i >= 0; i--) { 6531 const rightPrologue = declarations[i] as PrologueDirective; 6532 if (!leftPrologues.has(rightPrologue.expression.text)) { 6533 left.unshift(rightPrologue); 6534 } 6535 } 6536 } 6537 } 6538 6539 if (isNodeArray(statements)) { 6540 return setTextRange(createNodeArray(left, statements.hasTrailingComma), statements); 6541 } 6542 6543 return statements; 6544 } 6545 6546 function updateModifiers<T extends HasModifiers>(node: T, modifiers: readonly Modifier[] | ModifierFlags): T; 6547 function updateModifiers(node: HasModifiers, modifiers: readonly Modifier[] | ModifierFlags) { 6548 let modifierArray; 6549 if (typeof modifiers === "number") { 6550 modifierArray = createModifiersFromModifierFlags(modifiers); 6551 } 6552 else { 6553 modifierArray = modifiers; 6554 } 6555 return isTypeParameterDeclaration(node) ? updateTypeParameterDeclaration(node, modifierArray, node.name, node.constraint, node.default) : 6556 isParameter(node) ? updateParameterDeclaration(node, modifierArray, node.dotDotDotToken, node.name, node.questionToken, node.type, node.initializer) : 6557 isConstructorTypeNode(node) ? updateConstructorTypeNode1(node, modifierArray, node.typeParameters, node.parameters, node.type) : 6558 isPropertySignature(node) ? updatePropertySignature(node, modifierArray, node.name, node.questionToken, node.type) : 6559 isPropertyDeclaration(node) ? updatePropertyDeclaration(node, modifierArray, node.name, node.questionToken ?? node.exclamationToken, node.type, node.initializer) : 6560 isMethodSignature(node) ? updateMethodSignature(node, modifierArray, node.name, node.questionToken, node.typeParameters, node.parameters, node.type) : 6561 isMethodDeclaration(node) ? updateMethodDeclaration(node, modifierArray, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body) : 6562 isConstructorDeclaration(node) ? updateConstructorDeclaration(node, modifierArray, node.parameters, node.body) : 6563 isGetAccessorDeclaration(node) ? updateGetAccessorDeclaration(node, modifierArray, node.name, node.parameters, node.type, node.body) : 6564 isSetAccessorDeclaration(node) ? updateSetAccessorDeclaration(node, modifierArray, node.name, node.parameters, node.body) : 6565 isIndexSignatureDeclaration(node) ? updateIndexSignature(node, modifierArray, node.parameters, node.type) : 6566 isFunctionExpression(node) ? updateFunctionExpression(node, modifierArray, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) : 6567 isArrowFunction(node) ? updateArrowFunction(node, modifierArray, node.typeParameters, node.parameters, node.type, node.equalsGreaterThanToken, node.body) : 6568 isClassExpression(node) ? updateClassExpression(node, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : 6569 isStructDeclaration(node) ? updateStructDeclaration(node, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : 6570 isAnnotationDeclaration(node) ? updateAnnotationDeclaration(node, modifierArray, node.name, node.members) : 6571 isVariableStatement(node) ? updateVariableStatement(node, modifierArray, node.declarationList) : 6572 isFunctionDeclaration(node) ? updateFunctionDeclaration(node, modifierArray, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) : 6573 isClassDeclaration(node) ? updateClassDeclaration(node, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : 6574 isInterfaceDeclaration(node) ? updateInterfaceDeclaration(node, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : 6575 isTypeAliasDeclaration(node) ? updateTypeAliasDeclaration(node, modifierArray, node.name, node.typeParameters, node.type) : 6576 isEnumDeclaration(node) ? updateEnumDeclaration(node, modifierArray, node.name, node.members) : 6577 isModuleDeclaration(node) ? updateModuleDeclaration(node, modifierArray, node.name, node.body) : 6578 isImportEqualsDeclaration(node) ? updateImportEqualsDeclaration(node, modifierArray, node.isTypeOnly, node.name, node.moduleReference) : 6579 isImportDeclaration(node) ? updateImportDeclaration(node, modifierArray, node.importClause, node.moduleSpecifier, node.assertClause) : 6580 isExportAssignment(node) ? updateExportAssignment(node, modifierArray, node.expression) : 6581 isExportDeclaration(node) ? updateExportDeclaration(node, modifierArray, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause) : 6582 Debug.assertNever(node); 6583 } 6584 6585 function asNodeArray<T extends Node>(array: readonly T[]): NodeArray<T>; 6586 function asNodeArray<T extends Node>(array: readonly T[] | undefined): NodeArray<T> | undefined; 6587 function asNodeArray<T extends Node>(array: readonly T[] | undefined): NodeArray<T> | undefined { 6588 return array ? createNodeArray(array) : undefined; 6589 } 6590 6591 function asName<T extends DeclarationName | Identifier | BindingName | PropertyName | NoSubstitutionTemplateLiteral | EntityName | ThisTypeNode | undefined>(name: string | T): T | Identifier { 6592 return typeof name === "string" ? createIdentifier(name) : 6593 name; 6594 } 6595 6596 function asExpression<T extends Expression | undefined>(value: string | number | boolean | T): T | StringLiteral | NumericLiteral | BooleanLiteral { 6597 return typeof value === "string" ? createStringLiteral(value) : 6598 typeof value === "number" ? createNumericLiteral(value) : 6599 typeof value === "boolean" ? value ? createTrue() : createFalse() : 6600 value; 6601 } 6602 6603 function asToken<TKind extends SyntaxKind>(value: TKind | Token<TKind>): Token<TKind> { 6604 return typeof value === "number" ? createToken(value) : value; 6605 } 6606 6607 function asEmbeddedStatement<T extends Node>(statement: T): T | EmptyStatement; 6608 function asEmbeddedStatement<T extends Node>(statement: T | undefined): T | EmptyStatement | undefined; 6609 function asEmbeddedStatement<T extends Node>(statement: T | undefined): T | EmptyStatement | undefined { 6610 return statement && isNotEmittedStatement(statement) ? setTextRange(setOriginalNode(createEmptyStatement(), statement), statement) : statement; 6611 } 6612} 6613 6614function updateWithoutOriginal<T extends Node>(updated: Mutable<T>, original: T): T { 6615 if (updated !== original) { 6616 setTextRange(updated, original); 6617 } 6618 return updated; 6619} 6620 6621function updateWithOriginal<T extends Node>(updated: Mutable<T>, original: T): T { 6622 if (updated !== original) { 6623 setOriginalNode(updated, original); 6624 setTextRange(updated, original); 6625 } 6626 return updated; 6627} 6628 6629function getDefaultTagNameForKind(kind: JSDocTag["kind"]): string { 6630 switch (kind) { 6631 case SyntaxKind.JSDocTypeTag: return "type"; 6632 case SyntaxKind.JSDocReturnTag: return "returns"; 6633 case SyntaxKind.JSDocThisTag: return "this"; 6634 case SyntaxKind.JSDocEnumTag: return "enum"; 6635 case SyntaxKind.JSDocAuthorTag: return "author"; 6636 case SyntaxKind.JSDocClassTag: return "class"; 6637 case SyntaxKind.JSDocPublicTag: return "public"; 6638 case SyntaxKind.JSDocPrivateTag: return "private"; 6639 case SyntaxKind.JSDocProtectedTag: return "protected"; 6640 case SyntaxKind.JSDocReadonlyTag: return "readonly"; 6641 case SyntaxKind.JSDocOverrideTag: return "override"; 6642 case SyntaxKind.JSDocTemplateTag: return "template"; 6643 case SyntaxKind.JSDocTypedefTag: return "typedef"; 6644 case SyntaxKind.JSDocParameterTag: return "param"; 6645 case SyntaxKind.JSDocPropertyTag: return "prop"; 6646 case SyntaxKind.JSDocCallbackTag: return "callback"; 6647 case SyntaxKind.JSDocAugmentsTag: return "augments"; 6648 case SyntaxKind.JSDocImplementsTag: return "implements"; 6649 default: 6650 return Debug.fail(`Unsupported kind: ${Debug.formatSyntaxKind(kind)}`); 6651 } 6652} 6653 6654let rawTextScanner: Scanner | undefined; 6655const invalidValueSentinel: object = { }; 6656 6657function getCookedText(kind: TemplateLiteralToken["kind"], rawText: string) { 6658 if (!rawTextScanner) { 6659 rawTextScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard); 6660 } 6661 switch (kind) { 6662 case SyntaxKind.NoSubstitutionTemplateLiteral: 6663 rawTextScanner.setText("`" + rawText + "`"); 6664 break; 6665 case SyntaxKind.TemplateHead: 6666 rawTextScanner.setText("`" + rawText + "${"); 6667 break; 6668 case SyntaxKind.TemplateMiddle: 6669 rawTextScanner.setText("}" + rawText + "${"); 6670 break; 6671 case SyntaxKind.TemplateTail: 6672 rawTextScanner.setText("}" + rawText + "`"); 6673 break; 6674 } 6675 6676 let token = rawTextScanner.scan(); 6677 if (token === SyntaxKind.CloseBraceToken) { 6678 token = rawTextScanner.reScanTemplateToken(/*isTaggedTemplate*/ false); 6679 } 6680 6681 if (rawTextScanner.isUnterminated()) { 6682 rawTextScanner.setText(undefined); 6683 return invalidValueSentinel; 6684 } 6685 6686 let tokenValue: string | undefined; 6687 switch (token) { 6688 case SyntaxKind.NoSubstitutionTemplateLiteral: 6689 case SyntaxKind.TemplateHead: 6690 case SyntaxKind.TemplateMiddle: 6691 case SyntaxKind.TemplateTail: 6692 tokenValue = rawTextScanner.getTokenValue(); 6693 break; 6694 } 6695 6696 if (tokenValue === undefined || rawTextScanner.scan() !== SyntaxKind.EndOfFileToken) { 6697 rawTextScanner.setText(undefined); 6698 return invalidValueSentinel; 6699 } 6700 6701 rawTextScanner.setText(undefined); 6702 return tokenValue; 6703} 6704 6705function propagateIdentifierNameFlags(node: Identifier) { 6706 // An IdentifierName is allowed to be `await` 6707 return propagateChildFlags(node) & ~TransformFlags.ContainsPossibleTopLevelAwait; 6708} 6709 6710function propagatePropertyNameFlagsOfChild(node: PropertyName, transformFlags: TransformFlags) { 6711 return transformFlags | (node.transformFlags & TransformFlags.PropertyNamePropagatingFlags); 6712} 6713 6714function propagateChildFlags(child: Node | undefined): TransformFlags { 6715 if (!child) return TransformFlags.None; 6716 const childFlags = child.transformFlags & ~getTransformFlagsSubtreeExclusions(child.kind); 6717 return isNamedDeclaration(child) && isPropertyName(child.name) ? propagatePropertyNameFlagsOfChild(child.name, childFlags) : childFlags; 6718} 6719 6720function propagateChildrenFlags(children: NodeArray<Node> | undefined): TransformFlags { 6721 return children ? children.transformFlags : TransformFlags.None; 6722} 6723 6724function aggregateChildrenFlags(children: MutableNodeArray<Node>) { 6725 let subtreeFlags = TransformFlags.None; 6726 for (const child of children) { 6727 subtreeFlags |= propagateChildFlags(child); 6728 } 6729 children.transformFlags = subtreeFlags; 6730} 6731 6732/** 6733 * Gets the transform flags to exclude when unioning the transform flags of a subtree. 6734 * 6735 * @internal 6736 */ 6737export function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) { 6738 if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) { 6739 return TransformFlags.TypeExcludes; 6740 } 6741 6742 switch (kind) { 6743 case SyntaxKind.CallExpression: 6744 case SyntaxKind.NewExpression: 6745 case SyntaxKind.ArrayLiteralExpression: 6746 return TransformFlags.ArrayLiteralOrCallOrNewExcludes; 6747 case SyntaxKind.ModuleDeclaration: 6748 return TransformFlags.ModuleExcludes; 6749 case SyntaxKind.Parameter: 6750 return TransformFlags.ParameterExcludes; 6751 case SyntaxKind.ArrowFunction: 6752 return TransformFlags.ArrowFunctionExcludes; 6753 case SyntaxKind.FunctionExpression: 6754 case SyntaxKind.FunctionDeclaration: 6755 return TransformFlags.FunctionExcludes; 6756 case SyntaxKind.VariableDeclarationList: 6757 return TransformFlags.VariableDeclarationListExcludes; 6758 case SyntaxKind.ClassDeclaration: 6759 case SyntaxKind.ClassExpression: 6760 return TransformFlags.ClassExcludes; 6761 case SyntaxKind.Constructor: 6762 return TransformFlags.ConstructorExcludes; 6763 case SyntaxKind.PropertyDeclaration: 6764 return TransformFlags.PropertyExcludes; 6765 case SyntaxKind.MethodDeclaration: 6766 case SyntaxKind.GetAccessor: 6767 case SyntaxKind.SetAccessor: 6768 return TransformFlags.MethodOrAccessorExcludes; 6769 case SyntaxKind.AnyKeyword: 6770 case SyntaxKind.NumberKeyword: 6771 case SyntaxKind.BigIntKeyword: 6772 case SyntaxKind.NeverKeyword: 6773 case SyntaxKind.StringKeyword: 6774 case SyntaxKind.ObjectKeyword: 6775 case SyntaxKind.BooleanKeyword: 6776 case SyntaxKind.SymbolKeyword: 6777 case SyntaxKind.VoidKeyword: 6778 case SyntaxKind.TypeParameter: 6779 case SyntaxKind.PropertySignature: 6780 case SyntaxKind.MethodSignature: 6781 case SyntaxKind.CallSignature: 6782 case SyntaxKind.ConstructSignature: 6783 case SyntaxKind.IndexSignature: 6784 case SyntaxKind.InterfaceDeclaration: 6785 case SyntaxKind.TypeAliasDeclaration: 6786 return TransformFlags.TypeExcludes; 6787 case SyntaxKind.ObjectLiteralExpression: 6788 return TransformFlags.ObjectLiteralExcludes; 6789 case SyntaxKind.CatchClause: 6790 return TransformFlags.CatchClauseExcludes; 6791 case SyntaxKind.ObjectBindingPattern: 6792 case SyntaxKind.ArrayBindingPattern: 6793 return TransformFlags.BindingPatternExcludes; 6794 case SyntaxKind.TypeAssertionExpression: 6795 case SyntaxKind.SatisfiesExpression: 6796 case SyntaxKind.AsExpression: 6797 case SyntaxKind.PartiallyEmittedExpression: 6798 case SyntaxKind.ParenthesizedExpression: 6799 case SyntaxKind.SuperKeyword: 6800 return TransformFlags.OuterExpressionExcludes; 6801 case SyntaxKind.PropertyAccessExpression: 6802 case SyntaxKind.ElementAccessExpression: 6803 return TransformFlags.PropertyAccessExcludes; 6804 default: 6805 return TransformFlags.NodeExcludes; 6806 } 6807} 6808 6809const baseFactory = createBaseNodeFactory(); 6810 6811function makeSynthetic(node: Node) { 6812 (node as Mutable<Node>).flags |= NodeFlags.Synthesized; 6813 return node; 6814} 6815 6816const syntheticFactory: BaseNodeFactory = { 6817 createBaseSourceFileNode: kind => makeSynthetic(baseFactory.createBaseSourceFileNode(kind)), 6818 createBaseIdentifierNode: kind => makeSynthetic(baseFactory.createBaseIdentifierNode(kind)), 6819 createBasePrivateIdentifierNode: kind => makeSynthetic(baseFactory.createBasePrivateIdentifierNode(kind)), 6820 createBaseTokenNode: kind => makeSynthetic(baseFactory.createBaseTokenNode(kind)), 6821 createBaseNode: kind => makeSynthetic(baseFactory.createBaseNode(kind)), 6822}; 6823 6824export const factory = createNodeFactory(NodeFactoryFlags.NoIndentationOnFreshPropertyAccess, syntheticFactory); 6825 6826export function createUnparsedSourceFile(text: string): UnparsedSource; 6827export function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; 6828export function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; 6829export function createUnparsedSourceFile(textOrInputFiles: string | InputFiles, mapPathOrType?: string, mapTextOrStripInternal?: string | boolean): UnparsedSource { 6830 let stripInternal: boolean | undefined; 6831 let bundleFileInfo: BundleFileInfo | undefined; 6832 let fileName: string; 6833 let text: string | undefined; 6834 let length: number | (() => number); 6835 let sourceMapPath: string | undefined; 6836 let sourceMapText: string | undefined; 6837 let getText: (() => string) | undefined; 6838 let getSourceMapText: (() => string | undefined) | undefined; 6839 let oldFileOfCurrentEmit: boolean | undefined; 6840 6841 if (!isString(textOrInputFiles)) { 6842 Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts"); 6843 fileName = (mapPathOrType === "js" ? textOrInputFiles.javascriptPath : textOrInputFiles.declarationPath) || ""; 6844 sourceMapPath = mapPathOrType === "js" ? textOrInputFiles.javascriptMapPath : textOrInputFiles.declarationMapPath; 6845 getText = () => mapPathOrType === "js" ? textOrInputFiles.javascriptText : textOrInputFiles.declarationText; 6846 getSourceMapText = () => mapPathOrType === "js" ? textOrInputFiles.javascriptMapText : textOrInputFiles.declarationMapText; 6847 length = () => getText!().length; 6848 if (textOrInputFiles.buildInfo && textOrInputFiles.buildInfo.bundle) { 6849 Debug.assert(mapTextOrStripInternal === undefined || typeof mapTextOrStripInternal === "boolean"); 6850 stripInternal = mapTextOrStripInternal; 6851 bundleFileInfo = mapPathOrType === "js" ? textOrInputFiles.buildInfo.bundle.js : textOrInputFiles.buildInfo.bundle.dts; 6852 oldFileOfCurrentEmit = textOrInputFiles.oldFileOfCurrentEmit; 6853 } 6854 } 6855 else { 6856 fileName = ""; 6857 text = textOrInputFiles; 6858 length = textOrInputFiles.length; 6859 sourceMapPath = mapPathOrType; 6860 sourceMapText = mapTextOrStripInternal as string; 6861 } 6862 const node = oldFileOfCurrentEmit ? 6863 parseOldFileOfCurrentEmit(Debug.checkDefined(bundleFileInfo)) : 6864 parseUnparsedSourceFile(bundleFileInfo, stripInternal, length); 6865 node.fileName = fileName; 6866 node.sourceMapPath = sourceMapPath; 6867 node.oldFileOfCurrentEmit = oldFileOfCurrentEmit; 6868 if (getText && getSourceMapText) { 6869 Object.defineProperty(node, "text", { get: getText }); 6870 Object.defineProperty(node, "sourceMapText", { get: getSourceMapText }); 6871 } 6872 else { 6873 Debug.assert(!oldFileOfCurrentEmit); 6874 node.text = text ?? ""; 6875 node.sourceMapText = sourceMapText; 6876 } 6877 6878 return node; 6879} 6880 6881function parseUnparsedSourceFile(bundleFileInfo: BundleFileInfo | undefined, stripInternal: boolean | undefined, length: number | (() => number)) { 6882 let prologues: UnparsedPrologue[] | undefined; 6883 let helpers: UnscopedEmitHelper[] | undefined; 6884 let referencedFiles: FileReference[] | undefined; 6885 let typeReferenceDirectives: FileReference[] | undefined; 6886 let libReferenceDirectives: FileReference[] | undefined; 6887 let prependChildren: UnparsedTextLike[] | undefined; 6888 let texts: UnparsedSourceText[] | undefined; 6889 let hasNoDefaultLib: boolean | undefined; 6890 6891 for (const section of bundleFileInfo ? bundleFileInfo.sections : emptyArray) { 6892 switch (section.kind) { 6893 case BundleFileSectionKind.Prologue: 6894 prologues = append(prologues, setTextRange(factory.createUnparsedPrologue(section.data), section)); 6895 break; 6896 case BundleFileSectionKind.EmitHelpers: 6897 helpers = append(helpers, getAllUnscopedEmitHelpers().get(section.data)!); 6898 break; 6899 case BundleFileSectionKind.NoDefaultLib: 6900 hasNoDefaultLib = true; 6901 break; 6902 case BundleFileSectionKind.Reference: 6903 referencedFiles = append(referencedFiles, { pos: -1, end: -1, fileName: section.data }); 6904 break; 6905 case BundleFileSectionKind.Type: 6906 typeReferenceDirectives = append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data }); 6907 break; 6908 case BundleFileSectionKind.TypeResolutionModeImport: 6909 typeReferenceDirectives = append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data, resolutionMode: ModuleKind.ESNext }); 6910 break; 6911 case BundleFileSectionKind.TypeResolutionModeRequire: 6912 typeReferenceDirectives = append(typeReferenceDirectives, { pos: -1, end: -1, fileName: section.data, resolutionMode: ModuleKind.CommonJS }); 6913 break; 6914 case BundleFileSectionKind.Lib: 6915 libReferenceDirectives = append(libReferenceDirectives, { pos: -1, end: -1, fileName: section.data }); 6916 break; 6917 case BundleFileSectionKind.Prepend: 6918 let prependTexts: UnparsedTextLike[] | undefined; 6919 for (const text of section.texts) { 6920 if (!stripInternal || text.kind !== BundleFileSectionKind.Internal) { 6921 prependTexts = append(prependTexts, setTextRange(factory.createUnparsedTextLike(text.data, text.kind === BundleFileSectionKind.Internal), text)); 6922 } 6923 } 6924 prependChildren = addRange(prependChildren, prependTexts); 6925 texts = append(texts, factory.createUnparsedPrepend(section.data, prependTexts ?? emptyArray)); 6926 break; 6927 case BundleFileSectionKind.Internal: 6928 if (stripInternal) { 6929 if (!texts) texts = []; 6930 break; 6931 } 6932 // falls through 6933 6934 case BundleFileSectionKind.Text: 6935 texts = append(texts, setTextRange(factory.createUnparsedTextLike(section.data, section.kind === BundleFileSectionKind.Internal), section)); 6936 break; 6937 default: 6938 Debug.assertNever(section); 6939 } 6940 } 6941 6942 if (!texts) { 6943 const textNode = factory.createUnparsedTextLike(/*data*/ undefined, /*internal*/ false); 6944 setTextRangePosWidth(textNode, 0, typeof length === "function" ? length() : length); 6945 texts = [textNode]; 6946 } 6947 6948 const node = parseNodeFactory.createUnparsedSource(prologues ?? emptyArray, /*syntheticReferences*/ undefined, texts); 6949 setEachParent(prologues, node); 6950 setEachParent(texts, node); 6951 setEachParent(prependChildren, node); 6952 node.hasNoDefaultLib = hasNoDefaultLib; 6953 node.helpers = helpers; 6954 node.referencedFiles = referencedFiles || emptyArray; 6955 node.typeReferenceDirectives = typeReferenceDirectives; 6956 node.libReferenceDirectives = libReferenceDirectives || emptyArray; 6957 return node; 6958} 6959 6960function parseOldFileOfCurrentEmit(bundleFileInfo: BundleFileInfo) { 6961 let texts: UnparsedTextLike[] | undefined; 6962 let syntheticReferences: UnparsedSyntheticReference[] | undefined; 6963 for (const section of bundleFileInfo.sections) { 6964 switch (section.kind) { 6965 case BundleFileSectionKind.Internal: 6966 case BundleFileSectionKind.Text: 6967 texts = append(texts, setTextRange(factory.createUnparsedTextLike(section.data, section.kind === BundleFileSectionKind.Internal), section)); 6968 break; 6969 6970 case BundleFileSectionKind.NoDefaultLib: 6971 case BundleFileSectionKind.Reference: 6972 case BundleFileSectionKind.Type: 6973 case BundleFileSectionKind.TypeResolutionModeImport: 6974 case BundleFileSectionKind.TypeResolutionModeRequire: 6975 case BundleFileSectionKind.Lib: 6976 syntheticReferences = append(syntheticReferences, setTextRange(factory.createUnparsedSyntheticReference(section), section)); 6977 break; 6978 6979 // Ignore 6980 case BundleFileSectionKind.Prologue: 6981 case BundleFileSectionKind.EmitHelpers: 6982 case BundleFileSectionKind.Prepend: 6983 break; 6984 6985 default: 6986 Debug.assertNever(section); 6987 } 6988 } 6989 6990 const node = factory.createUnparsedSource(emptyArray, syntheticReferences, texts ?? emptyArray); 6991 setEachParent(syntheticReferences, node); 6992 setEachParent(texts, node); 6993 node.helpers = map(bundleFileInfo.sources && bundleFileInfo.sources.helpers, name => getAllUnscopedEmitHelpers().get(name)!); 6994 return node; 6995} 6996 6997// TODO(rbuckton): Move part of this to factory 6998export function createInputFiles( 6999 javascriptText: string, 7000 declarationText: string 7001): InputFiles; 7002export function createInputFiles( 7003 readFileText: (path: string) => string | undefined, 7004 javascriptPath: string, 7005 javascriptMapPath: string | undefined, 7006 declarationPath: string, 7007 declarationMapPath: string | undefined, 7008 buildInfoPath: string | undefined 7009): InputFiles; 7010export function createInputFiles( 7011 javascriptText: string, 7012 declarationText: string, 7013 javascriptMapPath: string | undefined, 7014 javascriptMapText: string | undefined, 7015 declarationMapPath: string | undefined, 7016 declarationMapText: string | undefined 7017): InputFiles; 7018/** @internal */ 7019export function createInputFiles( 7020 javascriptText: string, 7021 declarationText: string, 7022 javascriptMapPath: string | undefined, 7023 javascriptMapText: string | undefined, 7024 declarationMapPath: string | undefined, 7025 declarationMapText: string | undefined, 7026 javascriptPath: string | undefined, 7027 declarationPath: string | undefined, 7028 buildInfoPath?: string | undefined, 7029 buildInfo?: BuildInfo, 7030 oldFileOfCurrentEmit?: boolean 7031): InputFiles; 7032export function createInputFiles( 7033 javascriptTextOrReadFileText: string | ((path: string) => string | undefined), 7034 declarationTextOrJavascriptPath: string, 7035 javascriptMapPath?: string, 7036 javascriptMapTextOrDeclarationPath?: string, 7037 declarationMapPath?: string, 7038 declarationMapTextOrBuildInfoPath?: string, 7039 javascriptPath?: string | undefined, 7040 declarationPath?: string | undefined, 7041 buildInfoPath?: string | undefined, 7042 buildInfo?: BuildInfo, 7043 oldFileOfCurrentEmit?: boolean 7044): InputFiles { 7045 const node = parseNodeFactory.createInputFiles(); 7046 if (!isString(javascriptTextOrReadFileText)) { 7047 const cache = new Map<string, string | false>(); 7048 const textGetter = (path: string | undefined) => { 7049 if (path === undefined) return undefined; 7050 let value = cache.get(path); 7051 if (value === undefined) { 7052 value = javascriptTextOrReadFileText(path); 7053 cache.set(path, value !== undefined ? value : false); 7054 } 7055 return value !== false ? value as string : undefined; 7056 }; 7057 const definedTextGetter = (path: string) => { 7058 const result = textGetter(path); 7059 return result !== undefined ? result : `/* Input file ${path} was missing */\r\n`; 7060 }; 7061 let buildInfo: BuildInfo | false; 7062 const getAndCacheBuildInfo = (getText: () => string | undefined) => { 7063 if (buildInfo === undefined) { 7064 const result = getText(); 7065 buildInfo = result !== undefined ? getBuildInfo(node.buildInfoPath!, result) ?? false : false; 7066 } 7067 return buildInfo || undefined; 7068 }; 7069 node.javascriptPath = declarationTextOrJavascriptPath; 7070 node.javascriptMapPath = javascriptMapPath; 7071 node.declarationPath = Debug.checkDefined(javascriptMapTextOrDeclarationPath); 7072 node.declarationMapPath = declarationMapPath; 7073 node.buildInfoPath = declarationMapTextOrBuildInfoPath; 7074 Object.defineProperties(node, { 7075 javascriptText: { get() { return definedTextGetter(declarationTextOrJavascriptPath); } }, 7076 javascriptMapText: { get() { return textGetter(javascriptMapPath); } }, // TODO:: if there is inline sourceMap in jsFile, use that 7077 declarationText: { get() { return definedTextGetter(Debug.checkDefined(javascriptMapTextOrDeclarationPath)); } }, 7078 declarationMapText: { get() { return textGetter(declarationMapPath); } }, // TODO:: if there is inline sourceMap in dtsFile, use that 7079 buildInfo: { get() { return getAndCacheBuildInfo(() => textGetter(declarationMapTextOrBuildInfoPath)); } } 7080 }); 7081 } 7082 else { 7083 node.javascriptText = javascriptTextOrReadFileText; 7084 node.javascriptMapPath = javascriptMapPath; 7085 node.javascriptMapText = javascriptMapTextOrDeclarationPath; 7086 node.declarationText = declarationTextOrJavascriptPath; 7087 node.declarationMapPath = declarationMapPath; 7088 node.declarationMapText = declarationMapTextOrBuildInfoPath; 7089 node.javascriptPath = javascriptPath; 7090 node.declarationPath = declarationPath; 7091 node.buildInfoPath = buildInfoPath; 7092 node.buildInfo = buildInfo; 7093 node.oldFileOfCurrentEmit = oldFileOfCurrentEmit; 7094 } 7095 return node; 7096} 7097 7098let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; 7099 7100/** 7101 * Create an external source map source file reference 7102 */ 7103export function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource { 7104 return new (SourceMapSource || (SourceMapSource = objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia); 7105} 7106 7107// Utilities 7108 7109export function setOriginalNode<T extends Node>(node: T, original: Node | undefined): T { 7110 node.original = original; 7111 if (original) { 7112 const emitNode = original.emitNode; 7113 if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); 7114 } 7115 return node; 7116} 7117 7118function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode | undefined) { 7119 const { 7120 flags, 7121 leadingComments, 7122 trailingComments, 7123 commentRange, 7124 sourceMapRange, 7125 tokenSourceMapRanges, 7126 constantValue, 7127 helpers, 7128 startsOnNewLine, 7129 snippetElement, 7130 } = sourceEmitNode; 7131 if (!destEmitNode) destEmitNode = {} as EmitNode; 7132 // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later. 7133 if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments); 7134 if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments); 7135 if (flags) destEmitNode.flags = flags & ~EmitFlags.Immutable; 7136 if (commentRange) destEmitNode.commentRange = commentRange; 7137 if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange; 7138 if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges!); 7139 if (constantValue !== undefined) destEmitNode.constantValue = constantValue; 7140 if (helpers) { 7141 for (const helper of helpers) { 7142 destEmitNode.helpers = appendIfUnique(destEmitNode.helpers, helper); 7143 } 7144 } 7145 if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine; 7146 if (snippetElement !== undefined) destEmitNode.snippetElement = snippetElement; 7147 return destEmitNode; 7148} 7149 7150function mergeTokenSourceMapRanges(sourceRanges: (TextRange | undefined)[], destRanges: (TextRange | undefined)[]) { 7151 if (!destRanges) destRanges = []; 7152 for (const key in sourceRanges) { 7153 destRanges[key] = sourceRanges[key]; 7154 } 7155 return destRanges; 7156} 7157