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