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