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