diff --git a/.vscode/launch.template.json b/.vscode/launch.template.json index ede5febb3bff4..07e919ba96048 100644 --- a/.vscode/launch.template.json +++ b/.vscode/launch.template.json @@ -43,7 +43,7 @@ }, "sourceMaps": true, "smartStep": true, - "preLaunchTask": "tests", + "preLaunchTask": "gulp: tests", "console": "integratedTerminal", "outFiles": [ "${workspaceRoot}/built/local/run.js" diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 2f6f528677583..807da9ce56e69 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,31 +4,42 @@ "version": "2.0.0", "tasks": [ { - "type": "shell", - "identifier": "local", + "type": "gulp", "label": "gulp: local", - "command": "gulp", - "args": ["local"], - "group": { "kind": "build", "isDefault": true }, - "problemMatcher": ["$gulp-tsc"] + "task": "local", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [ + "$tsc" + ] }, { - "type": "shell", - "identifier": "tsc", + "type": "gulp", "label": "gulp: tsc", - "command": "gulp", - "args": ["tsc"], + "task": "tsc", "group": "build", - "problemMatcher": ["$gulp-tsc"] + "problemMatcher": [ + "$tsc" + ] }, { - "type": "shell", - "identifier": "tests", + "type": "gulp", "label": "gulp: tests", - "command": "gulp", - "args": ["tests"], + "task": "tests", "group": "build", - "problemMatcher": ["$gulp-tsc"] + "problemMatcher": [ + "$tsc" + ] + }, + { + "type": "gulp", + "task": "services", + "label": "gulp: services", + "problemMatcher": [ + "$tsc" + ], } ] } \ No newline at end of file diff --git a/src/compat/deprecations.ts b/src/compat/deprecations.ts new file mode 100644 index 0000000000000..e9a6dc3b9a878 --- /dev/null +++ b/src/compat/deprecations.ts @@ -0,0 +1,1324 @@ +namespace ts { + // The following are deprecations for the public API. Deprecated exports are removed from the compiler itself + // and compatible implementations are added here, along with an appropriate deprecation warning using + // the `@deprecated` JSDoc tag as well as the `Debug.deprecate` API. + // + // Deprecations fall into one of three categories: + // + // * "soft" - Soft deprecations are indicated with the `@deprecated` JSDoc Tag. + // * "warn" - Warning deprecations are indicated with the `@deprecated` JSDoc Tag and a diagnostic message (assuming a compatible host) + // * "error" - Error deprecations are indicated with the `@deprecated` JSDoc tag and will throw a `TypeError` when invoked. + + // DEPRECATION: Node factory top-level exports + // DEPRECATION PLAN: + // - soft: 4.0 + // - warn: 4.1 + // - error: TBD + // #region Node factory top-level exports + + // NOTE: These exports are deprecated in favor of using a `NodeFactory` instance and exist here purely for backwards compatibility reasons. + const factoryDeprecation: DeprecationOptions = { since: "4.0", warnAfter: "4.1", message: "Use the appropriate method on 'ts.factory' or the 'factory' supplied by your transformation context instead." }; + + /** @deprecated Use `factory.createNodeArray` or the factory supplied by your transformation context instead. */ + export const createNodeArray = Debug.deprecate(factory.createNodeArray, factoryDeprecation); + + /** @deprecated Use `factory.createNumericLiteral` or the factory supplied by your transformation context instead. */ + export const createNumericLiteral = Debug.deprecate(factory.createNumericLiteral, factoryDeprecation); + + /** @deprecated Use `factory.createBigIntLiteral` or the factory supplied by your transformation context instead. */ + export const createBigIntLiteral = Debug.deprecate(factory.createBigIntLiteral, factoryDeprecation); + + /** @deprecated Use `factory.createStringLiteral` or the factory supplied by your transformation context instead. */ + export const createStringLiteral = Debug.deprecate(factory.createStringLiteral, factoryDeprecation); + + /** @deprecated Use `factory.createStringLiteralFromNode` or the factory supplied by your transformation context instead. */ + export const createStringLiteralFromNode = Debug.deprecate(factory.createStringLiteralFromNode, factoryDeprecation); + + /** @deprecated Use `factory.createRegularExpressionLiteral` or the factory supplied by your transformation context instead. */ + export const createRegularExpressionLiteral = Debug.deprecate(factory.createRegularExpressionLiteral, factoryDeprecation); + + /** @deprecated Use `factory.createLoopVariable` or the factory supplied by your transformation context instead. */ + export const createLoopVariable = Debug.deprecate(factory.createLoopVariable, factoryDeprecation); + + /** @deprecated Use `factory.createUniqueName` or the factory supplied by your transformation context instead. */ + export const createUniqueName = Debug.deprecate(factory.createUniqueName, factoryDeprecation); + + /** @deprecated Use `factory.createPrivateIdentifier` or the factory supplied by your transformation context instead. */ + export const createPrivateIdentifier = Debug.deprecate(factory.createPrivateIdentifier, factoryDeprecation); + + /** @deprecated Use `factory.createSuper` or the factory supplied by your transformation context instead. */ + export const createSuper = Debug.deprecate(factory.createSuper, factoryDeprecation); + + /** @deprecated Use `factory.createThis` or the factory supplied by your transformation context instead. */ + export const createThis = Debug.deprecate(factory.createThis, factoryDeprecation); + + /** @deprecated Use `factory.createNull` or the factory supplied by your transformation context instead. */ + export const createNull = Debug.deprecate(factory.createNull, factoryDeprecation); + + /** @deprecated Use `factory.createTrue` or the factory supplied by your transformation context instead. */ + export const createTrue = Debug.deprecate(factory.createTrue, factoryDeprecation); + + /** @deprecated Use `factory.createFalse` or the factory supplied by your transformation context instead. */ + export const createFalse = Debug.deprecate(factory.createFalse, factoryDeprecation); + + /** @deprecated Use `factory.createModifier` or the factory supplied by your transformation context instead. */ + export const createModifier = Debug.deprecate(factory.createModifier, factoryDeprecation); + + /** @deprecated Use `factory.createModifiersFromModifierFlags` or the factory supplied by your transformation context instead. */ + export const createModifiersFromModifierFlags = Debug.deprecate(factory.createModifiersFromModifierFlags, factoryDeprecation); + + /** @deprecated Use `factory.createQualifiedName` or the factory supplied by your transformation context instead. */ + export const createQualifiedName = Debug.deprecate(factory.createQualifiedName, factoryDeprecation); + + /** @deprecated Use `factory.updateQualifiedName` or the factory supplied by your transformation context instead. */ + export const updateQualifiedName = Debug.deprecate(factory.updateQualifiedName, factoryDeprecation); + + /** @deprecated Use `factory.createComputedPropertyName` or the factory supplied by your transformation context instead. */ + export const createComputedPropertyName = Debug.deprecate(factory.createComputedPropertyName, factoryDeprecation); + + /** @deprecated Use `factory.updateComputedPropertyName` or the factory supplied by your transformation context instead. */ + export const updateComputedPropertyName = Debug.deprecate(factory.updateComputedPropertyName, factoryDeprecation); + + /** @deprecated Use `factory.createTypeParameterDeclaration` or the factory supplied by your transformation context instead. */ + export const createTypeParameterDeclaration = Debug.deprecate(factory.createTypeParameterDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateTypeParameterDeclaration` or the factory supplied by your transformation context instead. */ + export const updateTypeParameterDeclaration = Debug.deprecate(factory.updateTypeParameterDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createParameterDeclaration` or the factory supplied by your transformation context instead. */ + export const createParameter = Debug.deprecate(factory.createParameterDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateParameterDeclaration` or the factory supplied by your transformation context instead. */ + export const updateParameter = Debug.deprecate(factory.updateParameterDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createDecorator` or the factory supplied by your transformation context instead. */ + export const createDecorator = Debug.deprecate(factory.createDecorator, factoryDeprecation); + + /** @deprecated Use `factory.updateDecorator` or the factory supplied by your transformation context instead. */ + export const updateDecorator = Debug.deprecate(factory.updateDecorator, factoryDeprecation); + + /** @deprecated Use `factory.createPropertyDeclaration` or the factory supplied by your transformation context instead. */ + export const createProperty = Debug.deprecate(factory.createPropertyDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updatePropertyDeclaration` or the factory supplied by your transformation context instead. */ + export const updateProperty = Debug.deprecate(factory.updatePropertyDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createMethodDeclaration` or the factory supplied by your transformation context instead. */ + export const createMethod = Debug.deprecate(factory.createMethodDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateMethodDeclaration` or the factory supplied by your transformation context instead. */ + export const updateMethod = Debug.deprecate(factory.updateMethodDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createConstructorDeclaration` or the factory supplied by your transformation context instead. */ + export const createConstructor = Debug.deprecate(factory.createConstructorDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateConstructorDeclaration` or the factory supplied by your transformation context instead. */ + export const updateConstructor = Debug.deprecate(factory.updateConstructorDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createGetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + export const createGetAccessor = Debug.deprecate(factory.createGetAccessorDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateGetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + export const updateGetAccessor = Debug.deprecate(factory.updateGetAccessorDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createSetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + export const createSetAccessor = Debug.deprecate(factory.createSetAccessorDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateSetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + export const updateSetAccessor = Debug.deprecate(factory.updateSetAccessorDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createCallSignature` or the factory supplied by your transformation context instead. */ + export const createCallSignature = Debug.deprecate(factory.createCallSignature, factoryDeprecation); + + /** @deprecated Use `factory.updateCallSignature` or the factory supplied by your transformation context instead. */ + export const updateCallSignature = Debug.deprecate(factory.updateCallSignature, factoryDeprecation); + + /** @deprecated Use `factory.createConstructSignature` or the factory supplied by your transformation context instead. */ + export const createConstructSignature = Debug.deprecate(factory.createConstructSignature, factoryDeprecation); + + /** @deprecated Use `factory.updateConstructSignature` or the factory supplied by your transformation context instead. */ + export const updateConstructSignature = Debug.deprecate(factory.updateConstructSignature, factoryDeprecation); + + /** @deprecated Use `factory.updateIndexSignature` or the factory supplied by your transformation context instead. */ + export const updateIndexSignature = Debug.deprecate(factory.updateIndexSignature, factoryDeprecation); + + /** @deprecated Use `factory.createKeywordTypeNode` or the factory supplied by your transformation context instead. */ + export const createKeywordTypeNode = Debug.deprecate(factory.createKeywordTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createTypePredicateNode` or the factory supplied by your transformation context instead. */ + export const createTypePredicateNodeWithModifier = Debug.deprecate(factory.createTypePredicateNode, factoryDeprecation); + + /** @deprecated Use `factory.updateTypePredicateNode` or the factory supplied by your transformation context instead. */ + export const updateTypePredicateNodeWithModifier = Debug.deprecate(factory.updateTypePredicateNode, factoryDeprecation); + + /** @deprecated Use `factory.createTypeReferenceNode` or the factory supplied by your transformation context instead. */ + export const createTypeReferenceNode = Debug.deprecate(factory.createTypeReferenceNode, factoryDeprecation); + + /** @deprecated Use `factory.updateTypeReferenceNode` or the factory supplied by your transformation context instead. */ + export const updateTypeReferenceNode = Debug.deprecate(factory.updateTypeReferenceNode, factoryDeprecation); + + /** @deprecated Use `factory.createFunctionTypeNode` or the factory supplied by your transformation context instead. */ + export const createFunctionTypeNode = Debug.deprecate(factory.createFunctionTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateFunctionTypeNode` or the factory supplied by your transformation context instead. */ + export const updateFunctionTypeNode = Debug.deprecate(factory.updateFunctionTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createConstructorTypeNode` or the factory supplied by your transformation context instead. */ + export const createConstructorTypeNode = Debug.deprecate(factory.createConstructorTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateConstructorTypeNode` or the factory supplied by your transformation context instead. */ + export const updateConstructorTypeNode = Debug.deprecate(factory.updateConstructorTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createTypeQueryNode` or the factory supplied by your transformation context instead. */ + export const createTypeQueryNode = Debug.deprecate(factory.createTypeQueryNode, factoryDeprecation); + + /** @deprecated Use `factory.updateTypeQueryNode` or the factory supplied by your transformation context instead. */ + export const updateTypeQueryNode = Debug.deprecate(factory.updateTypeQueryNode, factoryDeprecation); + + /** @deprecated Use `factory.createTypeLiteralNode` or the factory supplied by your transformation context instead. */ + export const createTypeLiteralNode = Debug.deprecate(factory.createTypeLiteralNode, factoryDeprecation); + + /** @deprecated Use `factory.updateTypeLiteralNode` or the factory supplied by your transformation context instead. */ + export const updateTypeLiteralNode = Debug.deprecate(factory.updateTypeLiteralNode, factoryDeprecation); + + /** @deprecated Use `factory.createArrayTypeNode` or the factory supplied by your transformation context instead. */ + export const createArrayTypeNode = Debug.deprecate(factory.createArrayTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateArrayTypeNode` or the factory supplied by your transformation context instead. */ + export const updateArrayTypeNode = Debug.deprecate(factory.updateArrayTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createTupleTypeNode` or the factory supplied by your transformation context instead. */ + export const createTupleTypeNode = Debug.deprecate(factory.createTupleTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateTupleTypeNode` or the factory supplied by your transformation context instead. */ + export const updateTupleTypeNode = Debug.deprecate(factory.updateTupleTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createOptionalTypeNode` or the factory supplied by your transformation context instead. */ + export const createOptionalTypeNode = Debug.deprecate(factory.createOptionalTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateOptionalTypeNode` or the factory supplied by your transformation context instead. */ + export const updateOptionalTypeNode = Debug.deprecate(factory.updateOptionalTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createRestTypeNode` or the factory supplied by your transformation context instead. */ + export const createRestTypeNode = Debug.deprecate(factory.createRestTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateRestTypeNode` or the factory supplied by your transformation context instead. */ + export const updateRestTypeNode = Debug.deprecate(factory.updateRestTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createUnionTypeNode` or the factory supplied by your transformation context instead. */ + export const createUnionTypeNode = Debug.deprecate(factory.createUnionTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateUnionTypeNode` or the factory supplied by your transformation context instead. */ + export const updateUnionTypeNode = Debug.deprecate(factory.updateUnionTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createIntersectionTypeNode` or the factory supplied by your transformation context instead. */ + export const createIntersectionTypeNode = Debug.deprecate(factory.createIntersectionTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateIntersectionTypeNode` or the factory supplied by your transformation context instead. */ + export const updateIntersectionTypeNode = Debug.deprecate(factory.updateIntersectionTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createConditionalTypeNode` or the factory supplied by your transformation context instead. */ + export const createConditionalTypeNode = Debug.deprecate(factory.createConditionalTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateConditionalTypeNode` or the factory supplied by your transformation context instead. */ + export const updateConditionalTypeNode = Debug.deprecate(factory.updateConditionalTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createInferTypeNode` or the factory supplied by your transformation context instead. */ + export const createInferTypeNode = Debug.deprecate(factory.createInferTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateInferTypeNode` or the factory supplied by your transformation context instead. */ + export const updateInferTypeNode = Debug.deprecate(factory.updateInferTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createImportTypeNode` or the factory supplied by your transformation context instead. */ + export const createImportTypeNode = Debug.deprecate(factory.createImportTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateImportTypeNode` or the factory supplied by your transformation context instead. */ + export const updateImportTypeNode = Debug.deprecate(factory.updateImportTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createParenthesizedType` or the factory supplied by your transformation context instead. */ + export const createParenthesizedType = Debug.deprecate(factory.createParenthesizedType, factoryDeprecation); + + /** @deprecated Use `factory.updateParenthesizedType` or the factory supplied by your transformation context instead. */ + export const updateParenthesizedType = Debug.deprecate(factory.updateParenthesizedType, factoryDeprecation); + + /** @deprecated Use `factory.createThisTypeNode` or the factory supplied by your transformation context instead. */ + export const createThisTypeNode = Debug.deprecate(factory.createThisTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateTypeOperatorNode` or the factory supplied by your transformation context instead. */ + export const updateTypeOperatorNode = Debug.deprecate(factory.updateTypeOperatorNode, factoryDeprecation); + + /** @deprecated Use `factory.createIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */ + export const createIndexedAccessTypeNode = Debug.deprecate(factory.createIndexedAccessTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */ + export const updateIndexedAccessTypeNode = Debug.deprecate(factory.updateIndexedAccessTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createMappedTypeNode` or the factory supplied by your transformation context instead. */ + export const createMappedTypeNode = Debug.deprecate(factory.createMappedTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateMappedTypeNode` or the factory supplied by your transformation context instead. */ + export const updateMappedTypeNode = Debug.deprecate(factory.updateMappedTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createLiteralTypeNode` or the factory supplied by your transformation context instead. */ + export const createLiteralTypeNode = Debug.deprecate(factory.createLiteralTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.updateLiteralTypeNode` or the factory supplied by your transformation context instead. */ + export const updateLiteralTypeNode = Debug.deprecate(factory.updateLiteralTypeNode, factoryDeprecation); + + /** @deprecated Use `factory.createObjectBindingPattern` or the factory supplied by your transformation context instead. */ + export const createObjectBindingPattern = Debug.deprecate(factory.createObjectBindingPattern, factoryDeprecation); + + /** @deprecated Use `factory.updateObjectBindingPattern` or the factory supplied by your transformation context instead. */ + export const updateObjectBindingPattern = Debug.deprecate(factory.updateObjectBindingPattern, factoryDeprecation); + + /** @deprecated Use `factory.createArrayBindingPattern` or the factory supplied by your transformation context instead. */ + export const createArrayBindingPattern = Debug.deprecate(factory.createArrayBindingPattern, factoryDeprecation); + + /** @deprecated Use `factory.updateArrayBindingPattern` or the factory supplied by your transformation context instead. */ + export const updateArrayBindingPattern = Debug.deprecate(factory.updateArrayBindingPattern, factoryDeprecation); + + /** @deprecated Use `factory.createBindingElement` or the factory supplied by your transformation context instead. */ + export const createBindingElement = Debug.deprecate(factory.createBindingElement, factoryDeprecation); + + /** @deprecated Use `factory.updateBindingElement` or the factory supplied by your transformation context instead. */ + export const updateBindingElement = Debug.deprecate(factory.updateBindingElement, factoryDeprecation); + + /** @deprecated Use `factory.createArrayLiteral` or the factory supplied by your transformation context instead. */ + export const createArrayLiteral = Debug.deprecate(factory.createArrayLiteralExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateArrayLiteral` or the factory supplied by your transformation context instead. */ + export const updateArrayLiteral = Debug.deprecate(factory.updateArrayLiteralExpression, factoryDeprecation); + + /** @deprecated Use `factory.createObjectLiteral` or the factory supplied by your transformation context instead. */ + export const createObjectLiteral = Debug.deprecate(factory.createObjectLiteralExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateObjectLiteral` or the factory supplied by your transformation context instead. */ + export const updateObjectLiteral = Debug.deprecate(factory.updateObjectLiteralExpression, factoryDeprecation); + + /** @deprecated Use `factory.createPropertyAccess` or the factory supplied by your transformation context instead. */ + export const createPropertyAccess = Debug.deprecate(factory.createPropertyAccessExpression, factoryDeprecation); + + /** @deprecated Use `factory.updatePropertyAccess` or the factory supplied by your transformation context instead. */ + export const updatePropertyAccess = Debug.deprecate(factory.updatePropertyAccessExpression, factoryDeprecation); + + /** @deprecated Use `factory.createPropertyAccessChain` or the factory supplied by your transformation context instead. */ + export const createPropertyAccessChain = Debug.deprecate(factory.createPropertyAccessChain, factoryDeprecation); + + /** @deprecated Use `factory.updatePropertyAccessChain` or the factory supplied by your transformation context instead. */ + export const updatePropertyAccessChain = Debug.deprecate(factory.updatePropertyAccessChain, factoryDeprecation); + + /** @deprecated Use `factory.createElementAccess` or the factory supplied by your transformation context instead. */ + export const createElementAccess = Debug.deprecate(factory.createElementAccessExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateElementAccess` or the factory supplied by your transformation context instead. */ + export const updateElementAccess = Debug.deprecate(factory.updateElementAccessExpression, factoryDeprecation); + + /** @deprecated Use `factory.createElementAccessChain` or the factory supplied by your transformation context instead. */ + export const createElementAccessChain = Debug.deprecate(factory.createElementAccessChain, factoryDeprecation); + + /** @deprecated Use `factory.updateElementAccessChain` or the factory supplied by your transformation context instead. */ + export const updateElementAccessChain = Debug.deprecate(factory.updateElementAccessChain, factoryDeprecation); + + /** @deprecated Use `factory.createCall` or the factory supplied by your transformation context instead. */ + export const createCall = Debug.deprecate(factory.createCallExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateCall` or the factory supplied by your transformation context instead. */ + export const updateCall = Debug.deprecate(factory.updateCallExpression, factoryDeprecation); + + /** @deprecated Use `factory.createCallChain` or the factory supplied by your transformation context instead. */ + export const createCallChain = Debug.deprecate(factory.createCallChain, factoryDeprecation); + + /** @deprecated Use `factory.updateCallChain` or the factory supplied by your transformation context instead. */ + export const updateCallChain = Debug.deprecate(factory.updateCallChain, factoryDeprecation); + + /** @deprecated Use `factory.createNew` or the factory supplied by your transformation context instead. */ + export const createNew = Debug.deprecate(factory.createNewExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateNew` or the factory supplied by your transformation context instead. */ + export const updateNew = Debug.deprecate(factory.updateNewExpression, factoryDeprecation); + + /** @deprecated Use `factory.createTypeAssertion` or the factory supplied by your transformation context instead. */ + export const createTypeAssertion = Debug.deprecate(factory.createTypeAssertion, factoryDeprecation); + + /** @deprecated Use `factory.updateTypeAssertion` or the factory supplied by your transformation context instead. */ + export const updateTypeAssertion = Debug.deprecate(factory.updateTypeAssertion, factoryDeprecation); + + /** @deprecated Use `factory.createParen` or the factory supplied by your transformation context instead. */ + export const createParen = Debug.deprecate(factory.createParenthesizedExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateParen` or the factory supplied by your transformation context instead. */ + export const updateParen = Debug.deprecate(factory.updateParenthesizedExpression, factoryDeprecation); + + /** @deprecated Use `factory.createFunctionExpression` or the factory supplied by your transformation context instead. */ + export const createFunctionExpression = Debug.deprecate(factory.createFunctionExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateFunctionExpression` or the factory supplied by your transformation context instead. */ + export const updateFunctionExpression = Debug.deprecate(factory.updateFunctionExpression, factoryDeprecation); + + /** @deprecated Use `factory.createDelete` or the factory supplied by your transformation context instead. */ + export const createDelete = Debug.deprecate(factory.createDeleteExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateDelete` or the factory supplied by your transformation context instead. */ + export const updateDelete = Debug.deprecate(factory.updateDeleteExpression, factoryDeprecation); + + /** @deprecated Use `factory.createTypeOf` or the factory supplied by your transformation context instead. */ + export const createTypeOf = Debug.deprecate(factory.createTypeOfExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateTypeOf` or the factory supplied by your transformation context instead. */ + export const updateTypeOf = Debug.deprecate(factory.updateTypeOfExpression, factoryDeprecation); + + /** @deprecated Use `factory.createVoid` or the factory supplied by your transformation context instead. */ + export const createVoid = Debug.deprecate(factory.createVoidExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateVoid` or the factory supplied by your transformation context instead. */ + export const updateVoid = Debug.deprecate(factory.updateVoidExpression, factoryDeprecation); + + /** @deprecated Use `factory.createAwait` or the factory supplied by your transformation context instead. */ + export const createAwait = Debug.deprecate(factory.createAwaitExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateAwait` or the factory supplied by your transformation context instead. */ + export const updateAwait = Debug.deprecate(factory.updateAwaitExpression, factoryDeprecation); + + /** @deprecated Use `factory.createPrefix` or the factory supplied by your transformation context instead. */ + export const createPrefix = Debug.deprecate(factory.createPrefixUnaryExpression, factoryDeprecation); + + /** @deprecated Use `factory.updatePrefix` or the factory supplied by your transformation context instead. */ + export const updatePrefix = Debug.deprecate(factory.updatePrefixUnaryExpression, factoryDeprecation); + + /** @deprecated Use `factory.createPostfix` or the factory supplied by your transformation context instead. */ + export const createPostfix = Debug.deprecate(factory.createPostfixUnaryExpression, factoryDeprecation); + + /** @deprecated Use `factory.updatePostfix` or the factory supplied by your transformation context instead. */ + export const updatePostfix = Debug.deprecate(factory.updatePostfixUnaryExpression, factoryDeprecation); + + /** @deprecated Use `factory.createBinary` or the factory supplied by your transformation context instead. */ + export const createBinary = Debug.deprecate(factory.createBinaryExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateConditional` or the factory supplied by your transformation context instead. */ + export const updateConditional = Debug.deprecate(factory.updateConditionalExpression, factoryDeprecation); + + /** @deprecated Use `factory.createTemplateExpression` or the factory supplied by your transformation context instead. */ + export const createTemplateExpression = Debug.deprecate(factory.createTemplateExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateTemplateExpression` or the factory supplied by your transformation context instead. */ + export const updateTemplateExpression = Debug.deprecate(factory.updateTemplateExpression, factoryDeprecation); + + /** @deprecated Use `factory.createTemplateHead` or the factory supplied by your transformation context instead. */ + export const createTemplateHead = Debug.deprecate(factory.createTemplateHead, factoryDeprecation); + + /** @deprecated Use `factory.createTemplateMiddle` or the factory supplied by your transformation context instead. */ + export const createTemplateMiddle = Debug.deprecate(factory.createTemplateMiddle, factoryDeprecation); + + /** @deprecated Use `factory.createTemplateTail` or the factory supplied by your transformation context instead. */ + export const createTemplateTail = Debug.deprecate(factory.createTemplateTail, factoryDeprecation); + + /** @deprecated Use `factory.createNoSubstitutionTemplateLiteral` or the factory supplied by your transformation context instead. */ + export const createNoSubstitutionTemplateLiteral = Debug.deprecate(factory.createNoSubstitutionTemplateLiteral, factoryDeprecation); + + /** @deprecated Use `factory.updateYield` or the factory supplied by your transformation context instead. */ + export const updateYield = Debug.deprecate(factory.updateYieldExpression, factoryDeprecation); + + /** @deprecated Use `factory.createSpread` or the factory supplied by your transformation context instead. */ + export const createSpread = Debug.deprecate(factory.createSpreadElement, factoryDeprecation); + + /** @deprecated Use `factory.updateSpread` or the factory supplied by your transformation context instead. */ + export const updateSpread = Debug.deprecate(factory.updateSpreadElement, factoryDeprecation); + + /** @deprecated Use `factory.createOmittedExpression` or the factory supplied by your transformation context instead. */ + export const createOmittedExpression = Debug.deprecate(factory.createOmittedExpression, factoryDeprecation); + + /** @deprecated Use `factory.createAsExpression` or the factory supplied by your transformation context instead. */ + export const createAsExpression = Debug.deprecate(factory.createAsExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateAsExpression` or the factory supplied by your transformation context instead. */ + export const updateAsExpression = Debug.deprecate(factory.updateAsExpression, factoryDeprecation); + + /** @deprecated Use `factory.createNonNullExpression` or the factory supplied by your transformation context instead. */ + export const createNonNullExpression = Debug.deprecate(factory.createNonNullExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateNonNullExpression` or the factory supplied by your transformation context instead. */ + export const updateNonNullExpression = Debug.deprecate(factory.updateNonNullExpression, factoryDeprecation); + + /** @deprecated Use `factory.createNonNullChain` or the factory supplied by your transformation context instead. */ + export const createNonNullChain = Debug.deprecate(factory.createNonNullChain, factoryDeprecation); + + /** @deprecated Use `factory.updateNonNullChain` or the factory supplied by your transformation context instead. */ + export const updateNonNullChain = Debug.deprecate(factory.updateNonNullChain, factoryDeprecation); + + /** @deprecated Use `factory.createMetaProperty` or the factory supplied by your transformation context instead. */ + export const createMetaProperty = Debug.deprecate(factory.createMetaProperty, factoryDeprecation); + + /** @deprecated Use `factory.updateMetaProperty` or the factory supplied by your transformation context instead. */ + export const updateMetaProperty = Debug.deprecate(factory.updateMetaProperty, factoryDeprecation); + + /** @deprecated Use `factory.createTemplateSpan` or the factory supplied by your transformation context instead. */ + export const createTemplateSpan = Debug.deprecate(factory.createTemplateSpan, factoryDeprecation); + + /** @deprecated Use `factory.updateTemplateSpan` or the factory supplied by your transformation context instead. */ + export const updateTemplateSpan = Debug.deprecate(factory.updateTemplateSpan, factoryDeprecation); + + /** @deprecated Use `factory.createSemicolonClassElement` or the factory supplied by your transformation context instead. */ + export const createSemicolonClassElement = Debug.deprecate(factory.createSemicolonClassElement, factoryDeprecation); + + /** @deprecated Use `factory.createBlock` or the factory supplied by your transformation context instead. */ + export const createBlock = Debug.deprecate(factory.createBlock, factoryDeprecation); + + /** @deprecated Use `factory.updateBlock` or the factory supplied by your transformation context instead. */ + export const updateBlock = Debug.deprecate(factory.updateBlock, factoryDeprecation); + + /** @deprecated Use `factory.createVariableStatement` or the factory supplied by your transformation context instead. */ + export const createVariableStatement = Debug.deprecate(factory.createVariableStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateVariableStatement` or the factory supplied by your transformation context instead. */ + export const updateVariableStatement = Debug.deprecate(factory.updateVariableStatement, factoryDeprecation); + + /** @deprecated Use `factory.createEmptyStatement` or the factory supplied by your transformation context instead. */ + export const createEmptyStatement = Debug.deprecate(factory.createEmptyStatement, factoryDeprecation); + + /** @deprecated Use `factory.createExpressionStatement` or the factory supplied by your transformation context instead. */ + export const createExpressionStatement = Debug.deprecate(factory.createExpressionStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateExpressionStatement` or the factory supplied by your transformation context instead. */ + export const updateExpressionStatement = Debug.deprecate(factory.updateExpressionStatement, factoryDeprecation); + + /** @deprecated Use `factory.createExpressionStatement` or the factory supplied by your transformation context instead. */ + export const createStatement = Debug.deprecate(factory.createExpressionStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateExpressionStatement` or the factory supplied by your transformation context instead. */ + export const updateStatement = Debug.deprecate(factory.updateExpressionStatement, factoryDeprecation); + + /** @deprecated Use `factory.createIf` or the factory supplied by your transformation context instead. */ + export const createIf = Debug.deprecate(factory.createIfStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateIf` or the factory supplied by your transformation context instead. */ + export const updateIf = Debug.deprecate(factory.updateIfStatement, factoryDeprecation); + + /** @deprecated Use `factory.createDo` or the factory supplied by your transformation context instead. */ + export const createDo = Debug.deprecate(factory.createDoStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateDo` or the factory supplied by your transformation context instead. */ + export const updateDo = Debug.deprecate(factory.updateDoStatement, factoryDeprecation); + + /** @deprecated Use `factory.createWhile` or the factory supplied by your transformation context instead. */ + export const createWhile = Debug.deprecate(factory.createWhileStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateWhile` or the factory supplied by your transformation context instead. */ + export const updateWhile = Debug.deprecate(factory.updateWhileStatement, factoryDeprecation); + + /** @deprecated Use `factory.createFor` or the factory supplied by your transformation context instead. */ + export const createFor = Debug.deprecate(factory.createForStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateFor` or the factory supplied by your transformation context instead. */ + export const updateFor = Debug.deprecate(factory.updateForStatement, factoryDeprecation); + + /** @deprecated Use `factory.createForIn` or the factory supplied by your transformation context instead. */ + export const createForIn = Debug.deprecate(factory.createForInStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateForIn` or the factory supplied by your transformation context instead. */ + export const updateForIn = Debug.deprecate(factory.updateForInStatement, factoryDeprecation); + + /** @deprecated Use `factory.createForOf` or the factory supplied by your transformation context instead. */ + export const createForOf = Debug.deprecate(factory.createForOfStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateForOf` or the factory supplied by your transformation context instead. */ + export const updateForOf = Debug.deprecate(factory.updateForOfStatement, factoryDeprecation); + + /** @deprecated Use `factory.createContinue` or the factory supplied by your transformation context instead. */ + export const createContinue = Debug.deprecate(factory.createContinueStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateContinue` or the factory supplied by your transformation context instead. */ + export const updateContinue = Debug.deprecate(factory.updateContinueStatement, factoryDeprecation); + + /** @deprecated Use `factory.createBreak` or the factory supplied by your transformation context instead. */ + export const createBreak = Debug.deprecate(factory.createBreakStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateBreak` or the factory supplied by your transformation context instead. */ + export const updateBreak = Debug.deprecate(factory.updateBreakStatement, factoryDeprecation); + + /** @deprecated Use `factory.createReturn` or the factory supplied by your transformation context instead. */ + export const createReturn = Debug.deprecate(factory.createReturnStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateReturn` or the factory supplied by your transformation context instead. */ + export const updateReturn = Debug.deprecate(factory.updateReturnStatement, factoryDeprecation); + + /** @deprecated Use `factory.createWith` or the factory supplied by your transformation context instead. */ + export const createWith = Debug.deprecate(factory.createWithStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateWith` or the factory supplied by your transformation context instead. */ + export const updateWith = Debug.deprecate(factory.updateWithStatement, factoryDeprecation); + + /** @deprecated Use `factory.createSwitch` or the factory supplied by your transformation context instead. */ + export const createSwitch = Debug.deprecate(factory.createSwitchStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateSwitch` or the factory supplied by your transformation context instead. */ + export const updateSwitch = Debug.deprecate(factory.updateSwitchStatement, factoryDeprecation); + + /** @deprecated Use `factory.createLabel` or the factory supplied by your transformation context instead. */ + export const createLabel = Debug.deprecate(factory.createLabeledStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateLabel` or the factory supplied by your transformation context instead. */ + export const updateLabel = Debug.deprecate(factory.updateLabeledStatement, factoryDeprecation); + + /** @deprecated Use `factory.createThrow` or the factory supplied by your transformation context instead. */ + export const createThrow = Debug.deprecate(factory.createThrowStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateThrow` or the factory supplied by your transformation context instead. */ + export const updateThrow = Debug.deprecate(factory.updateThrowStatement, factoryDeprecation); + + /** @deprecated Use `factory.createTry` or the factory supplied by your transformation context instead. */ + export const createTry = Debug.deprecate(factory.createTryStatement, factoryDeprecation); + + /** @deprecated Use `factory.updateTry` or the factory supplied by your transformation context instead. */ + export const updateTry = Debug.deprecate(factory.updateTryStatement, factoryDeprecation); + + /** @deprecated Use `factory.createDebuggerStatement` or the factory supplied by your transformation context instead. */ + export const createDebuggerStatement = Debug.deprecate(factory.createDebuggerStatement, factoryDeprecation); + + /** @deprecated Use `factory.createVariableDeclarationList` or the factory supplied by your transformation context instead. */ + export const createVariableDeclarationList = Debug.deprecate(factory.createVariableDeclarationList, factoryDeprecation); + + /** @deprecated Use `factory.updateVariableDeclarationList` or the factory supplied by your transformation context instead. */ + export const updateVariableDeclarationList = Debug.deprecate(factory.updateVariableDeclarationList, factoryDeprecation); + + /** @deprecated Use `factory.createFunctionDeclaration` or the factory supplied by your transformation context instead. */ + export const createFunctionDeclaration = Debug.deprecate(factory.createFunctionDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateFunctionDeclaration` or the factory supplied by your transformation context instead. */ + export const updateFunctionDeclaration = Debug.deprecate(factory.updateFunctionDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createClassDeclaration` or the factory supplied by your transformation context instead. */ + export const createClassDeclaration = Debug.deprecate(factory.createClassDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateClassDeclaration` or the factory supplied by your transformation context instead. */ + export const updateClassDeclaration = Debug.deprecate(factory.updateClassDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createInterfaceDeclaration` or the factory supplied by your transformation context instead. */ + export const createInterfaceDeclaration = Debug.deprecate(factory.createInterfaceDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateInterfaceDeclaration` or the factory supplied by your transformation context instead. */ + export const updateInterfaceDeclaration = Debug.deprecate(factory.updateInterfaceDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createTypeAliasDeclaration` or the factory supplied by your transformation context instead. */ + export const createTypeAliasDeclaration = Debug.deprecate(factory.createTypeAliasDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateTypeAliasDeclaration` or the factory supplied by your transformation context instead. */ + export const updateTypeAliasDeclaration = Debug.deprecate(factory.updateTypeAliasDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createEnumDeclaration` or the factory supplied by your transformation context instead. */ + export const createEnumDeclaration = Debug.deprecate(factory.createEnumDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateEnumDeclaration` or the factory supplied by your transformation context instead. */ + export const updateEnumDeclaration = Debug.deprecate(factory.updateEnumDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createModuleDeclaration` or the factory supplied by your transformation context instead. */ + export const createModuleDeclaration = Debug.deprecate(factory.createModuleDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateModuleDeclaration` or the factory supplied by your transformation context instead. */ + export const updateModuleDeclaration = Debug.deprecate(factory.updateModuleDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createModuleBlock` or the factory supplied by your transformation context instead. */ + export const createModuleBlock = Debug.deprecate(factory.createModuleBlock, factoryDeprecation); + + /** @deprecated Use `factory.updateModuleBlock` or the factory supplied by your transformation context instead. */ + export const updateModuleBlock = Debug.deprecate(factory.updateModuleBlock, factoryDeprecation); + + /** @deprecated Use `factory.createCaseBlock` or the factory supplied by your transformation context instead. */ + export const createCaseBlock = Debug.deprecate(factory.createCaseBlock, factoryDeprecation); + + /** @deprecated Use `factory.updateCaseBlock` or the factory supplied by your transformation context instead. */ + export const updateCaseBlock = Debug.deprecate(factory.updateCaseBlock, factoryDeprecation); + + /** @deprecated Use `factory.createNamespaceExportDeclaration` or the factory supplied by your transformation context instead. */ + export const createNamespaceExportDeclaration = Debug.deprecate(factory.createNamespaceExportDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateNamespaceExportDeclaration` or the factory supplied by your transformation context instead. */ + export const updateNamespaceExportDeclaration = Debug.deprecate(factory.updateNamespaceExportDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createImportEqualsDeclaration` or the factory supplied by your transformation context instead. */ + export const createImportEqualsDeclaration = Debug.deprecate(factory.createImportEqualsDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateImportEqualsDeclaration` or the factory supplied by your transformation context instead. */ + export const updateImportEqualsDeclaration = Debug.deprecate(factory.updateImportEqualsDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createImportDeclaration` or the factory supplied by your transformation context instead. */ + export const createImportDeclaration = Debug.deprecate(factory.createImportDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.updateImportDeclaration` or the factory supplied by your transformation context instead. */ + export const updateImportDeclaration = Debug.deprecate(factory.updateImportDeclaration, factoryDeprecation); + + /** @deprecated Use `factory.createNamespaceImport` or the factory supplied by your transformation context instead. */ + export const createNamespaceImport = Debug.deprecate(factory.createNamespaceImport, factoryDeprecation); + + /** @deprecated Use `factory.updateNamespaceImport` or the factory supplied by your transformation context instead. */ + export const updateNamespaceImport = Debug.deprecate(factory.updateNamespaceImport, factoryDeprecation); + + /** @deprecated Use `factory.createNamedImports` or the factory supplied by your transformation context instead. */ + export const createNamedImports = Debug.deprecate(factory.createNamedImports, factoryDeprecation); + + /** @deprecated Use `factory.updateNamedImports` or the factory supplied by your transformation context instead. */ + export const updateNamedImports = Debug.deprecate(factory.updateNamedImports, factoryDeprecation); + + /** @deprecated Use `factory.createImportSpecifier` or the factory supplied by your transformation context instead. */ + export const createImportSpecifier = Debug.deprecate(factory.createImportSpecifier, factoryDeprecation); + + /** @deprecated Use `factory.updateImportSpecifier` or the factory supplied by your transformation context instead. */ + export const updateImportSpecifier = Debug.deprecate(factory.updateImportSpecifier, factoryDeprecation); + + /** @deprecated Use `factory.createExportAssignment` or the factory supplied by your transformation context instead. */ + export const createExportAssignment = Debug.deprecate(factory.createExportAssignment, factoryDeprecation); + + /** @deprecated Use `factory.updateExportAssignment` or the factory supplied by your transformation context instead. */ + export const updateExportAssignment = Debug.deprecate(factory.updateExportAssignment, factoryDeprecation); + + /** @deprecated Use `factory.createNamedExports` or the factory supplied by your transformation context instead. */ + export const createNamedExports = Debug.deprecate(factory.createNamedExports, factoryDeprecation); + + /** @deprecated Use `factory.updateNamedExports` or the factory supplied by your transformation context instead. */ + export const updateNamedExports = Debug.deprecate(factory.updateNamedExports, factoryDeprecation); + + /** @deprecated Use `factory.createExportSpecifier` or the factory supplied by your transformation context instead. */ + export const createExportSpecifier = Debug.deprecate(factory.createExportSpecifier, factoryDeprecation); + + /** @deprecated Use `factory.updateExportSpecifier` or the factory supplied by your transformation context instead. */ + export const updateExportSpecifier = Debug.deprecate(factory.updateExportSpecifier, factoryDeprecation); + + /** @deprecated Use `factory.createExternalModuleReference` or the factory supplied by your transformation context instead. */ + export const createExternalModuleReference = Debug.deprecate(factory.createExternalModuleReference, factoryDeprecation); + + /** @deprecated Use `factory.updateExternalModuleReference` or the factory supplied by your transformation context instead. */ + export const updateExternalModuleReference = Debug.deprecate(factory.updateExternalModuleReference, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocTypeExpression` or the factory supplied by your transformation context instead. */ + export const createJSDocTypeExpression = Debug.deprecate(factory.createJSDocTypeExpression, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocTypeTag` or the factory supplied by your transformation context instead. */ + export const createJSDocTypeTag = Debug.deprecate(factory.createJSDocTypeTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocReturnTag` or the factory supplied by your transformation context instead. */ + export const createJSDocReturnTag = Debug.deprecate(factory.createJSDocReturnTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocThisTag` or the factory supplied by your transformation context instead. */ + export const createJSDocThisTag = Debug.deprecate(factory.createJSDocThisTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocComment` or the factory supplied by your transformation context instead. */ + export const createJSDocComment = Debug.deprecate(factory.createJSDocComment, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ + export const createJSDocParameterTag = Debug.deprecate(factory.createJSDocParameterTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocClassTag` or the factory supplied by your transformation context instead. */ + export const createJSDocClassTag = Debug.deprecate(factory.createJSDocClassTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocAugmentsTag` or the factory supplied by your transformation context instead. */ + export const createJSDocAugmentsTag = Debug.deprecate(factory.createJSDocAugmentsTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocEnumTag` or the factory supplied by your transformation context instead. */ + export const createJSDocEnumTag = Debug.deprecate(factory.createJSDocEnumTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocTemplateTag` or the factory supplied by your transformation context instead. */ + export const createJSDocTemplateTag = Debug.deprecate(factory.createJSDocTemplateTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocTypedefTag` or the factory supplied by your transformation context instead. */ + export const createJSDocTypedefTag = Debug.deprecate(factory.createJSDocTypedefTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocCallbackTag` or the factory supplied by your transformation context instead. */ + export const createJSDocCallbackTag = Debug.deprecate(factory.createJSDocCallbackTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocSignature` or the factory supplied by your transformation context instead. */ + export const createJSDocSignature = Debug.deprecate(factory.createJSDocSignature, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocPropertyTag` or the factory supplied by your transformation context instead. */ + export const createJSDocPropertyTag = Debug.deprecate(factory.createJSDocPropertyTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocTypeLiteral` or the factory supplied by your transformation context instead. */ + export const createJSDocTypeLiteral = Debug.deprecate(factory.createJSDocTypeLiteral, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocImplementsTag` or the factory supplied by your transformation context instead. */ + export const createJSDocImplementsTag = Debug.deprecate(factory.createJSDocImplementsTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocAuthorTag` or the factory supplied by your transformation context instead. */ + export const createJSDocAuthorTag = Debug.deprecate(factory.createJSDocAuthorTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocPublicTag` or the factory supplied by your transformation context instead. */ + export const createJSDocPublicTag = Debug.deprecate(factory.createJSDocPublicTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocPrivateTag` or the factory supplied by your transformation context instead. */ + export const createJSDocPrivateTag = Debug.deprecate(factory.createJSDocPrivateTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocProtectedTag` or the factory supplied by your transformation context instead. */ + export const createJSDocProtectedTag = Debug.deprecate(factory.createJSDocProtectedTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocReadonlyTag` or the factory supplied by your transformation context instead. */ + export const createJSDocReadonlyTag = Debug.deprecate(factory.createJSDocReadonlyTag, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocUnknownTag` or the factory supplied by your transformation context instead. */ + export const createJSDocTag = Debug.deprecate(factory.createJSDocUnknownTag, factoryDeprecation); + + /** @deprecated Use `factory.createJsxElement` or the factory supplied by your transformation context instead. */ + export const createJsxElement = Debug.deprecate(factory.createJsxElement, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxElement` or the factory supplied by your transformation context instead. */ + export const updateJsxElement = Debug.deprecate(factory.updateJsxElement, factoryDeprecation); + + /** @deprecated Use `factory.createJsxSelfClosingElement` or the factory supplied by your transformation context instead. */ + export const createJsxSelfClosingElement = Debug.deprecate(factory.createJsxSelfClosingElement, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxSelfClosingElement` or the factory supplied by your transformation context instead. */ + export const updateJsxSelfClosingElement = Debug.deprecate(factory.updateJsxSelfClosingElement, factoryDeprecation); + + /** @deprecated Use `factory.createJsxOpeningElement` or the factory supplied by your transformation context instead. */ + export const createJsxOpeningElement = Debug.deprecate(factory.createJsxOpeningElement, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxOpeningElement` or the factory supplied by your transformation context instead. */ + export const updateJsxOpeningElement = Debug.deprecate(factory.updateJsxOpeningElement, factoryDeprecation); + + /** @deprecated Use `factory.createJsxClosingElement` or the factory supplied by your transformation context instead. */ + export const createJsxClosingElement = Debug.deprecate(factory.createJsxClosingElement, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxClosingElement` or the factory supplied by your transformation context instead. */ + export const updateJsxClosingElement = Debug.deprecate(factory.updateJsxClosingElement, factoryDeprecation); + + /** @deprecated Use `factory.createJsxFragment` or the factory supplied by your transformation context instead. */ + export const createJsxFragment = Debug.deprecate(factory.createJsxFragment, factoryDeprecation); + + /** @deprecated Use `factory.createJsxText` or the factory supplied by your transformation context instead. */ + export const createJsxText = Debug.deprecate(factory.createJsxText, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxText` or the factory supplied by your transformation context instead. */ + export const updateJsxText = Debug.deprecate(factory.updateJsxText, factoryDeprecation); + + /** @deprecated Use `factory.createJsxOpeningFragment` or the factory supplied by your transformation context instead. */ + export const createJsxOpeningFragment = Debug.deprecate(factory.createJsxOpeningFragment, factoryDeprecation); + + /** @deprecated Use `factory.createJsxJsxClosingFragment` or the factory supplied by your transformation context instead. */ + export const createJsxJsxClosingFragment = Debug.deprecate(factory.createJsxJsxClosingFragment, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxFragment` or the factory supplied by your transformation context instead. */ + export const updateJsxFragment = Debug.deprecate(factory.updateJsxFragment, factoryDeprecation); + + /** @deprecated Use `factory.createJsxAttribute` or the factory supplied by your transformation context instead. */ + export const createJsxAttribute = Debug.deprecate(factory.createJsxAttribute, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxAttribute` or the factory supplied by your transformation context instead. */ + export const updateJsxAttribute = Debug.deprecate(factory.updateJsxAttribute, factoryDeprecation); + + /** @deprecated Use `factory.createJsxAttributes` or the factory supplied by your transformation context instead. */ + export const createJsxAttributes = Debug.deprecate(factory.createJsxAttributes, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxAttributes` or the factory supplied by your transformation context instead. */ + export const updateJsxAttributes = Debug.deprecate(factory.updateJsxAttributes, factoryDeprecation); + + /** @deprecated Use `factory.createJsxSpreadAttribute` or the factory supplied by your transformation context instead. */ + export const createJsxSpreadAttribute = Debug.deprecate(factory.createJsxSpreadAttribute, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxSpreadAttribute` or the factory supplied by your transformation context instead. */ + export const updateJsxSpreadAttribute = Debug.deprecate(factory.updateJsxSpreadAttribute, factoryDeprecation); + + /** @deprecated Use `factory.createJsxExpression` or the factory supplied by your transformation context instead. */ + export const createJsxExpression = Debug.deprecate(factory.createJsxExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateJsxExpression` or the factory supplied by your transformation context instead. */ + export const updateJsxExpression = Debug.deprecate(factory.updateJsxExpression, factoryDeprecation); + + /** @deprecated Use `factory.createCaseClause` or the factory supplied by your transformation context instead. */ + export const createCaseClause = Debug.deprecate(factory.createCaseClause, factoryDeprecation); + + /** @deprecated Use `factory.updateCaseClause` or the factory supplied by your transformation context instead. */ + export const updateCaseClause = Debug.deprecate(factory.updateCaseClause, factoryDeprecation); + + /** @deprecated Use `factory.createDefaultClause` or the factory supplied by your transformation context instead. */ + export const createDefaultClause = Debug.deprecate(factory.createDefaultClause, factoryDeprecation); + + /** @deprecated Use `factory.updateDefaultClause` or the factory supplied by your transformation context instead. */ + export const updateDefaultClause = Debug.deprecate(factory.updateDefaultClause, factoryDeprecation); + + /** @deprecated Use `factory.createHeritageClause` or the factory supplied by your transformation context instead. */ + export const createHeritageClause = Debug.deprecate(factory.createHeritageClause, factoryDeprecation); + + /** @deprecated Use `factory.updateHeritageClause` or the factory supplied by your transformation context instead. */ + export const updateHeritageClause = Debug.deprecate(factory.updateHeritageClause, factoryDeprecation); + + /** @deprecated Use `factory.createCatchClause` or the factory supplied by your transformation context instead. */ + export const createCatchClause = Debug.deprecate(factory.createCatchClause, factoryDeprecation); + + /** @deprecated Use `factory.updateCatchClause` or the factory supplied by your transformation context instead. */ + export const updateCatchClause = Debug.deprecate(factory.updateCatchClause, factoryDeprecation); + + /** @deprecated Use `factory.createPropertyAssignment` or the factory supplied by your transformation context instead. */ + export const createPropertyAssignment = Debug.deprecate(factory.createPropertyAssignment, factoryDeprecation); + + /** @deprecated Use `factory.updatePropertyAssignment` or the factory supplied by your transformation context instead. */ + export const updatePropertyAssignment = Debug.deprecate(factory.updatePropertyAssignment, factoryDeprecation); + + /** @deprecated Use `factory.createShorthandPropertyAssignment` or the factory supplied by your transformation context instead. */ + export const createShorthandPropertyAssignment = Debug.deprecate(factory.createShorthandPropertyAssignment, factoryDeprecation); + + /** @deprecated Use `factory.updateShorthandPropertyAssignment` or the factory supplied by your transformation context instead. */ + export const updateShorthandPropertyAssignment = Debug.deprecate(factory.updateShorthandPropertyAssignment, factoryDeprecation); + + /** @deprecated Use `factory.createSpreadAssignment` or the factory supplied by your transformation context instead. */ + export const createSpreadAssignment = Debug.deprecate(factory.createSpreadAssignment, factoryDeprecation); + + /** @deprecated Use `factory.updateSpreadAssignment` or the factory supplied by your transformation context instead. */ + export const updateSpreadAssignment = Debug.deprecate(factory.updateSpreadAssignment, factoryDeprecation); + + /** @deprecated Use `factory.createEnumMember` or the factory supplied by your transformation context instead. */ + export const createEnumMember = Debug.deprecate(factory.createEnumMember, factoryDeprecation); + + /** @deprecated Use `factory.updateEnumMember` or the factory supplied by your transformation context instead. */ + export const updateEnumMember = Debug.deprecate(factory.updateEnumMember, factoryDeprecation); + + /** @deprecated Use `factory.updateSourceFile` or the factory supplied by your transformation context instead. */ + export const updateSourceFileNode = Debug.deprecate(factory.updateSourceFile, factoryDeprecation); + + /** @deprecated Use `factory.createNotEmittedStatement` or the factory supplied by your transformation context instead. */ + export const createNotEmittedStatement = Debug.deprecate(factory.createNotEmittedStatement, factoryDeprecation); + + /** @deprecated Use `factory.createPartiallyEmittedExpression` or the factory supplied by your transformation context instead. */ + export const createPartiallyEmittedExpression = Debug.deprecate(factory.createPartiallyEmittedExpression, factoryDeprecation); + + /** @deprecated Use `factory.updatePartiallyEmittedExpression` or the factory supplied by your transformation context instead. */ + export const updatePartiallyEmittedExpression = Debug.deprecate(factory.updatePartiallyEmittedExpression, factoryDeprecation); + + /** @deprecated Use `factory.createCommaList` or the factory supplied by your transformation context instead. */ + export const createCommaList = Debug.deprecate(factory.createCommaListExpression, factoryDeprecation); + + /** @deprecated Use `factory.updateCommaList` or the factory supplied by your transformation context instead. */ + export const updateCommaList = Debug.deprecate(factory.updateCommaListExpression, factoryDeprecation); + + /** @deprecated Use `factory.createBundle` or the factory supplied by your transformation context instead. */ + export const createBundle = Debug.deprecate(factory.createBundle, factoryDeprecation); + + /** @deprecated Use `factory.updateBundle` or the factory supplied by your transformation context instead. */ + export const updateBundle = Debug.deprecate(factory.updateBundle, factoryDeprecation); + + /** @deprecated Use `factory.createImmediatelyInvokedFunctionExpression` or the factory supplied by your transformation context instead. */ + export const createImmediatelyInvokedFunctionExpression = Debug.deprecate(factory.createImmediatelyInvokedFunctionExpression, factoryDeprecation); + + /** @deprecated Use `factory.createImmediatelyInvokedArrowFunction` or the factory supplied by your transformation context instead. */ + export const createImmediatelyInvokedArrowFunction = Debug.deprecate(factory.createImmediatelyInvokedArrowFunction, factoryDeprecation); + + /** @deprecated Use `factory.createVoidZero` or the factory supplied by your transformation context instead. */ + export const createVoidZero = Debug.deprecate(factory.createVoidZero, factoryDeprecation); + + /** @deprecated Use `factory.createExportDefault` or the factory supplied by your transformation context instead. */ + export const createExportDefault = Debug.deprecate(factory.createExportDefault, factoryDeprecation); + + /** @deprecated Use `factory.createExternalModuleExport` or the factory supplied by your transformation context instead. */ + export const createExternalModuleExport = Debug.deprecate(factory.createExternalModuleExport, factoryDeprecation); + + /** @deprecated Use `factory.createNamespaceExport` or the factory supplied by your transformation context instead. */ + export const createNamespaceExport = Debug.deprecate(factory.createNamespaceExport, factoryDeprecation); + + /** @deprecated Use `factory.updateNamespaceExport` or the factory supplied by your transformation context instead. */ + export const updateNamespaceExport = Debug.deprecate(factory.updateNamespaceExport, factoryDeprecation); + + /** @deprecated Use `factory.createToken` or the factory supplied by your transformation context instead. */ + export const createToken = Debug.deprecate(function createToken(kind: TKind): Token { + return factory.createToken(kind); + }, factoryDeprecation); + + /** @deprecated Use `factory.createIdentifier` or the factory supplied by your transformation context instead. */ + export const createIdentifier = Debug.deprecate(function createIdentifier(text: string) { + return factory.createIdentifier(text, /*typeArguments*/ undefined, /*originalKeywordKind*/ undefined); + }, factoryDeprecation); + + /** @deprecated Use `factory.createTempVariable` or the factory supplied by your transformation context instead. */ + export const createTempVariable = Debug.deprecate(function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier { + return factory.createTempVariable(recordTempVariable, /*reserveInNestedScopes*/ undefined); + }, factoryDeprecation); + + /** @deprecated Use `factory.getGeneratedNameForNode` or the factory supplied by your transformation context instead. */ + export const getGeneratedNameForNode = Debug.deprecate(function getGeneratedNameForNode(node: Node | undefined): Identifier { + return factory.getGeneratedNameForNode(node, /*flags*/ undefined); + }, factoryDeprecation); + + /** @deprecated Use `factory.createUniqueName(text, GeneratedIdentifierFlags.Optimistic)` or the factory supplied by your transformation context instead. */ + export const createOptimisticUniqueName = Debug.deprecate(function createOptimisticUniqueName(text: string): Identifier { + return factory.createUniqueName(text, GeneratedIdentifierFlags.Optimistic); + }, factoryDeprecation); + + /** @deprecated Use `factory.createUniqueName(text, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)` or the factory supplied by your transformation context instead. */ + export const createFileLevelUniqueName = Debug.deprecate(function createFileLevelUniqueName(text: string): Identifier { + return factory.createUniqueName(text, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel); + }, factoryDeprecation); + + /** @deprecated Use `factory.createIndexSignature` or the factory supplied by your transformation context instead. */ + export const createIndexSignature = Debug.deprecate(function createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration { + return factory.createIndexSignature(decorators, modifiers, parameters, type); + }, factoryDeprecation); + + /** @deprecated Use `factory.createTypePredicateNode` or the factory supplied by your transformation context instead. */ + export const createTypePredicateNode = Debug.deprecate(function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode { + return factory.createTypePredicateNode(/*assertsModifier*/ undefined, parameterName, type); + }, factoryDeprecation); + + /** @deprecated Use `factory.updateTypePredicateNode` or the factory supplied by your transformation context instead. */ + export const updateTypePredicateNode = Debug.deprecate(function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode { + return factory.updateTypePredicateNode(node, /*assertsModifier*/ undefined, parameterName, type); + }, factoryDeprecation); + + /** @deprecated Use `factory.createStringLiteral`, `factory.createStringLiteralFromNode`, `factory.createNumericLiteral`, `factory.createBigIntLiteral`, `factory.createTrue`, `factory.createFalse`, or the factory supplied by your transformation context instead. */ + export const createLiteral = Debug.deprecate(function createLiteral(value: string | number | PseudoBigInt | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): PrimaryExpression { + if (typeof value === "number") { + return factory.createNumericLiteral(value); + } + // eslint-disable-next-line no-in-operator + if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt + return factory.createBigIntLiteral(value); + } + if (typeof value === "boolean") { + return value ? factory.createTrue() : factory.createFalse(); + } + if (typeof value === "string") { + return factory.createStringLiteral(value, /*isSingleQuote*/ undefined); + } + return factory.createStringLiteralFromNode(value); + } as { + (value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; + (value: number | PseudoBigInt): NumericLiteral; + (value: boolean): BooleanLiteral; + (value: string | number | PseudoBigInt | boolean): PrimaryExpression; + }, { since: "4.0", warnAfter: "4.1", message: "Use `factory.createStringLiteral`, `factory.createStringLiteralFromNode`, `factory.createNumericLiteral`, `factory.createBigIntLiteral`, `factory.createTrue`, `factory.createFalse`, or the factory supplied by your transformation context instead." }); + + /** @deprecated Use `factory.createMethodSignature` or the factory supplied by your transformation context instead. */ + export const createMethodSignature = Debug.deprecate(function createMethodSignature( + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + name: string | PropertyName, + questionToken: QuestionToken | undefined + ) { + return factory.createMethodSignature(/*modifiers*/ undefined, name, questionToken, typeParameters, parameters, type); + }, factoryDeprecation); + + /** @deprecated Use `factory.updateMethodSignature` or the factory supplied by your transformation context instead. */ + export const updateMethodSignature = Debug.deprecate(function updateMethodSignature( + node: MethodSignature, + typeParameters: NodeArray | undefined, + parameters: NodeArray, + type: TypeNode | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined + ) { + return factory.updateMethodSignature(node, node.modifiers, name, questionToken, typeParameters, parameters, type); + }, factoryDeprecation); + + /** @deprecated Use `factory.createTypeOperatorNode` or the factory supplied by your transformation context instead. */ + export const createTypeOperatorNode = Debug.deprecate(function createTypeOperatorNode(operatorOrType: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | TypeNode, type?: TypeNode) { + let operator: TypeOperatorNode["operator"]; + if (type) { + operator = operatorOrType as TypeOperatorNode["operator"]; + } + else { + type = operatorOrType as TypeNode; + operator = SyntaxKind.KeyOfKeyword; + } + return factory.createTypeOperatorNode(operator, type); + } as { + (type: TypeNode): TypeOperatorNode; + (operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; + }, factoryDeprecation); + + /** @deprecated Use `factory.createTaggedTemplate` or the factory supplied by your transformation context instead. */ + export const createTaggedTemplate = Debug.deprecate(function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: readonly TypeNode[] | TemplateLiteral | undefined, template?: TemplateLiteral) { + let typeArguments: readonly TypeNode[] | undefined; + if (template) { + typeArguments = typeArgumentsOrTemplate as readonly TypeNode[] | undefined; + } + else { + template = typeArgumentsOrTemplate as TemplateLiteral; + } + return factory.createTaggedTemplateExpression(tag, typeArguments, template); + } as { + (tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + (tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + }, factoryDeprecation); + + /** @deprecated Use `factory.updateTaggedTemplate` or the factory supplied by your transformation context instead. */ + export const updateTaggedTemplate = Debug.deprecate(function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArgumentsOrTemplate: readonly TypeNode[] | TemplateLiteral | undefined, template?: TemplateLiteral) { + let typeArguments: readonly TypeNode[] | undefined; + if (template) { + typeArguments = typeArgumentsOrTemplate as readonly TypeNode[] | undefined; + } + else { + template = typeArgumentsOrTemplate as TemplateLiteral; + } + return factory.updateTaggedTemplateExpression(node, tag, typeArguments, template); + } as { + (node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + (node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + }, factoryDeprecation); + + /** @deprecated Use `factory.updateBinary` or the factory supplied by your transformation context instead. */ + export const updateBinary = Debug.deprecate(function updateBinary(node: BinaryExpression, left: Expression, right: Expression, operator: BinaryOperator | BinaryOperatorToken = node.operatorToken) { + if (typeof operator === "number") { + operator = operator === node.operatorToken.kind ? node.operatorToken : factory.createToken(operator); + } + return factory.updateBinaryExpression(node, left, operator, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createConditional` or the factory supplied by your transformation context instead. */ + export const createConditional = Debug.deprecate(function createConditional(condition: Expression, questionTokenOrWhenTrue: QuestionToken | Expression, whenTrueOrWhenFalse: Expression, colonToken?: ColonToken, whenFalse?: Expression) { + return arguments.length === 5 ? factory.createConditionalExpression(condition, questionTokenOrWhenTrue as QuestionToken, whenTrueOrWhenFalse, colonToken, whenFalse!) : + arguments.length === 3 ? factory.createConditionalExpression(condition, factory.createToken(SyntaxKind.QuestionToken), questionTokenOrWhenTrue as Expression, factory.createToken(SyntaxKind.ColonToken), whenTrueOrWhenFalse) : + Debug.fail("Argument count mismatch"); + } as { + (condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; + (condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; + }, factoryDeprecation); + + /** @deprecated Use `factory.createYield` or the factory supplied by your transformation context instead. */ + export const createYield = Debug.deprecate(function createYield(asteriskTokenOrExpression?: AsteriskToken | Expression | undefined, expression?: Expression) { + let asteriskToken: AsteriskToken | undefined; + if (expression) { + asteriskToken = asteriskTokenOrExpression as AsteriskToken; + } + else { + expression = asteriskTokenOrExpression as Expression; + } + return factory.createYieldExpression(asteriskToken, expression); + } as { + (expression?: Expression): YieldExpression; + (asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; + }, factoryDeprecation); + + /** @deprecated Use `factory.createClassExpression` or the factory supplied by your transformation context instead. */ + export const createClassExpression = Debug.deprecate(function createClassExpression( + modifiers: readonly Modifier[] | undefined, + name: string | Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly ClassElement[] + ) { + return factory.createClassExpression(/*decorators*/ undefined, modifiers, name, typeParameters, heritageClauses, members); + }, factoryDeprecation); + + /** @deprecated Use `factory.updateClassExpression` or the factory supplied by your transformation context instead. */ + export const updateClassExpression = Debug.deprecate(function updateClassExpression( + node: ClassExpression, + modifiers: readonly Modifier[] | undefined, + name: Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly ClassElement[] + ) { + return factory.updateClassExpression(node, /*decorators*/ undefined, modifiers, name, typeParameters, heritageClauses, members); + }, factoryDeprecation); + + /** @deprecated Use `factory.createPropertySignature` or the factory supplied by your transformation context instead. */ + export const createPropertySignature = Debug.deprecate(function createPropertySignature( + modifiers: readonly Modifier[] | undefined, + name: PropertyName | string, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer?: Expression + ): PropertySignature { + const node = factory.createPropertySignature(modifiers, name, questionToken, type); + node.initializer = initializer; + return node; + }, factoryDeprecation); + + /** @deprecated Use `factory.updatePropertySignature` or the factory supplied by your transformation context instead. */ + export const updatePropertySignature = Debug.deprecate(function updatePropertySignature( + node: PropertySignature, + modifiers: readonly Modifier[] | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined + ) { + let updated = factory.updatePropertySignature(node, modifiers, name, questionToken, type); + if (node.initializer !== initializer) { + if (updated === node) { + updated = factory.cloneNode(node); + } + updated.initializer = initializer; + } + return updated; + }, factoryDeprecation); + + /** @deprecated Use `factory.createExpressionWithTypeArguments` or the factory supplied by your transformation context instead. */ + export const createExpressionWithTypeArguments = Debug.deprecate(function createExpressionWithTypeArguments(typeArguments: readonly TypeNode[] | undefined, expression: Expression) { + return factory.createExpressionWithTypeArguments(expression, typeArguments); + }, factoryDeprecation); + + /** @deprecated Use `factory.updateExpressionWithTypeArguments` or the factory supplied by your transformation context instead. */ + export const updateExpressionWithTypeArguments = Debug.deprecate(function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: readonly TypeNode[] | undefined, expression: Expression) { + return factory.updateExpressionWithTypeArguments(node, expression, typeArguments); + }, factoryDeprecation); + + /** @deprecated Use `factory.createArrowFunction` or the factory supplied by your transformation context instead. */ + export const createArrowFunction = Debug.deprecate(function createArrowFunction(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanTokenOrBody: ConciseBody | EqualsGreaterThanToken | undefined, body?: ConciseBody) { + return arguments.length === 6 ? factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody as EqualsGreaterThanToken | undefined, body!) : + arguments.length === 5 ? factory.createArrowFunction(modifiers, typeParameters, parameters, type, /*equalsGreaterThanToken*/ undefined, equalsGreaterThanTokenOrBody as ConciseBody) : + Debug.fail("Argument count mismatch"); + } as { + (modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; + (modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + }, factoryDeprecation); + + /** @deprecated Use `factory.updateArrowFunction` or the factory supplied by your transformation context instead. */ + export const updateArrowFunction = Debug.deprecate(function updateArrowFunction(node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanTokenOrBody: EqualsGreaterThanToken | ConciseBody, body?: ConciseBody) { + return arguments.length === 7 ? factory.updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody as EqualsGreaterThanToken, body!) : + arguments.length === 6 ? factory.updateArrowFunction(node, modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, equalsGreaterThanTokenOrBody as ConciseBody) : + Debug.fail("Argument count mismatch"); + } as { + (node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody): ArrowFunction; + (node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + }, factoryDeprecation); + + /** @deprecated Use `factory.createVariableDeclaration` or the factory supplied by your transformation context instead. */ + export const createVariableDeclaration = Debug.deprecate(function createVariableDeclaration(name: string | BindingName, exclamationTokenOrType?: ExclamationToken | TypeNode, typeOrInitializer?: TypeNode | Expression, initializer?: Expression) { + return arguments.length === 4 ? factory.createVariableDeclaration(name, exclamationTokenOrType as ExclamationToken | undefined, typeOrInitializer as TypeNode | undefined, initializer) : + arguments.length >= 1 && arguments.length <= 3 ? factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, exclamationTokenOrType as TypeNode | undefined, typeOrInitializer as Expression | undefined) : + Debug.fail("Argument count mismatch"); + } as { + (name: string | BindingName, type?: TypeNode, initializer?: Expression): VariableDeclaration; + (name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + }, factoryDeprecation); + + /** @deprecated Use `factory.updateVariableDeclaration` or the factory supplied by your transformation context instead. */ + export const updateVariableDeclaration = Debug.deprecate(function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, exclamationTokenOrType: ExclamationToken | TypeNode | undefined, typeOrInitializer: TypeNode | Expression | undefined, initializer?: Expression | undefined) { + return arguments.length === 5 ? factory.updateVariableDeclaration(node, name, exclamationTokenOrType as ExclamationToken | undefined, typeOrInitializer as TypeNode | undefined, initializer) : + arguments.length === 4 ? factory.updateVariableDeclaration(node, name, node.exclamationToken, exclamationTokenOrType as TypeNode | undefined, typeOrInitializer as Expression | undefined) : + Debug.fail("Argument count mismatch"); + } as { + (node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + (node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + }, factoryDeprecation); + + /** @deprecated Use `factory.createImportClause` or the factory supplied by your transformation context instead. */ + export const createImportClause = Debug.deprecate(function createImportClause(name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly = false): ImportClause { + return factory.createImportClause(isTypeOnly, name, namedBindings); + }, factoryDeprecation); + + /** @deprecated Use `factory.updateImportClause` or the factory supplied by your transformation context instead. */ + export const updateImportClause = Debug.deprecate(function updateImportClause(node: ImportClause, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly: boolean) { + return factory.updateImportClause(node, isTypeOnly, name, namedBindings); + }, factoryDeprecation); + + /** @deprecated Use `factory.createExportDeclaration` or the factory supplied by your transformation context instead. */ + export const createExportDeclaration = Debug.deprecate(function createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression, isTypeOnly = false) { + return factory.createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier); + }, factoryDeprecation); + + /** @deprecated Use `factory.updateExportDeclaration` or the factory supplied by your transformation context instead. */ + export const updateExportDeclaration = Debug.deprecate(function updateExportDeclaration( + node: ExportDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + exportClause: NamedExportBindings | undefined, + moduleSpecifier: Expression | undefined, + isTypeOnly: boolean) { + return factory.updateExportDeclaration(node, decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier); + }, factoryDeprecation); + + /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ + export const createJSDocParamTag = Debug.deprecate(function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag { + return factory.createJSDocParameterTag(/*tagName*/ undefined, name, isBracketed, typeExpression, /*isNameFirst*/ false, comment); + }, factoryDeprecation); + + /** @deprecated Use `factory.createComma` or the factory supplied by your transformation context instead. */ + export const createComma = Debug.deprecate(function createComma(left: Expression, right: Expression): Expression { + return factory.createComma(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createLessThan` or the factory supplied by your transformation context instead. */ + export const createLessThan = Debug.deprecate(function createLessThan(left: Expression, right: Expression): Expression { + return factory.createLessThan(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createAssignment` or the factory supplied by your transformation context instead. */ + export const createAssignment = Debug.deprecate(function createAssignment(left: Expression, right: Expression): BinaryExpression { + return factory.createAssignment(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createStrictEquality` or the factory supplied by your transformation context instead. */ + export const createStrictEquality = Debug.deprecate(function createStrictEquality(left: Expression, right: Expression): BinaryExpression { + return factory.createStrictEquality(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createStrictInequality` or the factory supplied by your transformation context instead. */ + export const createStrictInequality = Debug.deprecate(function createStrictInequality(left: Expression, right: Expression): BinaryExpression { + return factory.createStrictInequality(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createAdd` or the factory supplied by your transformation context instead. */ + export const createAdd = Debug.deprecate(function createAdd(left: Expression, right: Expression): BinaryExpression { + return factory.createAdd(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createSubtract` or the factory supplied by your transformation context instead. */ + export const createSubtract = Debug.deprecate(function createSubtract(left: Expression, right: Expression): BinaryExpression { + return factory.createSubtract(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createLogicalAnd` or the factory supplied by your transformation context instead. */ + export const createLogicalAnd = Debug.deprecate(function createLogicalAnd(left: Expression, right: Expression): BinaryExpression { + return factory.createLogicalAnd(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createLogicalOr` or the factory supplied by your transformation context instead. */ + export const createLogicalOr = Debug.deprecate(function createLogicalOr(left: Expression, right: Expression): BinaryExpression { + return factory.createLogicalOr(left, right); + }, factoryDeprecation); + + /** @deprecated Use `factory.createPostfixIncrement` or the factory supplied by your transformation context instead. */ + export const createPostfixIncrement = Debug.deprecate(function createPostfixIncrement(operand: Expression): PostfixUnaryExpression { + return factory.createPostfixIncrement(operand); + }, factoryDeprecation); + + /** @deprecated Use `factory.createLogicalNot` or the factory supplied by your transformation context instead. */ + export const createLogicalNot = Debug.deprecate(function createLogicalNot(operand: Expression): PrefixUnaryExpression { + return factory.createLogicalNot(operand); + }, factoryDeprecation); + + /** @deprecated Use an appropriate `factory` method instead. */ + export const createNode = Debug.deprecate(function createNode(kind: SyntaxKind, pos = 0, end = 0): Node { + return setTextRangePosEnd( + kind === SyntaxKind.SourceFile ? parseBaseNodeFactory.createBaseSourceFileNode(kind) : + kind === SyntaxKind.Identifier ? parseBaseNodeFactory.createBaseIdentifierNode(kind) : + kind === SyntaxKind.PrivateIdentifier ? parseBaseNodeFactory.createBasePrivateIdentifierNode(kind) : + !isNodeKind(kind) ? parseBaseNodeFactory.createBaseTokenNode(kind) : + parseBaseNodeFactory.createBaseNode(kind), + pos, + end + ); + }, { since: "4.0", warnAfter: "4.1", message: "Use an appropriate `factory` method instead." }); + + /** + * Creates a shallow, memberwise clone of a node ~for mutation~ with its `pos`, `end`, and `parent` set. + * + * NOTE: It is unsafe to change any properties of a `Node` that relate to its AST children, as those changes won't be + * captured with respect to transformations. + * + * @deprecated Use `factory.cloneNode` instead and use `setCommentRange` or `setSourceMapRange` and avoid setting `parent`. + */ + export const getMutableClone = Debug.deprecate(function getMutableClone(node: T): T { + const clone = factory.cloneNode(node); + setTextRange(clone, node); + setParent(clone, node.parent); + return clone; + }, { since: "4.0", warnAfter: "4.1", message: "Use `factory.cloneNode` instead and use `setCommentRange` or `setSourceMapRange` and avoid setting `parent`." }); + + // #endregion Node Factory top-level exports + + // DEPRECATION: Renamed node tests + // DEPRECATION PLAN: + // - soft: 4.0 + // - warn: 4.1 + // - error: TBD + // #region Renamed node Tests + + /** @deprecated Use `isTypeAssertionExpression` instead. */ + export const isTypeAssertion = Debug.deprecate(function isTypeAssertion(node: Node): node is TypeAssertion { + return node.kind === SyntaxKind.TypeAssertionExpression; + }, { + since: "4.0", + warnAfter: "4.1", + message: "Use `isTypeAssertionExpression` instead." + }); + + // #endregion Renamed node Tests +} \ No newline at end of file diff --git a/src/compat/tsconfig.json b/src/compat/tsconfig.json new file mode 100644 index 0000000000000..c9559ebc8651f --- /dev/null +++ b/src/compat/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig-base", + "compilerOptions": { + "outFile": "../../built/local/compat.js" + }, + "references": [ + { "path": "../compiler" } + ], + "files": [ + "deprecations.ts" + ] +} \ No newline at end of file diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0d42737bf4dca..c65b720f8f5f3 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -18,7 +18,8 @@ namespace ts { export function getModuleInstanceState(node: ModuleDeclaration, visited?: Map): ModuleInstanceState { if (node.body && !node.body.parent) { // getModuleInstanceStateForAliasTarget needs to walk up the parent chain, so parent pointers must be set on this tree already - setParentPointers(node, node.body); + setParent(node.body, node); + setParentRecursive(node.body, /*incremental*/ false); } return node.body ? getModuleInstanceStateCached(node.body, visited) : ModuleInstanceState.Instantiated; } @@ -116,7 +117,8 @@ namespace ts { for (const statement of statements) { if (nodeHasName(statement, name)) { if (!statement.parent) { - setParentPointers(p, statement); + setParent(statement, p); + setParentRecursive(statement, /*incremental*/ false); } const state = getModuleInstanceStateCached(statement, visited); if (found === undefined || state > found) { @@ -221,10 +223,6 @@ namespace ts { const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; - // state used to aggregate transform flags during bind. - let subtreeTransformFlags: TransformFlags = TransformFlags.None; - let skipTransformFlagAggregation: boolean; - /** * Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file) * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node) @@ -241,7 +239,6 @@ namespace ts { inStrictMode = bindInStrictMode(file, opts); classifiableNames = createUnderscoreEscapedMap(); symbolCount = 0; - skipTransformFlagAggregation = file.isDeclarationFile; Symbol = objectAllocator.getSymbolConstructor(); @@ -276,7 +273,6 @@ namespace ts { activeLabelList = undefined; hasExplicitReturn = false; emitFlags = NodeFlags.None; - subtreeTransformFlags = TransformFlags.None; } return bindSourceFile; @@ -469,7 +465,7 @@ namespace ts { else if (!(includes & SymbolFlags.Variable && symbol.flags & SymbolFlags.Assignment)) { // Assignment declarations are allowed to merge with variables, no matter what other flags they have. if (isNamedDeclaration(node)) { - node.name.parent = node; + setParent(node.name, node); } // Report errors every position with duplicate declaration // Report errors on previous encountered declarations @@ -590,7 +586,7 @@ namespace ts { // All container nodes are kept on a linked list in declaration order. This list is used by // the getLocalNameOfContainer function in the type checker to validate that the local name // used for a container is unique. - function bindContainer(node: Node, containerFlags: ContainerFlags) { + function bindContainer(node: Mutable, containerFlags: ContainerFlags) { // Before we recurse into a node's children, we first save the existing parent, container // and block-container. Then after we pop out of processing the children, we restore // these saved values. @@ -698,24 +694,6 @@ namespace ts { blockScopeContainer = savedBlockScopeContainer; } - function bindChildren(node: Node): void { - if (skipTransformFlagAggregation) { - bindChildrenWorker(node); - } - else if (node.transformFlags & TransformFlags.HasComputedFlags) { - skipTransformFlagAggregation = true; - bindChildrenWorker(node); - skipTransformFlagAggregation = false; - subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind); - } - else { - const savedSubtreeTransformFlags = subtreeTransformFlags; - subtreeTransformFlags = 0; - bindChildrenWorker(node); - subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags); - } - } - function bindEachFunctionsFirst(nodes: NodeArray | undefined): void { bindEach(nodes, n => n.kind === SyntaxKind.FunctionDeclaration ? bind(n) : undefined); bindEach(nodes, n => n.kind !== SyntaxKind.FunctionDeclaration ? bind(n) : undefined); @@ -726,27 +704,14 @@ namespace ts { return; } - if (skipTransformFlagAggregation) { - forEach(nodes, bindFunction); - } - else { - const savedSubtreeTransformFlags = subtreeTransformFlags; - subtreeTransformFlags = TransformFlags.None; - let nodeArrayFlags = TransformFlags.None; - for (const node of nodes) { - bindFunction(node); - nodeArrayFlags |= node.transformFlags & ~TransformFlags.HasComputedFlags; - } - nodes.transformFlags = nodeArrayFlags | TransformFlags.HasComputedFlags; - subtreeTransformFlags |= savedSubtreeTransformFlags; - } + forEach(nodes, bindFunction); } function bindEachChild(node: Node) { forEachChild(node, bind, bindEach); } - function bindChildrenWorker(node: Node): void { + function bindChildren(node: Node): void { if (checkUnreachable(node)) { bindEachChild(node); bindJSDoc(node); @@ -1310,8 +1275,6 @@ namespace ts { } function bindCaseBlock(node: CaseBlock): void { - const savedSubtreeTransformFlags = subtreeTransformFlags; - subtreeTransformFlags = 0; const clauses = node.clauses; const isNarrowingSwitch = isNarrowingExpression(node.parent.expression); let fallthroughFlow = unreachableFlow; @@ -1332,8 +1295,6 @@ namespace ts { clause.fallthroughFlowNode = currentFlow; } } - clauses.transformFlags = subtreeTransformFlags | TransformFlags.HasComputedFlags; - subtreeTransformFlags |= savedSubtreeTransformFlags; } function bindCaseClause(node: CaseClause): void { @@ -1474,13 +1435,11 @@ namespace ts { state: BindBinaryExpressionFlowState[], inStrictMode: (boolean | undefined)[], parent: (Node | undefined)[], - subtreeFlags: (number | undefined)[] } = { expr: [node], state: [BindBinaryExpressionFlowState.MaybeBindLeft], inStrictMode: [undefined], parent: [undefined], - subtreeFlags: [undefined] }; let stackIndex = 0; while (stackIndex >= 0) { @@ -1489,29 +1448,13 @@ namespace ts { case BindBinaryExpressionFlowState.BindThenBindChildren: { // This state is used only when recuring, to emulate the work that `bind` does before // reaching `bindChildren`. A normal call to `bindBinaryExpressionFlow` will already have done this work. - node.parent = parent; + setParent(node, parent); const saveInStrictMode = inStrictMode; bindWorker(node); const saveParent = parent; parent = node; - let subtreeFlagsState: number | undefined; - // While this next part does the work of `bindChildren` before it descends into `bindChildrenWorker` - // and uses `subtreeFlagsState` to queue up the work that needs to be done once the node is bound. - if (skipTransformFlagAggregation) { - // do nothing extra - } - else if (node.transformFlags & TransformFlags.HasComputedFlags) { - skipTransformFlagAggregation = true; - subtreeFlagsState = -1; - } - else { - const savedSubtreeTransformFlags = subtreeTransformFlags; - subtreeTransformFlags = 0; - subtreeFlagsState = savedSubtreeTransformFlags; - } - - advanceState(BindBinaryExpressionFlowState.MaybeBindLeft, saveInStrictMode, saveParent, subtreeFlagsState); + advanceState(BindBinaryExpressionFlowState.MaybeBindLeft, saveInStrictMode, saveParent); break; } case BindBinaryExpressionFlowState.MaybeBindLeft: { @@ -1569,7 +1512,7 @@ namespace ts { * Note that `advanceState` sets the _current_ head state, and that `maybeBind` potentially pushes on a new * head state; so `advanceState` must be called before any `maybeBind` during a state's execution. */ - function advanceState(state: BindBinaryExpressionFlowState, isInStrictMode?: boolean, parent?: Node, subtreeFlags?: number) { + function advanceState(state: BindBinaryExpressionFlowState, isInStrictMode?: boolean, parent?: Node) { workStacks.state[stackIndex] = state; if (isInStrictMode !== undefined) { workStacks.inStrictMode[stackIndex] = isInStrictMode; @@ -1577,20 +1520,10 @@ namespace ts { if (parent !== undefined) { workStacks.parent[stackIndex] = parent; } - if (subtreeFlags !== undefined) { - workStacks.subtreeFlags[stackIndex] = subtreeFlags; - } } function completeNode() { if (workStacks.inStrictMode[stackIndex] !== undefined) { - if (workStacks.subtreeFlags[stackIndex] === -1) { - skipTransformFlagAggregation = false; - subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind); - } - else if (workStacks.subtreeFlags[stackIndex] !== undefined) { - subtreeTransformFlags = workStacks.subtreeFlags[stackIndex]! | computeTransformFlagsForNode(node, subtreeTransformFlags); - } inStrictMode = workStacks.inStrictMode[stackIndex]!; parent = workStacks.parent[stackIndex]!; } @@ -1607,7 +1540,6 @@ namespace ts { workStacks.state[stackIndex] = BindBinaryExpressionFlowState.BindThenBindChildren; workStacks.inStrictMode[stackIndex] = undefined; workStacks.parent[stackIndex] = undefined; - workStacks.subtreeFlags[stackIndex] = undefined; } else { bind(node); @@ -1658,9 +1590,10 @@ namespace ts { } function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag) { - node.tagName.parent = node; + setParent(node.tagName, node); if (node.kind !== SyntaxKind.JSDocEnumTag && node.fullName) { - setParentPointers(node, node.fullName); + setParent(node.fullName, node); + setParentRecursive(node.fullName, /*incremental*/ false); } } @@ -1945,7 +1878,7 @@ namespace ts { return !!body && body.statements.some(s => isExportDeclaration(s) || isExportAssignment(s)); } - function setExportContextFlag(node: ModuleDeclaration | SourceFile) { + function setExportContextFlag(node: Mutable) { // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular // declarations with export modifiers) is an export context in which declarations are implicitly exported. if (node.flags & NodeFlags.Ambient && !hasExportDeclarations(node)) { @@ -2376,7 +2309,7 @@ namespace ts { if (!node) { return; } - node.parent = parent; + setParent(node, parent); const saveInStrictMode = inStrictMode; // Even though in the AST the jsdoc @typedef node belongs to the current node, @@ -2417,8 +2350,7 @@ namespace ts { } parent = saveParent; } - else if (!skipTransformFlagAggregation && (node.transformFlags & TransformFlags.HasComputedFlags) === 0) { - subtreeTransformFlags |= computeTransformFlagsForNode(node, 0); + else { const saveParent = parent; if (node.kind === SyntaxKind.EndOfFileToken) parent = node; bindJSDoc(node); @@ -2436,7 +2368,8 @@ namespace ts { } else { for (const j of node.jsDoc!) { - setParentPointers(node, j); + setParent(j, node); + setParentRecursive(j, /*incremental*/ false); } } } @@ -2773,7 +2706,7 @@ namespace ts { else if (isNamespaceExport(node.exportClause)) { // declareSymbol walks up parents to find name text, parent _must_ be set // but won't be set by the normal binder walk until `bindChildren` later on. - node.exportClause.parent = node; + setParent(node.exportClause, node); declareSymbol(container.symbol.exports, container.symbol, node.exportClause, SymbolFlags.Alias, SymbolFlags.AliasExcludes); } } @@ -2949,8 +2882,8 @@ namespace ts { /** For `x.prototype = { p, ... }`, declare members p,... if `x` is function/class/{}, or not declared. */ function bindPrototypeAssignment(node: BindableStaticPropertyAssignmentExpression) { - node.left.parent = node; - node.right.parent = node; + setParent(node.left, node); + setParent(node.right, node); bindPropertyAssignment(node.left.expression, node.left, /*isPrototypeProperty*/ false, /*containerIsClass*/ true); } @@ -2974,9 +2907,9 @@ namespace ts { const constructorFunction = classPrototype.expression; // Fix up parent pointers since we're going to use these nodes before we bind into them - lhs.parent = parent; - constructorFunction.parent = classPrototype; - classPrototype.parent = lhs; + setParent(constructorFunction, classPrototype); + setParent(classPrototype, lhs); + setParent(lhs, parent); bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true, /*containerIsClass*/ true); } @@ -2995,8 +2928,8 @@ namespace ts { return; } // Fix up parent pointers since we're going to use these nodes before we bind into them - node.left.parent = node; - node.right.parent = node; + setParent(node.left, node); + setParent(node.right, node); if (isIdentifier(node.left.expression) && container === file && isExportsOrModuleExportsOrAlias(file, node.left.expression)) { // This can be an alias for the 'exports' or 'module.exports' names, e.g. // var util = module.exports; @@ -3019,7 +2952,7 @@ namespace ts { */ function bindStaticPropertyAssignment(node: BindableStaticNameExpression) { Debug.assert(!isIdentifier(node)); - node.expression.parent = node; + setParent(node.expression, node); bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false, /*containerIsClass*/ false); } @@ -3206,7 +3139,7 @@ namespace ts { const symbolExport = symbol.exports!.get(prototypeSymbol.escapedName); if (symbolExport) { if (node.name) { - node.name.parent = node; + setParent(node.name, node); } file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, symbolName(prototypeSymbol))); } @@ -3468,996 +3401,4 @@ namespace ts { } return container.symbol && container.symbol.exports && container.symbol.exports.get(name); } - - /** - * Computes the transform flags for a node, given the transform flags of its subtree - * - * @param node The node to analyze - * @param subtreeFlags Transform flags computed for this node's subtree - */ - export function computeTransformFlagsForNode(node: Node, subtreeFlags: TransformFlags): TransformFlags { - const kind = node.kind; - switch (kind) { - case SyntaxKind.CallExpression: - return computeCallExpression(node, subtreeFlags); - - case SyntaxKind.NewExpression: - return computeNewExpression(node, subtreeFlags); - - case SyntaxKind.ModuleDeclaration: - return computeModuleDeclaration(node, subtreeFlags); - - case SyntaxKind.ParenthesizedExpression: - return computeParenthesizedExpression(node, subtreeFlags); - - case SyntaxKind.BinaryExpression: - return computeBinaryExpression(node, subtreeFlags); - - case SyntaxKind.ExpressionStatement: - return computeExpressionStatement(node, subtreeFlags); - - case SyntaxKind.Parameter: - return computeParameter(node, subtreeFlags); - - case SyntaxKind.ArrowFunction: - return computeArrowFunction(node, subtreeFlags); - - case SyntaxKind.FunctionExpression: - return computeFunctionExpression(node, subtreeFlags); - - case SyntaxKind.FunctionDeclaration: - return computeFunctionDeclaration(node, subtreeFlags); - - case SyntaxKind.VariableDeclaration: - return computeVariableDeclaration(node, subtreeFlags); - - case SyntaxKind.VariableDeclarationList: - return computeVariableDeclarationList(node, subtreeFlags); - - case SyntaxKind.VariableStatement: - return computeVariableStatement(node, subtreeFlags); - - case SyntaxKind.LabeledStatement: - return computeLabeledStatement(node, subtreeFlags); - - case SyntaxKind.ClassDeclaration: - return computeClassDeclaration(node, subtreeFlags); - - case SyntaxKind.ClassExpression: - return computeClassExpression(node, subtreeFlags); - - case SyntaxKind.HeritageClause: - return computeHeritageClause(node, subtreeFlags); - - case SyntaxKind.CatchClause: - return computeCatchClause(node, subtreeFlags); - - case SyntaxKind.ExpressionWithTypeArguments: - return computeExpressionWithTypeArguments(node, subtreeFlags); - - case SyntaxKind.Constructor: - return computeConstructor(node, subtreeFlags); - - case SyntaxKind.PropertyDeclaration: - return computePropertyDeclaration(node, subtreeFlags); - - case SyntaxKind.MethodDeclaration: - return computeMethod(node, subtreeFlags); - - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return computeAccessor(node, subtreeFlags); - - case SyntaxKind.ImportEqualsDeclaration: - return computeImportEquals(node, subtreeFlags); - - case SyntaxKind.PropertyAccessExpression: - return computePropertyAccess(node, subtreeFlags); - - case SyntaxKind.ElementAccessExpression: - return computeElementAccess(node, subtreeFlags); - - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxOpeningElement: - return computeJsxOpeningLikeElement(node, subtreeFlags); - - default: - return computeOther(node, kind, subtreeFlags); - } - } - - function computeCallExpression(node: CallExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const callee = skipOuterExpressions(node.expression); - const expression = node.expression; - - if (node.flags & NodeFlags.OptionalChain) { - transformFlags |= TransformFlags.ContainsES2020; - } - - if (node.typeArguments) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - if (subtreeFlags & TransformFlags.ContainsRestOrSpread || isSuperOrSuperProperty(callee)) { - // If the this node contains a SpreadExpression, or is a super call, then it is an ES6 - // node. - transformFlags |= TransformFlags.AssertES2015; - if (isSuperProperty(callee)) { - transformFlags |= TransformFlags.ContainsLexicalThis; - } - } - - if (expression.kind === SyntaxKind.ImportKeyword) { - transformFlags |= TransformFlags.ContainsDynamicImport; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; - } - - function computeNewExpression(node: NewExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - if (node.typeArguments) { - transformFlags |= TransformFlags.AssertTypeScript; - } - if (subtreeFlags & TransformFlags.ContainsRestOrSpread) { - // If the this node contains a SpreadElementExpression then it is an ES6 - // node. - transformFlags |= TransformFlags.AssertES2015; - } - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; - } - - function computeJsxOpeningLikeElement(node: JsxOpeningLikeElement, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags | TransformFlags.AssertJsx; - if (node.typeArguments) { - transformFlags |= TransformFlags.AssertTypeScript; - } - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const operatorTokenKind = node.operatorToken.kind; - const leftKind = node.left.kind; - - if (operatorTokenKind === SyntaxKind.QuestionQuestionToken) { - transformFlags |= TransformFlags.AssertES2020; - } - else if (isLogicalOrCoalescingAssignmentOperator(operatorTokenKind)) { - transformFlags |= TransformFlags.AssertESNext; - } - else if (operatorTokenKind === SyntaxKind.EqualsToken && leftKind === SyntaxKind.ObjectLiteralExpression) { - // Destructuring object assignments with are ES2015 syntax - // and possibly ES2018 if they contain rest - transformFlags |= TransformFlags.AssertES2018 | TransformFlags.AssertES2015 | TransformFlags.AssertDestructuringAssignment; - } - else if (operatorTokenKind === SyntaxKind.EqualsToken && leftKind === SyntaxKind.ArrayLiteralExpression) { - // Destructuring assignments are ES2015 syntax. - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertDestructuringAssignment; - } - else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken - || operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) { - // Exponentiation is ES2016 syntax. - transformFlags |= TransformFlags.AssertES2016; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeParameter(node: ParameterDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const name = node.name; - const initializer = node.initializer; - const dotDotDotToken = node.dotDotDotToken; - - // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript - // syntax. - if (node.questionToken - || node.type - || (subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax && some(node.decorators)) - || isThisIdentifier(name)) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // If a parameter has an accessibility modifier, then it is TypeScript syntax. - if (hasSyntacticModifier(node, ModifierFlags.ParameterPropertyModifier)) { - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsTypeScriptClassSyntax; - } - - // parameters with object rest destructuring are ES2018 syntax - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018; - } - - // If a parameter has an initializer, a binding pattern or a dotDotDot token, then - // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel. - if (subtreeFlags & TransformFlags.ContainsBindingPattern || initializer || dotDotDotToken) { - transformFlags |= TransformFlags.AssertES2015; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ParameterExcludes; - } - - function computeParenthesizedExpression(node: ParenthesizedExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const expression = node.expression; - const expressionKind = expression.kind; - - // If the node is synthesized, it means the emitter put the parentheses there, - // not the user. If we didn't want them, the emitter would not have put them - // there. - if (expressionKind === SyntaxKind.AsExpression - || expressionKind === SyntaxKind.TypeAssertionExpression) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.OuterExpressionExcludes; - } - - function computeClassDeclaration(node: ClassDeclaration, subtreeFlags: TransformFlags) { - let transformFlags: TransformFlags; - - if (hasSyntacticModifier(node, ModifierFlags.Ambient)) { - // An ambient declaration is TypeScript syntax. - transformFlags = TransformFlags.AssertTypeScript; - } - else { - // A ClassDeclaration is ES6 syntax. - transformFlags = subtreeFlags | TransformFlags.AssertES2015; - - // A class with a parameter property assignment or decorator is TypeScript syntax. - // An exported declaration may be TypeScript syntax, but is handled by the visitor - // for a namespace declaration. - if ((subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax) - || node.typeParameters) { - transformFlags |= TransformFlags.AssertTypeScript; - } - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ClassExcludes; - } - - function computeClassExpression(node: ClassExpression, subtreeFlags: TransformFlags) { - // A ClassExpression is ES6 syntax. - let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - - // A class with a parameter property assignment or decorator is TypeScript syntax. - if (subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax - || node.typeParameters) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ClassExcludes; - } - - function computeHeritageClause(node: HeritageClause, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - switch (node.token) { - case SyntaxKind.ExtendsKeyword: - // An `extends` HeritageClause is ES6 syntax. - transformFlags |= TransformFlags.AssertES2015; - break; - - case SyntaxKind.ImplementsKeyword: - // An `implements` HeritageClause is TypeScript syntax. - transformFlags |= TransformFlags.AssertTypeScript; - break; - - default: - Debug.fail("Unexpected token for heritage clause"); - break; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeCatchClause(node: CatchClause, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - if (!node.variableDeclaration) { - transformFlags |= TransformFlags.AssertES2019; - } - else if (isBindingPattern(node.variableDeclaration.name)) { - transformFlags |= TransformFlags.AssertES2015; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.CatchClauseExcludes; - } - - function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) { - // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the - // extends clause of a class. - let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - - // If an ExpressionWithTypeArguments contains type arguments, then it - // is TypeScript syntax. - if (node.typeArguments) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeConstructor(node: ConstructorDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // TypeScript-specific modifiers and overloads are TypeScript syntax - if (hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) - || !node.body) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // function declarations with object rest destructuring are ES2018 syntax - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ConstructorExcludes; - } - - function computeMethod(node: MethodDeclaration, subtreeFlags: TransformFlags) { - // A MethodDeclaration is ES6 syntax. - let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - - // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and - // overloads are TypeScript syntax. - if (node.decorators - || hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) - || node.typeParameters - || node.type - || !node.body - || node.questionToken) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // function declarations with object rest destructuring are ES2018 syntax - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018; - } - - // An async method declaration is ES2017 syntax. - if (hasSyntacticModifier(node, ModifierFlags.Async)) { - transformFlags |= node.asteriskToken ? TransformFlags.AssertES2018 : TransformFlags.AssertES2017; - } - - if (node.asteriskToken) { - transformFlags |= TransformFlags.AssertGenerator; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return propagatePropertyNameFlags(node.name, transformFlags & ~TransformFlags.MethodOrAccessorExcludes); - } - - function computeAccessor(node: AccessorDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // Decorators, TypeScript-specific modifiers, type annotations, and overloads are - // TypeScript syntax. - if (node.decorators - || hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) - || node.type - || !node.body) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // function declarations with object rest destructuring are ES2018 syntax - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return propagatePropertyNameFlags(node.name, transformFlags & ~TransformFlags.MethodOrAccessorExcludes); - } - - function computePropertyDeclaration(node: PropertyDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags | TransformFlags.ContainsClassFields; - - // Decorators, TypeScript-specific modifiers, and type annotations are TypeScript syntax. - if (some(node.decorators) || hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) || node.type || node.questionToken || node.exclamationToken) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // Hoisted variables related to class properties should live within the TypeScript class wrapper. - if (isComputedPropertyName(node.name) || (hasStaticModifier(node) && node.initializer)) { - transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return propagatePropertyNameFlags(node.name, transformFlags & ~TransformFlags.PropertyExcludes); - } - - function computeFunctionDeclaration(node: FunctionDeclaration, subtreeFlags: TransformFlags) { - let transformFlags: TransformFlags; - const modifierFlags = getSyntacticModifierFlags(node); - const body = node.body; - - if (!body || (modifierFlags & ModifierFlags.Ambient)) { - // An ambient declaration is TypeScript syntax. - // A FunctionDeclaration without a body is an overload and is TypeScript syntax. - transformFlags = TransformFlags.AssertTypeScript; - } - else { - transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion; - - // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript - // syntax. - if (modifierFlags & ModifierFlags.TypeScriptModifier - || node.typeParameters - || node.type) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // An async function declaration is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { - transformFlags |= node.asteriskToken ? TransformFlags.AssertES2018 : TransformFlags.AssertES2017; - } - - // function declarations with object rest destructuring are ES2018 syntax - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018; - } - - // If a FunctionDeclaration is generator function and is the body of a - // transformed async function, then this node can be transformed to a - // down-level generator. - // Currently we do not support transforming any other generator functions - // down level. - if (node.asteriskToken) { - transformFlags |= TransformFlags.AssertGenerator; - } - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.FunctionExcludes; - } - - function computeFunctionExpression(node: FunctionExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript - // syntax. - if (hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) - || node.typeParameters - || node.type) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // An async function expression is ES2017 syntax. - if (hasSyntacticModifier(node, ModifierFlags.Async)) { - transformFlags |= node.asteriskToken ? TransformFlags.AssertES2018 : TransformFlags.AssertES2017; - } - - // function expressions with object rest destructuring are ES2018 syntax - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018; - } - - // If a FunctionExpression is generator function and is the body of a - // transformed async function, then this node can be transformed to a - // down-level generator. - if (node.asteriskToken) { - transformFlags |= TransformFlags.AssertGenerator; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.FunctionExcludes; - } - - function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) { - // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction. - let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - - // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript - // syntax. - if (hasSyntacticModifier(node, ModifierFlags.TypeScriptModifier) - || node.typeParameters - || node.type) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // An async arrow function is ES2017 syntax. - if (hasSyntacticModifier(node, ModifierFlags.Async)) { - transformFlags |= TransformFlags.AssertES2017; - } - - // arrow functions with object rest destructuring are ES2018 syntax - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ArrowFunctionExcludes; - } - - function computePropertyAccess(node: PropertyAccessExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - if (node.flags & NodeFlags.OptionalChain) { - transformFlags |= TransformFlags.ContainsES2020; - } - - // If a PropertyAccessExpression starts with a super keyword, then it is - // ES6 syntax, and requires a lexical `this` binding. - if (node.expression.kind === SyntaxKind.SuperKeyword) { - // super inside of an async function requires hoisting the super access (ES2017). - // same for super inside of an async generator, which is ES2018. - transformFlags |= TransformFlags.ContainsES2017 | TransformFlags.ContainsES2018; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.PropertyAccessExcludes; - } - - function computeElementAccess(node: ElementAccessExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - if (node.flags & NodeFlags.OptionalChain) { - transformFlags |= TransformFlags.ContainsES2020; - } - - // If an ElementAccessExpression starts with a super keyword, then it is - // ES6 syntax, and requires a lexical `this` binding. - if (node.expression.kind === SyntaxKind.SuperKeyword) { - // super inside of an async function requires hoisting the super access (ES2017). - // same for super inside of an async generator, which is ES2018. - transformFlags |= TransformFlags.ContainsES2017 | TransformFlags.ContainsES2018; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.PropertyAccessExcludes; - } - - function computeVariableDeclaration(node: VariableDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern; // TODO(rbuckton): Why are these set unconditionally? - - // A VariableDeclaration containing ObjectRest is ES2018 syntax - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018; - } - - // Type annotations are TypeScript syntax. - if (node.type || node.exclamationToken) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeVariableStatement(node: VariableStatement, subtreeFlags: TransformFlags) { - let transformFlags: TransformFlags; - const declarationListTransformFlags = node.declarationList.transformFlags; - - // An ambient declaration is TypeScript syntax. - if (hasSyntacticModifier(node, ModifierFlags.Ambient)) { - transformFlags = TransformFlags.AssertTypeScript; - } - else { - transformFlags = subtreeFlags; - - if (declarationListTransformFlags & TransformFlags.ContainsBindingPattern) { - transformFlags |= TransformFlags.AssertES2015; - } - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeLabeledStatement(node: LabeledStatement, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // A labeled statement containing a block scoped binding *may* need to be transformed from ES6. - if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding - && isIterationStatement(node, /*lookInLabeledStatements*/ true)) { - transformFlags |= TransformFlags.AssertES2015; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeImportEquals(node: ImportEqualsDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // An ImportEqualsDeclaration with a namespace reference is TypeScript. - if (!isExternalModuleImportEqualsDeclaration(node)) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeExpressionStatement(node: ExpressionStatement, subtreeFlags: TransformFlags) { - const transformFlags = subtreeFlags; - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeModuleDeclaration(node: ModuleDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = TransformFlags.AssertTypeScript; - const modifierFlags = getSyntacticModifierFlags(node); - - if ((modifierFlags & ModifierFlags.Ambient) === 0) { - transformFlags |= subtreeFlags; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ModuleExcludes; - } - - function computeVariableDeclarationList(node: VariableDeclarationList, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion; - - if (subtreeFlags & TransformFlags.ContainsBindingPattern) { - transformFlags |= TransformFlags.AssertES2015; - } - - // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax. - if (node.flags & NodeFlags.BlockScoped) { - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBlockScopedBinding; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.VariableDeclarationListExcludes; - } - - function computeOther(node: Node, kind: SyntaxKind, subtreeFlags: TransformFlags) { - // Mark transformations needed for each node - let transformFlags = subtreeFlags; - let excludeFlags = TransformFlags.NodeExcludes; - - switch (kind) { - case SyntaxKind.AsyncKeyword: - // async is ES2017 syntax, but may be ES2018 syntax (for async generators) - transformFlags |= TransformFlags.AssertES2018 | TransformFlags.AssertES2017; - break; - case SyntaxKind.AwaitExpression: - // await is ES2017 syntax, but may be ES2018 syntax (for async generators) - transformFlags |= TransformFlags.AssertES2018 | TransformFlags.AssertES2017 | TransformFlags.ContainsAwait; - break; - - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.PartiallyEmittedExpression: - // These nodes are TypeScript syntax. - transformFlags |= TransformFlags.AssertTypeScript; - excludeFlags = TransformFlags.OuterExpressionExcludes; - break; - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.AbstractKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.EnumMember: - case SyntaxKind.NonNullExpression: - case SyntaxKind.ReadonlyKeyword: - // These nodes are TypeScript syntax. - transformFlags |= TransformFlags.AssertTypeScript; - break; - - case SyntaxKind.JsxElement: - case SyntaxKind.JsxText: - case SyntaxKind.JsxClosingElement: - case SyntaxKind.JsxFragment: - case SyntaxKind.JsxOpeningFragment: - case SyntaxKind.JsxClosingFragment: - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxAttributes: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.JsxExpression: - // These nodes are Jsx syntax. - transformFlags |= TransformFlags.AssertJsx; - break; - - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - case SyntaxKind.TemplateMiddle: - case SyntaxKind.TemplateTail: - if ((node).templateFlags) { - transformFlags |= TransformFlags.AssertES2018; - break; - } - // falls through - case SyntaxKind.TaggedTemplateExpression: - if (hasInvalidEscape((node).template)) { - transformFlags |= TransformFlags.AssertES2018; - break; - } - // falls through - case SyntaxKind.TemplateExpression: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.StaticKeyword: - case SyntaxKind.MetaProperty: - // These nodes are ES6 syntax. - transformFlags |= TransformFlags.AssertES2015; - break; - - case SyntaxKind.StringLiteral: - if ((node).hasExtendedUnicodeEscape) { - transformFlags |= TransformFlags.AssertES2015; - } - break; - - case SyntaxKind.NumericLiteral: - if ((node).numericLiteralFlags & TokenFlags.BinaryOrOctalSpecifier) { - transformFlags |= TransformFlags.AssertES2015; - } - break; - - case SyntaxKind.BigIntLiteral: - transformFlags |= TransformFlags.AssertESNext; - break; - - case SyntaxKind.ForOfStatement: - // This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of). - if ((node).awaitModifier) { - transformFlags |= TransformFlags.AssertES2018; - } - transformFlags |= TransformFlags.AssertES2015; - break; - - case SyntaxKind.YieldExpression: - // This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async - // generator). - transformFlags |= TransformFlags.AssertES2018 | TransformFlags.AssertES2015 | TransformFlags.ContainsYield; - break; - - case SyntaxKind.AnyKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.TypeParameter: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.TypePredicate: - case SyntaxKind.TypeReference: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.TypeQuery: - case SyntaxKind.TypeLiteral: - case SyntaxKind.ArrayType: - case SyntaxKind.TupleType: - case SyntaxKind.OptionalType: - case SyntaxKind.RestType: - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - case SyntaxKind.ConditionalType: - case SyntaxKind.InferType: - case SyntaxKind.ParenthesizedType: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ThisType: - case SyntaxKind.TypeOperator: - case SyntaxKind.IndexedAccessType: - case SyntaxKind.MappedType: - case SyntaxKind.LiteralType: - case SyntaxKind.NamespaceExportDeclaration: - // Types and signatures are TypeScript syntax, and exclude all other facts. - transformFlags = TransformFlags.AssertTypeScript; - excludeFlags = TransformFlags.TypeExcludes; - break; - - case SyntaxKind.ComputedPropertyName: - // Even though computed property names are ES6, we don't treat them as such. - // This is so that they can flow through PropertyName transforms unaffected. - // Instead, we mark the container as ES6, so that it can properly handle the transform. - transformFlags |= TransformFlags.ContainsComputedPropertyName; - break; - - case SyntaxKind.SpreadElement: - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsRestOrSpread; - break; - - case SyntaxKind.SpreadAssignment: - transformFlags |= TransformFlags.AssertES2018 | TransformFlags.ContainsObjectRestOrSpread; - break; - - case SyntaxKind.SuperKeyword: - // This node is ES6 syntax. - transformFlags |= TransformFlags.AssertES2015; - excludeFlags = TransformFlags.OuterExpressionExcludes; // must be set to persist `Super` - break; - - case SyntaxKind.ThisKeyword: - // Mark this node and its ancestors as containing a lexical `this` keyword. - transformFlags |= TransformFlags.ContainsLexicalThis; - break; - - case SyntaxKind.ObjectBindingPattern: - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern; - if (subtreeFlags & TransformFlags.ContainsRestOrSpread) { - transformFlags |= TransformFlags.AssertES2018 | TransformFlags.ContainsObjectRestOrSpread; - } - excludeFlags = TransformFlags.BindingPatternExcludes; - break; - - case SyntaxKind.ArrayBindingPattern: - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern; - excludeFlags = TransformFlags.BindingPatternExcludes; - break; - - case SyntaxKind.BindingElement: - transformFlags |= TransformFlags.AssertES2015; - if ((node).dotDotDotToken) { - transformFlags |= TransformFlags.ContainsRestOrSpread; - } - break; - - case SyntaxKind.Decorator: - // This node is TypeScript syntax, and marks its container as also being TypeScript syntax. - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsTypeScriptClassSyntax; - break; - - case SyntaxKind.ObjectLiteralExpression: - excludeFlags = TransformFlags.ObjectLiteralExcludes; - if (subtreeFlags & TransformFlags.ContainsComputedPropertyName) { - // If an ObjectLiteralExpression contains a ComputedPropertyName, then it - // is an ES6 node. - transformFlags |= TransformFlags.AssertES2015; - } - - if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) { - // If an ObjectLiteralExpression contains a spread element, then it - // is an ES2018 node. - transformFlags |= TransformFlags.AssertES2018; - } - - break; - - case SyntaxKind.ArrayLiteralExpression: - excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes; - break; - - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - // A loop containing a block scoped binding *may* need to be transformed from ES6. - if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding) { - transformFlags |= TransformFlags.AssertES2015; - } - - break; - - case SyntaxKind.SourceFile: - break; - - case SyntaxKind.NamespaceExport: - transformFlags |= TransformFlags.AssertESNext; - break; - - case SyntaxKind.ReturnStatement: - // Return statements may require an `await` in ES2018. - transformFlags |= TransformFlags.ContainsHoistedDeclarationOrCompletion | TransformFlags.AssertES2018; - break; - - case SyntaxKind.ContinueStatement: - case SyntaxKind.BreakStatement: - transformFlags |= TransformFlags.ContainsHoistedDeclarationOrCompletion; - break; - - case SyntaxKind.PrivateIdentifier: - transformFlags |= TransformFlags.ContainsClassFields; - break; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~excludeFlags; - } - - function propagatePropertyNameFlags(node: PropertyName, transformFlags: TransformFlags) { - return transformFlags | (node.transformFlags & TransformFlags.PropertyNamePropagatingFlags); - } - - /** - * Gets the transform flags to exclude when unioning the transform flags of a subtree. - * - * NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`. - * For performance reasons, `computeTransformFlagsForNode` uses local constant values rather - * than calling this function. - */ - export function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) { - if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) { - return TransformFlags.TypeExcludes; - } - - switch (kind) { - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.ArrayLiteralExpression: - return TransformFlags.ArrayLiteralOrCallOrNewExcludes; - case SyntaxKind.ModuleDeclaration: - return TransformFlags.ModuleExcludes; - case SyntaxKind.Parameter: - return TransformFlags.ParameterExcludes; - case SyntaxKind.ArrowFunction: - return TransformFlags.ArrowFunctionExcludes; - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - return TransformFlags.FunctionExcludes; - case SyntaxKind.VariableDeclarationList: - return TransformFlags.VariableDeclarationListExcludes; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - return TransformFlags.ClassExcludes; - case SyntaxKind.Constructor: - return TransformFlags.ConstructorExcludes; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return TransformFlags.MethodOrAccessorExcludes; - case SyntaxKind.AnyKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.TypeParameter: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - return TransformFlags.TypeExcludes; - case SyntaxKind.ObjectLiteralExpression: - return TransformFlags.ObjectLiteralExcludes; - case SyntaxKind.CatchClause: - return TransformFlags.CatchClauseExcludes; - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - return TransformFlags.BindingPatternExcludes; - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.PartiallyEmittedExpression: - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.SuperKeyword: - return TransformFlags.OuterExpressionExcludes; - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - return TransformFlags.PropertyAccessExcludes; - default: - return TransformFlags.NodeExcludes; - } - } - - /** - * "Binds" JSDoc nodes in TypeScript code. - * Since we will never create symbols for JSDoc, we just set parent pointers instead. - */ - function setParentPointers(parent: Node, child: Node): void { - child.parent = parent; - forEachChild(child, grandchild => setParentPointers(child, grandchild)); - } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fe4b3433a9909..192398a72520b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -372,8 +372,8 @@ namespace ts { getMergedSymbol, getDiagnostics, getGlobalDiagnostics, - getTypeOfSymbolAtLocation: (symbol, location) => { - location = getParseTreeNode(location); + getTypeOfSymbolAtLocation: (symbol, locationIn) => { + const location = getParseTreeNode(locationIn); return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType; }, getSymbolsOfParameterPropertyDeclaration: (parameterIn, parameterName) => { @@ -421,17 +421,17 @@ namespace ts { symbolToTypeParameterDeclarations: nodeBuilder.symbolToTypeParameterDeclarations, symbolToParameterDeclaration: nodeBuilder.symbolToParameterDeclaration, typeParameterToDeclaration: nodeBuilder.typeParameterToDeclaration, - getSymbolsInScope: (location, meaning) => { - location = getParseTreeNode(location); + getSymbolsInScope: (locationIn, meaning) => { + const location = getParseTreeNode(locationIn); return location ? getSymbolsInScope(location, meaning) : []; }, - getSymbolAtLocation: node => { - node = getParseTreeNode(node); + getSymbolAtLocation: nodeIn => { + const node = getParseTreeNode(nodeIn); // set ignoreErrors: true because any lookups invoked by the API shouldn't cause any new errors return node ? getSymbolAtLocation(node, /*ignoreErrors*/ true) : undefined; }, - getShorthandAssignmentValueSymbol: node => { - node = getParseTreeNode(node); + getShorthandAssignmentValueSymbol: nodeIn => { + const node = getParseTreeNode(nodeIn); return node ? getShorthandAssignmentValueSymbol(node) : undefined; }, getExportSpecifierLocalTargetSymbol: nodeIn => { @@ -441,8 +441,8 @@ namespace ts { getExportSymbolOfSymbol(symbol) { return getMergedSymbol(symbol.exportSymbol || symbol); }, - getTypeAtLocation: node => { - node = getParseTreeNode(node); + getTypeAtLocation: nodeIn => { + const node = getParseTreeNode(nodeIn); return node ? getTypeOfNode(node) : errorType; }, getTypeOfAssignmentPattern: nodeIn => { @@ -541,9 +541,9 @@ namespace ts { const declaration = getParseTreeNode(declarationIn, isFunctionLike); return declaration ? getSignatureFromDeclaration(declaration) : undefined; }, - isImplementationOfOverload: node => { - const parsed = getParseTreeNode(node, isFunctionLike); - return parsed ? isImplementationOfOverload(parsed) : undefined; + isImplementationOfOverload: nodeIn => { + const node = getParseTreeNode(nodeIn, isFunctionLike); + return node ? isImplementationOfOverload(node) : undefined; }, getImmediateAliasedSymbol, getAliasedSymbol: resolveAlias, @@ -618,19 +618,21 @@ namespace ts { getJsxNamespace: n => unescapeLeadingUnderscores(getJsxNamespace(n)), getAccessibleSymbolChain, getTypePredicateOfSignature, - resolveExternalModuleName: moduleSpecifier => { - return resolveExternalModuleName(moduleSpecifier, moduleSpecifier, /*ignoreErrors*/ true); + resolveExternalModuleName: moduleSpecifierIn => { + const moduleSpecifier = getParseTreeNode(moduleSpecifierIn, isExpression); + return moduleSpecifier && resolveExternalModuleName(moduleSpecifier, moduleSpecifier, /*ignoreErrors*/ true); }, resolveExternalModuleSymbol, - tryGetThisTypeAt: (node, includeGlobalThis) => { - node = getParseTreeNode(node); + tryGetThisTypeAt: (nodeIn, includeGlobalThis) => { + const node = getParseTreeNode(nodeIn); return node && tryGetThisTypeAt(node, includeGlobalThis); }, getTypeArgumentConstraint: nodeIn => { const node = getParseTreeNode(nodeIn, isTypeNode); return node && getTypeArgumentConstraint(node); }, - getSuggestionDiagnostics: (file, ct) => { + getSuggestionDiagnostics: (fileIn, ct) => { + const file = getParseTreeNode(fileIn, isSourceFile) || Debug.fail("Could not determine parsed source file."); if (skipTypeChecking(file, compilerOptions, host)) { return emptyArray; } @@ -980,13 +982,12 @@ namespace ts { } } if (!_jsxFactoryEntity) { - _jsxFactoryEntity = createQualifiedName(createIdentifier(unescapeLeadingUnderscores(_jsxNamespace)), "createElement"); + _jsxFactoryEntity = factory.createQualifiedName(factory.createIdentifier(unescapeLeadingUnderscores(_jsxNamespace)), "createElement"); } return _jsxNamespace; function markAsSynthetic(node: Node): VisitResult { - node.pos = -1; - node.end = -1; + setTextRangePosEnd(node, -1, -1); return visitEachChild(node, markAsSynthetic, nullTransformationContext); } } @@ -4178,8 +4179,8 @@ namespace ts { typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)), indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context)), - signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => + withContext(enclosingDeclaration, flags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context, /*typeNode*/ undefined)), + signatureToSignatureDeclaration: (signature: Signature, kind: SignatureDeclaration["kind"], enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => signatureToSignatureDeclarationHelper(signature, kind, context)), symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false)), @@ -4240,7 +4241,7 @@ namespace ts { return undefined!; // TODO: GH#18217 } context.approximateLength += 3; - return createKeywordTypeNode(SyntaxKind.AnyKeyword); + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } if (!(context.flags & NodeBuilderFlags.NoTypeReduction)) { @@ -4249,26 +4250,26 @@ namespace ts { if (type.flags & TypeFlags.Any) { context.approximateLength += 3; - return createKeywordTypeNode(SyntaxKind.AnyKeyword); + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } if (type.flags & TypeFlags.Unknown) { - return createKeywordTypeNode(SyntaxKind.UnknownKeyword); + return factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword); } if (type.flags & TypeFlags.String) { context.approximateLength += 6; - return createKeywordTypeNode(SyntaxKind.StringKeyword); + return factory.createKeywordTypeNode(SyntaxKind.StringKeyword); } if (type.flags & TypeFlags.Number) { context.approximateLength += 6; - return createKeywordTypeNode(SyntaxKind.NumberKeyword); + return factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); } if (type.flags & TypeFlags.BigInt) { context.approximateLength += 6; - return createKeywordTypeNode(SyntaxKind.BigIntKeyword); + return factory.createKeywordTypeNode(SyntaxKind.BigIntKeyword); } if (type.flags & TypeFlags.Boolean) { context.approximateLength += 7; - return createKeywordTypeNode(SyntaxKind.BooleanKeyword); + return factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); } if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) { const parentSymbol = getParentOfSymbol(type.symbol)!; @@ -4277,7 +4278,7 @@ namespace ts { ? parentName : appendReferenceToType( parentName as TypeReferenceNode | ImportTypeNode, - createTypeReferenceNode(symbolName(type.symbol), /*typeArguments*/ undefined) + factory.createTypeReferenceNode(symbolName(type.symbol), /*typeArguments*/ undefined) ); return enumLiteralName; } @@ -4286,20 +4287,20 @@ namespace ts { } if (type.flags & TypeFlags.StringLiteral) { context.approximateLength += ((type).value.length + 2); - return createLiteralTypeNode(setEmitFlags(createLiteral((type).value, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)), EmitFlags.NoAsciiEscaping)); + return factory.createLiteralTypeNode(setEmitFlags(factory.createStringLiteral((type).value, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)), EmitFlags.NoAsciiEscaping)); } if (type.flags & TypeFlags.NumberLiteral) { const value = (type).value; context.approximateLength += ("" + value).length; - return createLiteralTypeNode(value < 0 ? createPrefix(SyntaxKind.MinusToken, createLiteral(-value)) : createLiteral(value)); + return factory.createLiteralTypeNode(value < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-value)) : factory.createNumericLiteral(value)); } if (type.flags & TypeFlags.BigIntLiteral) { context.approximateLength += (pseudoBigIntToString((type).value).length) + 1; - return createLiteralTypeNode((createLiteral((type).value))); + return factory.createLiteralTypeNode((factory.createBigIntLiteral((type).value))); } if (type.flags & TypeFlags.BooleanLiteral) { context.approximateLength += (type).intrinsicName.length; - return (type).intrinsicName === "true" ? createTrue() : createFalse(); + return factory.createLiteralTypeNode((type).intrinsicName === "true" ? factory.createTrue() : factory.createFalse()); } if (type.flags & TypeFlags.UniqueESSymbol) { if (!(context.flags & NodeBuilderFlags.AllowUniqueESSymbolType)) { @@ -4312,31 +4313,31 @@ namespace ts { } } context.approximateLength += 13; - return createTypeOperatorNode(SyntaxKind.UniqueKeyword, createKeywordTypeNode(SyntaxKind.SymbolKeyword)); + return factory.createTypeOperatorNode(SyntaxKind.UniqueKeyword, factory.createKeywordTypeNode(SyntaxKind.SymbolKeyword)); } if (type.flags & TypeFlags.Void) { context.approximateLength += 4; - return createKeywordTypeNode(SyntaxKind.VoidKeyword); + return factory.createKeywordTypeNode(SyntaxKind.VoidKeyword); } if (type.flags & TypeFlags.Undefined) { context.approximateLength += 9; - return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + return factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword); } if (type.flags & TypeFlags.Null) { context.approximateLength += 4; - return createKeywordTypeNode(SyntaxKind.NullKeyword); + return factory.createLiteralTypeNode(factory.createNull()); } if (type.flags & TypeFlags.Never) { context.approximateLength += 5; - return createKeywordTypeNode(SyntaxKind.NeverKeyword); + return factory.createKeywordTypeNode(SyntaxKind.NeverKeyword); } if (type.flags & TypeFlags.ESSymbol) { context.approximateLength += 6; - return createKeywordTypeNode(SyntaxKind.SymbolKeyword); + return factory.createKeywordTypeNode(SyntaxKind.SymbolKeyword); } if (type.flags & TypeFlags.NonPrimitive) { context.approximateLength += 6; - return createKeywordTypeNode(SyntaxKind.ObjectKeyword); + return factory.createKeywordTypeNode(SyntaxKind.ObjectKeyword); } if (isThisTypeParameter(type)) { if (context.flags & NodeBuilderFlags.InObjectTypeLiteral) { @@ -4348,12 +4349,12 @@ namespace ts { } } context.approximateLength += 4; - return createThis(); + return factory.createThisTypeNode(); } if (!inTypeAlias && type.aliasSymbol && (context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) { const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); - if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & SymbolFlags.Class)) return createTypeReferenceNode(createIdentifier(""), typeArgumentNodes); + if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & SymbolFlags.Class)) return factory.createTypeReferenceNode(factory.createIdentifier(""), typeArgumentNodes); return symbolToTypeNode(type.aliasSymbol, context, SymbolFlags.Type, typeArgumentNodes); } @@ -4366,19 +4367,19 @@ namespace ts { if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) { if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) { context.approximateLength += (symbolName(type.symbol).length + 6); - return createInferTypeNode(typeParameterToDeclarationWithConstraint(type as TypeParameter, context, /*constraintNode*/ undefined)); + return factory.createInferTypeNode(typeParameterToDeclarationWithConstraint(type as TypeParameter, context, /*constraintNode*/ undefined)); } if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams && type.flags & TypeFlags.TypeParameter && !isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration)) { const name = typeParameterToName(type, context); context.approximateLength += idText(name).length; - return createTypeReferenceNode(createIdentifier(idText(name)), /*typeArguments*/ undefined); + return factory.createTypeReferenceNode(factory.createIdentifier(idText(name)), /*typeArguments*/ undefined); } // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return type.symbol ? symbolToTypeNode(type.symbol, context, SymbolFlags.Type) - : createTypeReferenceNode(createIdentifier("?"), /*typeArguments*/ undefined); + : factory.createTypeReferenceNode(factory.createIdentifier("?"), /*typeArguments*/ undefined); } if (type.flags & (TypeFlags.Union | TypeFlags.Intersection)) { const types = type.flags & TypeFlags.Union ? formatUnionTypes((type).types) : (type).types; @@ -4387,7 +4388,7 @@ namespace ts { } const typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true); if (typeNodes && typeNodes.length > 0) { - const unionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode(type.flags & TypeFlags.Union ? SyntaxKind.UnionType : SyntaxKind.IntersectionType, typeNodes); + const unionOrIntersectionTypeNode = type.flags & TypeFlags.Union ? factory.createUnionTypeNode(typeNodes) : factory.createIntersectionTypeNode(typeNodes); return unionOrIntersectionTypeNode; } else { @@ -4406,13 +4407,13 @@ namespace ts { const indexedType = (type).type; context.approximateLength += 6; const indexTypeNode = typeToTypeNodeHelper(indexedType, context); - return createTypeOperatorNode(indexTypeNode); + return factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, indexTypeNode); } if (type.flags & TypeFlags.IndexedAccess) { const objectTypeNode = typeToTypeNodeHelper((type).objectType, context); const indexTypeNode = typeToTypeNodeHelper((type).indexType, context); context.approximateLength += 2; - return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); + return factory.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); } if (type.flags & TypeFlags.Conditional) { const checkTypeNode = typeToTypeNodeHelper((type).checkType, context); @@ -4423,7 +4424,7 @@ namespace ts { const trueTypeNode = typeToTypeNodeOrCircularityElision(getTrueTypeFromConditionalType(type)); const falseTypeNode = typeToTypeNodeOrCircularityElision(getFalseTypeFromConditionalType(type)); context.approximateLength += 15; - return createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); + return factory.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); } if (type.flags & TypeFlags.Substitution) { return typeToTypeNodeHelper((type).baseType, context); @@ -4448,20 +4449,20 @@ namespace ts { function createMappedTypeNodeFromType(type: MappedType) { Debug.assert(!!(type.flags & TypeFlags.Object)); - const readonlyToken = type.declaration.readonlyToken ? createToken(type.declaration.readonlyToken.kind) : undefined; - const questionToken = type.declaration.questionToken ? createToken(type.declaration.questionToken.kind) : undefined; + const readonlyToken = type.declaration.readonlyToken ? factory.createToken(type.declaration.readonlyToken.kind) : undefined; + const questionToken = type.declaration.questionToken ? factory.createToken(type.declaration.questionToken.kind) : undefined; let appropriateConstraintTypeNode: TypeNode; if (isMappedTypeWithKeyofConstraintDeclaration(type)) { // We have a { [P in keyof T]: X } // We do this to ensure we retain the toplevel keyof-ness of the type which may be lost due to keyof distribution during `getConstraintTypeFromMappedType` - appropriateConstraintTypeNode = createTypeOperatorNode(typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context)); + appropriateConstraintTypeNode = factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context)); } else { appropriateConstraintTypeNode = typeToTypeNodeHelper(getConstraintTypeFromMappedType(type), context); } const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode); const templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context); - const mappedTypeNode = createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); + const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); context.approximateLength += 10; return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine); } @@ -4556,7 +4557,7 @@ namespace ts { if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { context.approximateLength += 2; - return setEmitFlags(createTypeLiteralNode(/*members*/ undefined), EmitFlags.SingleLine); + return setEmitFlags(factory.createTypeLiteralNode(/*members*/ undefined), EmitFlags.SingleLine); } if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { @@ -4577,7 +4578,7 @@ namespace ts { context.flags |= NodeBuilderFlags.InObjectTypeLiteral; const members = createTypeNodesFromResolvedType(resolved); context.flags = savedFlags; - const typeLiteralNode = createTypeLiteralNode(members); + const typeLiteralNode = factory.createTypeLiteralNode(members); context.approximateLength += 2; return setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine); } @@ -4587,11 +4588,11 @@ namespace ts { if (type.target === globalArrayType || type.target === globalReadonlyArrayType) { if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) { const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context); - return createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray", [typeArgumentNode]); + return factory.createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray", [typeArgumentNode]); } const elementType = typeToTypeNodeHelper(typeArguments[0], context); - const arrayType = createArrayTypeNode(elementType); - return type.target === globalArrayType ? arrayType : createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType); + const arrayType = factory.createArrayTypeNode(elementType); + return type.target === globalArrayType ? arrayType : factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType); } else if (type.target.objectFlags & ObjectFlags.Tuple) { if (typeArguments.length > 0) { @@ -4604,28 +4605,28 @@ namespace ts { const isOptionalOrRest = i >= (type.target).minLength; const isRest = isOptionalOrRest && hasRestElement && i === arity - 1; const isOptional = isOptionalOrRest && !isRest; - tupleConstituentNodes[i] = createNamedTupleMember( - isRest ? createToken(SyntaxKind.DotDotDotToken) : undefined, - createIdentifier(unescapeLeadingUnderscores(getTupleElementLabel((type.target as TupleType).labeledElementDeclarations![i]))), - isOptional ? createToken(SyntaxKind.QuestionToken) : undefined, - isRest ? createArrayTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i] + tupleConstituentNodes[i] = factory.createNamedTupleMember( + isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined, + factory.createIdentifier(unescapeLeadingUnderscores(getTupleElementLabel((type.target as TupleType).labeledElementDeclarations![i]))), + isOptional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, + isRest ? factory.createArrayTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i] ); } } else { for (let i = (type.target).minLength; i < Math.min(arity, tupleConstituentNodes.length); i++) { tupleConstituentNodes[i] = hasRestElement && i === arity - 1 ? - createRestTypeNode(createArrayTypeNode(tupleConstituentNodes[i])) : - createOptionalTypeNode(tupleConstituentNodes[i]); + factory.createRestTypeNode(factory.createArrayTypeNode(tupleConstituentNodes[i])) : + factory.createOptionalTypeNode(tupleConstituentNodes[i]); } } - const tupleTypeNode = setEmitFlags(createTupleTypeNode(tupleConstituentNodes), EmitFlags.SingleLine); - return (type.target).readonly ? createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode; + const tupleTypeNode = setEmitFlags(factory.createTupleTypeNode(tupleConstituentNodes), EmitFlags.SingleLine); + return (type.target).readonly ? factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode; } } if (context.encounteredError || (context.flags & NodeBuilderFlags.AllowEmptyTuple)) { - const tupleTypeNode = setEmitFlags(createTupleTypeNode([]), EmitFlags.SingleLine); - return (type.target).readonly ? createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode; + const tupleTypeNode = setEmitFlags(factory.createTupleTypeNode([]), EmitFlags.SingleLine); + return (type.target).readonly ? factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode; } context.encounteredError = true; return undefined!; // TODO: GH#18217 @@ -4679,29 +4680,53 @@ namespace ts { function appendReferenceToType(root: TypeReferenceNode | ImportTypeNode, ref: TypeReferenceNode): TypeReferenceNode | ImportTypeNode { if (isImportTypeNode(root)) { // first shift type arguments - const innerParams = root.typeArguments; - if (root.qualifier) { - (isIdentifier(root.qualifier) ? root.qualifier : root.qualifier.right).typeArguments = innerParams; + let typeArguments = root.typeArguments; + let qualifier = root.qualifier; + if (qualifier) { + if (isIdentifier(qualifier)) { + qualifier = factory.updateIdentifier(qualifier, typeArguments); + } + else { + qualifier = factory.updateQualifiedName(qualifier, + qualifier.left, + factory.updateIdentifier(qualifier.right, typeArguments)); + } } - root.typeArguments = ref.typeArguments; + typeArguments = ref.typeArguments; // then move qualifiers const ids = getAccessStack(ref); for (const id of ids) { - root.qualifier = root.qualifier ? createQualifiedName(root.qualifier, id) : id; + qualifier = qualifier ? factory.createQualifiedName(qualifier, id) : id; } - return root; + return factory.updateImportTypeNode( + root, + root.argument, + qualifier, + typeArguments, + root.isTypeOf); } else { // first shift type arguments - const innerParams = root.typeArguments; - (isIdentifier(root.typeName) ? root.typeName : root.typeName.right).typeArguments = innerParams; - root.typeArguments = ref.typeArguments; + let typeArguments = root.typeArguments; + let typeName = root.typeName; + if (isIdentifier(typeName)) { + typeName = factory.updateIdentifier(typeName, typeArguments); + } + else { + typeName = factory.updateQualifiedName(typeName, + typeName.left, + factory.updateIdentifier(typeName.right, typeArguments)); + } + typeArguments = ref.typeArguments; // then move qualifiers const ids = getAccessStack(ref); for (const id of ids) { - root.typeName = createQualifiedName(root.typeName, id); + typeName = factory.createQualifiedName(typeName, id); } - return root; + return factory.updateTypeReferenceNode( + root, + typeName, + typeArguments); } } @@ -4718,7 +4743,7 @@ namespace ts { function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] | undefined { if (checkTruncationLength(context)) { - return [createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)]; + return [factory.createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined)]; } const typeElements: TypeElement[] = []; for (const signature of resolvedType.callSignatures) { @@ -4730,16 +4755,19 @@ namespace ts { if (resolvedType.stringIndexInfo) { let indexSignature: IndexSignatureDeclaration; if (resolvedType.objectFlags & ObjectFlags.ReverseMapped) { - indexSignature = indexInfoToIndexSignatureDeclarationHelper(createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration), IndexKind.String, context); - indexSignature.type = createElidedInformationPlaceholder(context); + indexSignature = indexInfoToIndexSignatureDeclarationHelper( + createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration), + IndexKind.String, + context, + createElidedInformationPlaceholder(context)); } else { - indexSignature = indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, context); + indexSignature = indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, context, /*typeNode*/ undefined); } typeElements.push(indexSignature); } if (resolvedType.numberIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, context)); + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, context, /*typeNode*/ undefined)); } const properties = resolvedType.properties; @@ -4759,7 +4787,7 @@ namespace ts { } } if (checkTruncationLength(context) && (i + 2 < properties.length - 1)) { - typeElements.push(createPropertySignature(/*modifiers*/ undefined, `... ${properties.length - i} more ...`, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)); + typeElements.push(factory.createPropertySignature(/*modifiers*/ undefined, `... ${properties.length - i} more ...`, /*questionToken*/ undefined, /*type*/ undefined)); addPropertyToElementList(properties[properties.length - 1], context, typeElements); break; } @@ -4773,9 +4801,9 @@ namespace ts { function createElidedInformationPlaceholder(context: NodeBuilderContext) { context.approximateLength += 3; if (!(context.flags & NodeBuilderFlags.NoTruncation)) { - return createTypeReferenceNode(createIdentifier("..."), /*typeArguments*/ undefined); + return factory.createTypeReferenceNode(factory.createIdentifier("..."), /*typeArguments*/ undefined); } - return createKeywordTypeNode(SyntaxKind.AnyKeyword); + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) { @@ -4801,13 +4829,11 @@ namespace ts { context.enclosingDeclaration = saveEnclosingDeclaration; const propertyName = getPropertyNameNodeForSymbol(propertySymbol, context); context.approximateLength += (symbolName(propertySymbol).length + 1); - const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined; + const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined; if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) { const signatures = getSignaturesOfType(filterType(propertyType, t => !(t.flags & TypeFlags.Undefined)), SignatureKind.Call); for (const signature of signatures) { - const methodDeclaration = signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context); - methodDeclaration.name = propertyName; - methodDeclaration.questionToken = optionalToken; + const methodDeclaration = signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context, { name: propertyName, questionToken: optionalToken }); typeElements.push(preserveCommentsOn(methodDeclaration)); } } @@ -4819,20 +4845,19 @@ namespace ts { propertyTypeNode = createElidedInformationPlaceholder(context); } else { - propertyTypeNode = propertyType ? serializeTypeForDeclaration(context, propertyType, propertySymbol, saveEnclosingDeclaration) : createKeywordTypeNode(SyntaxKind.AnyKeyword); + propertyTypeNode = propertyType ? serializeTypeForDeclaration(context, propertyType, propertySymbol, saveEnclosingDeclaration) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } context.flags = savedFlags; - const modifiers = isReadonlySymbol(propertySymbol) ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined; + const modifiers = isReadonlySymbol(propertySymbol) ? [factory.createToken(SyntaxKind.ReadonlyKeyword)] : undefined; if (modifiers) { context.approximateLength += 9; } - const propertySignature = createPropertySignature( + const propertySignature = factory.createPropertySignature( modifiers, propertyName, optionalToken, - propertyTypeNode, - /*initializer*/ undefined); + propertyTypeNode); typeElements.push(preserveCommentsOn(propertySignature)); } @@ -4857,12 +4882,12 @@ namespace ts { if (some(types)) { if (checkTruncationLength(context)) { if (!isBareList) { - return [createTypeReferenceNode("...", /*typeArguments*/ undefined)]; + return [factory.createTypeReferenceNode("...", /*typeArguments*/ undefined)]; } else if (types.length > 2) { return [ typeToTypeNodeHelper(types[0], context), - createTypeReferenceNode(`... ${types.length - 2} more ...`, /*typeArguments*/ undefined), + factory.createTypeReferenceNode(`... ${types.length - 2} more ...`, /*typeArguments*/ undefined), typeToTypeNodeHelper(types[types.length - 1], context) ]; } @@ -4875,7 +4900,7 @@ namespace ts { for (const type of types) { i++; if (checkTruncationLength(context) && (i + 2 < types.length - 1)) { - result.push(createTypeReferenceNode(`... ${types.length - i} more ...`, /*typeArguments*/ undefined)); + result.push(factory.createTypeReferenceNode(`... ${types.length - i} more ...`, /*typeArguments*/ undefined)); const typeNode = typeToTypeNodeHelper(types[types.length - 1], context); if (typeNode) { result.push(typeNode); @@ -4922,11 +4947,11 @@ namespace ts { || !!a.aliasSymbol && a.aliasSymbol === b.aliasSymbol; } - function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, context: NodeBuilderContext): IndexSignatureDeclaration { + function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, context: NodeBuilderContext, typeNode: TypeNode | undefined): IndexSignatureDeclaration { const name = getNameFromIndexInfo(indexInfo) || "x"; - const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); + const indexerTypeNode = factory.createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); - const indexingParameter = createParameter( + const indexingParameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -4934,19 +4959,29 @@ namespace ts { /*questionToken*/ undefined, indexerTypeNode, /*initializer*/ undefined); - const typeNode = typeToTypeNodeHelper(indexInfo.type || anyType, context); + if (!typeNode) { + typeNode = typeToTypeNodeHelper(indexInfo.type || anyType, context); + } if (!indexInfo.type && !(context.flags & NodeBuilderFlags.AllowEmptyIndexInfoType)) { context.encounteredError = true; } context.approximateLength += (name.length + 4); - return createIndexSignature( + return factory.createIndexSignature( /*decorators*/ undefined, - indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined, + indexInfo.isReadonly ? [factory.createToken(SyntaxKind.ReadonlyKeyword)] : undefined, [indexingParameter], typeNode); } - function signatureToSignatureDeclarationHelper(signature: Signature, kind: SyntaxKind, context: NodeBuilderContext, privateSymbolVisitor?: (s: Symbol) => void, bundledImports?: boolean): SignatureDeclaration { + interface SignatureToSignatureDeclarationOptions { + modifiers?: readonly Modifier[]; + name?: PropertyName; + questionToken?: QuestionToken; + privateSymbolVisitor?: (s: Symbol) => void; + bundledImports?: boolean; + } + + function signatureToSignatureDeclarationHelper(signature: Signature, kind: SignatureDeclaration["kind"], context: NodeBuilderContext, options?: SignatureToSignatureDeclarationOptions): SignatureDeclaration { const suppressAny = context.flags & NodeBuilderFlags.SuppressAnyReturnType; if (suppressAny) context.flags &= ~NodeBuilderFlags.SuppressAnyReturnType; // suppress only toplevel `any`s let typeParameters: TypeParameterDeclaration[] | undefined; @@ -4958,7 +4993,7 @@ namespace ts { typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, context)); } - const parameters = getExpandedParameters(signature, /*skipUnionExpanding*/ true)[0].map(parameter => symbolToParameterDeclaration(parameter, context, kind === SyntaxKind.Constructor, privateSymbolVisitor, bundledImports)); + const parameters = getExpandedParameters(signature, /*skipUnionExpanding*/ true)[0].map(parameter => symbolToParameterDeclaration(parameter, context, kind === SyntaxKind.Constructor, options?.privateSymbolVisitor, options?.bundledImports)); if (signature.thisParameter) { const thisParameter = symbolToParameterDeclaration(signature.thisParameter, context); parameters.unshift(thisParameter); @@ -4968,25 +5003,47 @@ namespace ts { const typePredicate = getTypePredicateOfSignature(signature); if (typePredicate) { const assertsModifier = typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? - createToken(SyntaxKind.AssertsKeyword) : + factory.createToken(SyntaxKind.AssertsKeyword) : undefined; const parameterName = typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? - setEmitFlags(createIdentifier(typePredicate.parameterName), EmitFlags.NoAsciiEscaping) : - createThisTypeNode(); + setEmitFlags(factory.createIdentifier(typePredicate.parameterName), EmitFlags.NoAsciiEscaping) : + factory.createThisTypeNode(); const typeNode = typePredicate.type && typeToTypeNodeHelper(typePredicate.type, context); - returnTypeNode = createTypePredicateNodeWithModifier(assertsModifier, parameterName, typeNode); + returnTypeNode = factory.createTypePredicateNode(assertsModifier, parameterName, typeNode); } else { const returnType = getReturnTypeOfSignature(signature); if (returnType && !(suppressAny && isTypeAny(returnType))) { - returnTypeNode = serializeReturnTypeForSignature(context, returnType, signature, privateSymbolVisitor, bundledImports); + returnTypeNode = serializeReturnTypeForSignature(context, returnType, signature, options?.privateSymbolVisitor, options?.bundledImports); } else if (!suppressAny) { - returnTypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword); + returnTypeNode = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } } context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum - return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments); + + const node = + kind === SyntaxKind.CallSignature ? factory.createCallSignature(typeParameters, parameters, returnTypeNode) : + kind === SyntaxKind.ConstructSignature ? factory.createConstructSignature(typeParameters, parameters, returnTypeNode) : + kind === SyntaxKind.MethodSignature ? factory.createMethodSignature(options?.modifiers, options?.name ?? factory.createIdentifier(""), options?.questionToken, typeParameters, parameters, returnTypeNode) : + kind === SyntaxKind.MethodDeclaration ? factory.createMethodDeclaration(/*decorators*/ undefined, options?.modifiers, /*asteriskToken*/ undefined, options?.name ?? factory.createIdentifier(""), /*questionToken*/ undefined, typeParameters, parameters, returnTypeNode, /*body*/ undefined) : + kind === SyntaxKind.Constructor ? factory.createConstructorDeclaration(/*decorators*/ undefined, options?.modifiers, parameters, /*body*/ undefined) : + kind === SyntaxKind.GetAccessor ? factory.createGetAccessorDeclaration(/*decorators*/ undefined, options?.modifiers, options?.name ?? factory.createIdentifier(""), parameters, returnTypeNode, /*body*/ undefined) : + kind === SyntaxKind.SetAccessor ? factory.createSetAccessorDeclaration(/*decorators*/ undefined, options?.modifiers, options?.name ?? factory.createIdentifier(""), parameters, /*body*/ undefined) : + kind === SyntaxKind.IndexSignature ? factory.createIndexSignature(/*decorators*/ undefined, options?.modifiers, parameters, returnTypeNode) : + kind === SyntaxKind.JSDocFunctionType ? factory.createJSDocFunctionType(parameters, returnTypeNode) : + kind === SyntaxKind.FunctionType ? factory.createFunctionTypeNode(typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : + kind === SyntaxKind.ConstructorType ? factory.createConstructorTypeNode(typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : + kind === SyntaxKind.FunctionDeclaration ? factory.createFunctionDeclaration(/*decorators*/ undefined, options?.modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, /*body*/ undefined) : + kind === SyntaxKind.FunctionExpression ? factory.createFunctionExpression(options?.modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, factory.createBlock([])) : + kind === SyntaxKind.ArrowFunction ? factory.createArrowFunction(options?.modifiers, typeParameters, parameters, returnTypeNode, /*equalsGreaterThanToken*/ undefined, factory.createBlock([])) : + Debug.assertNever(kind); + + if (typeArguments) { + node.typeArguments = factory.createNodeArray(typeArguments); + } + + return node; } function typeParameterToDeclarationWithConstraint(type: TypeParameter, context: NodeBuilderContext, constraintNode: TypeNode | undefined): TypeParameterDeclaration { @@ -4996,7 +5053,7 @@ namespace ts { const defaultParameter = getDefaultFromTypeParameter(type); const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context); context.flags = savedContextFlags; - return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); + return factory.createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter(type)): TypeParameterDeclaration { @@ -5016,18 +5073,18 @@ namespace ts { } const parameterTypeNode = serializeTypeForDeclaration(context, parameterType, parameterSymbol, context.enclosingDeclaration, privateSymbolVisitor, bundledImports); - const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(getSynthesizedClone) : undefined; + const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(factory.cloneNode) : undefined; const isRest = parameterDeclaration && isRestParameter(parameterDeclaration) || getCheckFlags(parameterSymbol) & CheckFlags.RestParameter; - const dotDotDotToken = isRest ? createToken(SyntaxKind.DotDotDotToken) : undefined; + const dotDotDotToken = isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined; const name = parameterDeclaration ? parameterDeclaration.name ? - parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : - parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) : + parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(factory.cloneNode(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : + parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(factory.cloneNode(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) : cloneBindingName(parameterDeclaration.name) : symbolName(parameterSymbol) : symbolName(parameterSymbol); const isOptional = parameterDeclaration && isOptionalParameter(parameterDeclaration) || getCheckFlags(parameterSymbol) & CheckFlags.OptionalParameter; - const questionToken = isOptional ? createToken(SyntaxKind.QuestionToken) : undefined; - const parameterNode = createParameter( + const questionToken = isOptional ? factory.createToken(SyntaxKind.QuestionToken) : undefined; + const parameterNode = factory.createParameterDeclaration( /*decorators*/ undefined, modifiers, dotDotDotToken, @@ -5044,12 +5101,19 @@ namespace ts { if (context.tracker.trackSymbol && isComputedPropertyName(node) && isLateBindableName(node)) { trackComputedName(node.expression, context.enclosingDeclaration, context); } - const visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!; - const clone = nodeIsSynthesized(visited) ? visited : getSynthesizedClone(visited); - if (clone.kind === SyntaxKind.BindingElement) { - (clone).initializer = undefined; + let visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!; + if (isBindingElement(visited)) { + visited = factory.updateBindingElement( + visited, + visited.dotDotDotToken, + visited.propertyName, + visited.name, + /*initializer*/ undefined); } - return setEmitFlags(clone, EmitFlags.SingleLine | EmitFlags.NoAsciiEscaping); + if (!nodeIsSynthesized(visited)) { + visited = factory.cloneNode(visited); + } + return setEmitFlags(visited, EmitFlags.SingleLine | EmitFlags.NoAsciiEscaping); } } } @@ -5156,7 +5220,7 @@ namespace ts { let typeParameterNodes: NodeArray | undefined; const targetSymbol = getTargetSymbol(symbol); if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { - typeParameterNodes = createNodeArray(map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), tp => typeParameterToDeclaration(tp, context))); + typeParameterNodes = factory.createNodeArray(map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), tp => typeParameterToDeclaration(tp, context))); } return typeParameterNodes; } @@ -5269,7 +5333,7 @@ namespace ts { context.tracker.reportLikelyUnsafeImportRequiredError(specifier); } } - const lit = createLiteralTypeNode(createLiteral(specifier)); + const lit = factory.createLiteralTypeNode(factory.createStringLiteral(specifier)); if (context.tracker.trackExternalModuleSymbolOfImportTypeNode) context.tracker.trackExternalModuleSymbolOfImportTypeNode(chain[0]); context.approximateLength += specifier.length + 10; // specifier + import("") if (!nonRootParts || isEntityName(nonRootParts)) { @@ -5277,12 +5341,12 @@ namespace ts { const lastId = isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right; lastId.typeArguments = undefined; } - return createImportTypeNode(lit, nonRootParts as EntityName, typeParameterNodes as readonly TypeNode[], isTypeOf); + return factory.createImportTypeNode(lit, nonRootParts as EntityName, typeParameterNodes as readonly TypeNode[], isTypeOf); } else { const splitNode = getTopmostIndexedAccessType(nonRootParts); const qualifier = (splitNode.objectType as TypeReferenceNode).typeName; - return createIndexedAccessTypeNode(createImportTypeNode(lit, qualifier, typeParameterNodes as readonly TypeNode[], isTypeOf), splitNode.indexType); + return factory.createIndexedAccessTypeNode(factory.createImportTypeNode(lit, qualifier, typeParameterNodes as readonly TypeNode[], isTypeOf), splitNode.indexType); } } @@ -5291,13 +5355,13 @@ namespace ts { return entityName; // Indexed accesses can never be `typeof` } if (isTypeOf) { - return createTypeQueryNode(entityName); + return factory.createTypeQueryNode(entityName); } else { const lastId = isIdentifier(entityName) ? entityName : entityName.right; const lastTypeArgs = lastId.typeArguments; lastId.typeArguments = undefined; - return createTypeReferenceNode(entityName, lastTypeArgs as NodeArray); + return factory.createTypeReferenceNode(entityName, lastTypeArgs as NodeArray); } function createAccessFromSymbolChain(chain: Symbol[], index: number, stopper: number): EntityName | IndexedAccessTypeNode { @@ -5334,14 +5398,14 @@ namespace ts { // Should use an indexed access const LHS = createAccessFromSymbolChain(chain, index - 1, stopper); if (isIndexedAccessTypeNode(LHS)) { - return createIndexedAccessTypeNode(LHS, createLiteralTypeNode(createLiteral(symbolName))); + return factory.createIndexedAccessTypeNode(LHS, factory.createLiteralTypeNode(factory.createStringLiteral(symbolName))); } else { - return createIndexedAccessTypeNode(createTypeReferenceNode(LHS, typeParameterNodes as readonly TypeNode[]), createLiteralTypeNode(createLiteral(symbolName))); + return factory.createIndexedAccessTypeNode(factory.createTypeReferenceNode(LHS, typeParameterNodes as readonly TypeNode[]), factory.createLiteralTypeNode(factory.createStringLiteral(symbolName))); } } - const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; if (index > stopper) { @@ -5349,7 +5413,7 @@ namespace ts { if (!isEntityName(LHS)) { return Debug.fail("Impossible construct - an export of an indexed access cannot be reachable"); } - return createQualifiedName(LHS, identifier); + return factory.createQualifiedName(LHS, identifier); } return identifier; } @@ -5375,7 +5439,7 @@ namespace ts { } let result = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ true); if (!(result.kind & SyntaxKind.Identifier)) { - return createIdentifier("(Missing type parameter)"); + return factory.createIdentifier("(Missing type parameter)"); } if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) { const rawtext = result.escapedText as string; @@ -5386,7 +5450,7 @@ namespace ts { text = `${rawtext}_${i}`; } if (text !== rawtext) { - result = createIdentifier(text, result.typeArguments); + result = factory.createIdentifier(text, result.typeArguments); } (context.typeParameterNames || (context.typeParameterNames = createMap())).set("" + getTypeId(type), result); (context.typeParameterNamesByText || (context.typeParameterNamesByText = createMap())).set(result.escapedText as string, true); @@ -5418,10 +5482,10 @@ namespace ts { context.flags ^= NodeBuilderFlags.InInitialEntityName; } - const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; - return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; + return index > 0 ? factory.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; } } @@ -5444,16 +5508,16 @@ namespace ts { let firstChar = symbolName.charCodeAt(0); if (isSingleOrDoubleQuote(firstChar) && some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) { - return createLiteral(getSpecifierForModuleSymbol(symbol, context)); + return factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context)); } const canUsePropertyAccess = firstChar === CharacterCodes.hash ? symbolName.length > 1 && isIdentifierStart(symbolName.charCodeAt(1), languageVersion) : isIdentifierStart(firstChar, languageVersion); if (index === 0 || canUsePropertyAccess) { - const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; - return index > 0 ? createPropertyAccess(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier; + return index > 0 ? factory.createPropertyAccessExpression(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier; } else { if (firstChar === CharacterCodes.openBracket) { @@ -5462,17 +5526,20 @@ namespace ts { } let expression: Expression | undefined; if (isSingleOrDoubleQuote(firstChar)) { - expression = createLiteral(symbolName.substring(1, symbolName.length - 1).replace(/\\./g, s => s.substring(1))); - (expression as StringLiteral).singleQuote = firstChar === CharacterCodes.singleQuote; + expression = factory.createStringLiteral( + symbolName + .substring(1, symbolName.length - 1) + .replace(/\\./g, s => s.substring(1)), + firstChar === CharacterCodes.singleQuote); } else if (("" + +symbolName) === symbolName) { - expression = createLiteral(+symbolName); + expression = factory.createNumericLiteral(+symbolName); } if (!expression) { - expression = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + expression = setEmitFlags(factory.createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); expression.symbol = symbol; } - return createElementAccess(createExpressionFromSymbolChain(chain, index - 1), expression); + return factory.createElementAccessExpression(createExpressionFromSymbolChain(chain, index - 1), expression); } } } @@ -5495,7 +5562,7 @@ namespace ts { return fromNameType; } if (isKnownSymbol(symbol)) { - return createComputedPropertyName(createPropertyAccess(createIdentifier("Symbol"), (symbol.escapedName as string).substr(3))); + return factory.createComputedPropertyName(factory.createPropertyAccessExpression(factory.createIdentifier("Symbol"), (symbol.escapedName as string).substr(3))); } const rawName = unescapeLeadingUnderscores(symbol.escapedName); return createPropertyNameNodeForIdentifierOrLiteral(rawName, singleQuote); @@ -5508,21 +5575,23 @@ namespace ts { if (nameType.flags & TypeFlags.StringOrNumberLiteral) { const name = "" + (nameType).value; if (!isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) { - return createLiteral(name, !!singleQuote); + return factory.createStringLiteral(name, !!singleQuote); } if (isNumericLiteralName(name) && startsWith(name, "-")) { - return createComputedPropertyName(createLiteral(+name)); + return factory.createComputedPropertyName(factory.createNumericLiteral(+name)); } return createPropertyNameNodeForIdentifierOrLiteral(name); } if (nameType.flags & TypeFlags.UniqueESSymbol) { - return createComputedPropertyName(symbolToExpression((nameType).symbol, context, SymbolFlags.Value)); + return factory.createComputedPropertyName(symbolToExpression((nameType).symbol, context, SymbolFlags.Value)); } } } function createPropertyNameNodeForIdentifierOrLiteral(name: string, singleQuote?: boolean) { - return isIdentifierText(name, compilerOptions.target) ? createIdentifier(name) : createLiteral(isNumericLiteralName(name) && +name >= 0 ? +name : name, !!singleQuote); + return isIdentifierText(name, compilerOptions.target) ? factory.createIdentifier(name) : + isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : + factory.createStringLiteral(name, !!singleQuote); } function cloneNodeBuilderContext(context: NodeBuilderContext): NodeBuilderContext { @@ -5611,51 +5680,50 @@ namespace ts { if (hadError) { return undefined; } - return transformed === existing ? getMutableClone(existing) : transformed; + return transformed === existing ? setTextRange(factory.cloneNode(existing), existing) : transformed; function visitExistingNodeTreeSymbols(node: T): Node { // We don't _actually_ support jsdoc namepath types, emit `any` instead if (isJSDocAllType(node) || node.kind === SyntaxKind.JSDocNamepathType) { - return createKeywordTypeNode(SyntaxKind.AnyKeyword); + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } if (isJSDocUnknownType(node)) { - return createKeywordTypeNode(SyntaxKind.UnknownKeyword); + return factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword); } if (isJSDocNullableType(node)) { - return createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), createKeywordTypeNode(SyntaxKind.NullKeyword)]); + return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), factory.createLiteralTypeNode(factory.createNull())]); } if (isJSDocOptionalType(node)) { - return createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); + return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); } if (isJSDocNonNullableType(node)) { return visitNode(node.type, visitExistingNodeTreeSymbols); } if (isJSDocVariadicType(node)) { - return createArrayTypeNode(visitNode((node as JSDocVariadicType).type, visitExistingNodeTreeSymbols)); + return factory.createArrayTypeNode(visitNode((node as JSDocVariadicType).type, visitExistingNodeTreeSymbols)); } if (isJSDocTypeLiteral(node)) { - return createTypeLiteralNode(map(node.jsDocPropertyTags, t => { + return factory.createTypeLiteralNode(map(node.jsDocPropertyTags, t => { const name = isIdentifier(t.name) ? t.name : t.name.right; const typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(node), name.escapedText); const overrideTypeNode = typeViaParent && t.typeExpression && getTypeFromTypeNode(t.typeExpression.type) !== typeViaParent ? typeToTypeNodeHelper(typeViaParent, context) : undefined; - return createPropertySignature( + return factory.createPropertySignature( /*modifiers*/ undefined, name, - t.typeExpression && isJSDocOptionalType(t.typeExpression.type) ? createToken(SyntaxKind.QuestionToken) : undefined, - overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || createKeywordTypeNode(SyntaxKind.AnyKeyword), - /*initializer*/ undefined + t.typeExpression && isJSDocOptionalType(t.typeExpression.type) ? factory.createToken(SyntaxKind.QuestionToken) : undefined, + overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ); })); } if (isTypeReferenceNode(node) && isIdentifier(node.typeName) && node.typeName.escapedText === "") { - return setOriginalNode(createKeywordTypeNode(SyntaxKind.AnyKeyword), node); + return setOriginalNode(factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), node); } if ((isExpressionWithTypeArguments(node) || isTypeReferenceNode(node)) && isJSDocIndexSignature(node)) { - return createTypeLiteralNode([createIndexSignature( + return factory.createTypeLiteralNode([factory.createIndexSignature( /*decorators*/ undefined, /*modifiers*/ undefined, - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotdotdotToken*/ undefined, @@ -5669,9 +5737,9 @@ namespace ts { if (isJSDocFunctionType(node)) { if (isJSDocConstructSignature(node)) { let newTypeNode: TypeNode | undefined; - return createConstructorTypeNode( + return factory.createConstructorTypeNode( visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), - mapDefined(node.parameters, (p, i) => p.name && isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode = p.type, undefined) : createParameter( + mapDefined(node.parameters, (p, i) => p.name && isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode = p.type, undefined) : factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), @@ -5680,13 +5748,13 @@ namespace ts { visitNode(p.type, visitExistingNodeTreeSymbols), /*initializer*/ undefined )), - visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols) || createKeywordTypeNode(SyntaxKind.AnyKeyword) + visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ); } else { - return createFunctionTypeNode( + return factory.createFunctionTypeNode( visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), - map(node.parameters, (p, i) => createParameter( + map(node.parameters, (p, i) => factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), @@ -5695,7 +5763,7 @@ namespace ts { visitNode(p.type, visitExistingNodeTreeSymbols), /*initializer*/ undefined )), - visitNode(node.type, visitExistingNodeTreeSymbols) || createKeywordTypeNode(SyntaxKind.AnyKeyword) + visitNode(node.type, visitExistingNodeTreeSymbols) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ); } } @@ -5703,9 +5771,9 @@ namespace ts { return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node); } if (isLiteralImportTypeNode(node)) { - return updateImportTypeNode( + return factory.updateImportTypeNode( node, - updateLiteralTypeNode(node.argument, rewriteModuleSpecifier(node, node.argument.literal)), + factory.updateLiteralTypeNode(node.argument, rewriteModuleSpecifier(node, node.argument.literal)), node.qualifier, visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, isTypeNode), node.isTypeOf @@ -5728,7 +5796,7 @@ namespace ts { includePrivateSymbol?.(sym); } if (isIdentifier(node)) { - const name = sym.flags & SymbolFlags.TypeParameter ? typeParameterToName(getDeclaredTypeOfSymbol(sym), context) : getMutableClone(node); + const name = sym.flags & SymbolFlags.TypeParameter ? typeParameterToName(getDeclaredTypeOfSymbol(sym), context) : factory.cloneNode(node); name.symbol = sym; // for quickinfo, which uses identifier symbol information return setEmitFlags(setOriginalNode(name, node), EmitFlags.NoAsciiEscaping); } @@ -5742,7 +5810,7 @@ namespace ts { return visitEachChild(node, visitExistingNodeTreeSymbols, nullTransformationContext); function getEffectiveDotDotDotForParameter(p: ParameterDeclaration) { - return p.dotDotDotToken || (p.type && isJSDocVariadicType(p.type) ? createToken(SyntaxKind.DotDotDotToken) : undefined); + return p.dotDotDotToken || (p.type && isJSDocVariadicType(p.type) ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined); } function rewriteModuleSpecifier(parent: ImportTypeNode, lit: StringLiteral) { @@ -5757,7 +5825,7 @@ namespace ts { getCommonSourceDirectory: () => context.tracker.moduleResolverHost!.getCommonSourceDirectory() }; const newName = getResolvedExternalModuleName(resolverHost, targetFile); - return createLiteral(newName); + return factory.createStringLiteral(newName); } } } @@ -5775,8 +5843,8 @@ namespace ts { } function symbolTableToDeclarationStatements(symbolTable: SymbolTable, context: NodeBuilderContext, bundled?: boolean): Statement[] { - const serializePropertySymbolForClass = makeSerializePropertySymbol(createProperty, SyntaxKind.MethodDeclaration, /*useAcessors*/ true); - const serializePropertySymbolForInterfaceWorker = makeSerializePropertySymbol((_decorators, mods, name, question, type, initializer) => createPropertySignature(mods, name, question, type, initializer), SyntaxKind.MethodSignature, /*useAcessors*/ false); + const serializePropertySymbolForClass = makeSerializePropertySymbol(factory.createPropertyDeclaration, SyntaxKind.MethodDeclaration, /*useAcessors*/ true); + const serializePropertySymbolForInterfaceWorker = makeSerializePropertySymbol((_decorators, mods, name, question, type) => factory.createPropertySignature(mods, name, question, type), SyntaxKind.MethodSignature, /*useAcessors*/ false); // TODO: Use `setOriginalNode` on original declaration names where possible so these declarations see some kind of // declaration mapping @@ -5843,30 +5911,43 @@ namespace ts { function flattenExportAssignedNamespace(statements: Statement[]) { const exportAssignment = find(statements, isExportAssignment); - const ns = find(statements, isModuleDeclaration); + const nsIndex = findIndex(statements, isModuleDeclaration); + let ns = nsIndex !== -1 ? statements[nsIndex] as ModuleDeclaration : undefined; if (ns && exportAssignment && exportAssignment.isExportEquals && isIdentifier(exportAssignment.expression) && isIdentifier(ns.name) && idText(ns.name) === idText(exportAssignment.expression) && ns.body && isModuleBlock(ns.body)) { // Pass 0: Correct situations where a module has both an `export = ns` and multiple top-level exports by stripping the export modifiers from // the top-level exports and exporting them in the targeted ns, as can occur when a js file has both typedefs and `module.export` assignments const excessExports = filter(statements, s => !!(getEffectiveModifierFlags(s) & ModifierFlags.Export)); + const name = ns.name; + let body = ns.body; if (length(excessExports)) { - ns.body.statements = createNodeArray([...ns.body.statements, createExportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - createNamedExports(map(flatMap(excessExports, e => getNamesOfDeclaration(e)), id => createExportSpecifier(/*alias*/ undefined, id))), - /*moduleSpecifier*/ undefined - )]); + ns = factory.updateModuleDeclaration( + ns, + ns.decorators, + ns.modifiers, + ns.name, + body = factory.updateModuleBlock( + body, + factory.createNodeArray([...ns.body.statements, factory.createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*isTypeOnly*/ false, + factory.createNamedExports(map(flatMap(excessExports, e => getNamesOfDeclaration(e)), id => factory.createExportSpecifier(/*alias*/ undefined, id))), + /*moduleSpecifier*/ undefined + )]) + ) + ); + statements = [...statements.slice(0, nsIndex), ns, ...statements.slice(nsIndex + 1)]; } - // Pass 1: Flatten `export namespace _exports {} export = _exports;` so long as the `export=` only points at a single namespace declaration - if (!find(statements, s => s !== ns && nodeHasName(s, ns.name as Identifier))) { + if (!find(statements, s => s !== ns && nodeHasName(s, name))) { results = []; // If the namespace contains no export assignments or declarations, and no declarations flagged with `export`, then _everything_ is exported - // to respect this as the top level, we need to add an `export` modifier to everything - const mixinExportFlag = !some(ns.body.statements, s => hasSyntacticModifier(s, ModifierFlags.Export) || isExportAssignment(s) || isExportDeclaration(s)); - forEach(ns.body.statements, s => { + const mixinExportFlag = !some(body.statements, s => hasSyntacticModifier(s, ModifierFlags.Export) || isExportAssignment(s) || isExportDeclaration(s)); + forEach(body.statements, s => { addResult(s, mixinExportFlag ? ModifierFlags.Export : ModifierFlags.None); // Recalculates the ambient (and export, if applicable from above) flag }); statements = [...filter(statements, s => s !== ns && s !== exportAssignment), ...results]; @@ -5880,10 +5961,11 @@ namespace ts { const exports = filter(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && isNamedExports(d.exportClause)) as ExportDeclaration[]; if (length(exports) > 1) { const nonExports = filter(statements, d => !isExportDeclaration(d) || !!d.moduleSpecifier || !d.exportClause); - statements = [...nonExports, createExportDeclaration( + statements = [...nonExports, factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports(flatMap(exports, e => cast(e.exportClause, isNamedExports).elements)), + /*isTypeOnly*/ false, + factory.createNamedExports(flatMap(exports, e => cast(e.exportClause, isNamedExports).elements)), /*moduleSpecifier*/ undefined )]; } @@ -5897,10 +5979,11 @@ namespace ts { // remove group members from statements and then merge group members and add back to statements statements = [ ...filter(statements, s => group.indexOf(s as ExportDeclaration) === -1), - createExportDeclaration( + factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports(flatMap(group, e => cast(e.exportClause, isNamedExports).elements)), + /*isTypeOnly*/ false, + factory.createNamedExports(flatMap(group, e => cast(e.exportClause, isNamedExports).elements)), group[0].moduleSpecifier ) ]; @@ -5913,27 +5996,40 @@ namespace ts { function inlineExportModifiers(statements: Statement[]) { // Pass 3: Move all `export {}`'s to `export` modifiers where possible - const exportDecl = find(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause) as ExportDeclaration | undefined; - if (exportDecl && exportDecl.exportClause && isNamedExports(exportDecl.exportClause)) { + const index = findIndex(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && isNamedExports(d.exportClause)); + if (index >= 0) { + const exportDecl = statements[index] as ExportDeclaration & { readonly exportClause: NamedExports }; const replacements = mapDefined(exportDecl.exportClause.elements, e => { if (!e.propertyName) { // export {name} - look thru `statements` for `name`, and if all results can take an `export` modifier, do so and filter it - const associated = filter(statements, s => nodeHasName(s, e.name)); - if (length(associated) && every(associated, canHaveExportModifier)) { - forEach(associated, addExportModifier); + const indices = indicesOf(statements); + const associatedIndices = filter(indices, i => nodeHasName(statements[i], e.name)); + if (length(associatedIndices) && every(associatedIndices, i => canHaveExportModifier(statements[i]))) { + for (const index of associatedIndices) { + statements[index] = addExportModifier(statements[index] as Extract); + } return undefined; } } return e; }); if (!length(replacements)) { - // all clauses removed, filter the export declaration - statements = filter(statements, s => s !== exportDecl); + // all clauses removed, remove the export declaration + orderedRemoveItemAt(statements, index); } else { // some items filtered, others not - update the export declaration - // (mutating because why not, we're building a whole new tree here anyway) - exportDecl.exportClause.elements = createNodeArray(replacements); + statements[index] = factory.updateExportDeclaration( + exportDecl, + exportDecl.decorators, + exportDecl.modifiers, + exportDecl.isTypeOnly, + factory.updateNamedExports( + exportDecl.exportClause, + replacements + ), + exportDecl.moduleSpecifier + ); } } return statements; @@ -5949,12 +6045,12 @@ namespace ts { if (enclosingDeclaration && ((isSourceFile(enclosingDeclaration) && isExternalOrCommonJsModule(enclosingDeclaration)) || isModuleDeclaration(enclosingDeclaration)) && (!some(statements, isExternalModuleIndicator) || (!hasScopeMarker(statements) && some(statements, needsScopeMarker)))) { - statements.push(createEmptyExports()); + statements.push(createEmptyExports(factory)); } return statements; } - function canHaveExportModifier(node: Statement) { + function canHaveExportModifier(node: Statement): node is Extract { return isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || @@ -5964,17 +6060,14 @@ namespace ts { isTypeDeclaration(node); } - function addExportModifier(statement: Statement) { - const flags = (getEffectiveModifierFlags(statement) | ModifierFlags.Export) & ~ModifierFlags.Ambient; - statement.modifiers = createNodeArray(createModifiersFromModifierFlags(flags)); - statement.modifierFlagsCache = 0; + function addExportModifier(node: Extract) { + const flags = (getEffectiveModifierFlags(node) | ModifierFlags.Export) & ~ModifierFlags.Ambient; + return factory.updateModifiers(node, flags); } - function removeExportModifier(statement: Statement) { - const flags = getEffectiveModifierFlags(statement) & ~ModifierFlags.Export; - statement.modifiers = createNodeArray(createModifiersFromModifierFlags(flags)); - statement.modifierFlagsCache = 0; - return statement; + function removeExportModifier(node: Extract) { + const flags = getEffectiveModifierFlags(node) & ~ModifierFlags.Export; + return factory.updateModifiers(node, flags); } function visitSymbolTable(symbolTable: SymbolTable, suppressNewPrivateContext?: boolean, propertyAsAlias?: boolean) { @@ -6086,8 +6179,8 @@ namespace ts { if (textRange && isVariableDeclarationList(textRange.parent) && textRange.parent.declarations.length === 1) { textRange = textRange.parent.parent; } - const statement = setTextRange(createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([ - createVariableDeclaration(name, serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled)) + const statement = setTextRange(factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([ + factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled)) ], flags)), textRange); addResult(statement, name !== localName ? modifierFlags & ~ModifierFlags.Export : modifierFlags); if (name !== localName && !isPrivate) { @@ -6113,10 +6206,11 @@ namespace ts { // ``` // To create an export named `g` that does _not_ shadow the local `g` addResult( - createExportDeclaration( + factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports([createExportSpecifier(name, localName)]) + /*isTypeOnly*/ false, + factory.createNamedExports([factory.createExportSpecifier(name, localName)]) ), ModifierFlags.None ); @@ -6158,17 +6252,18 @@ namespace ts { for (const node of symbol.declarations) { const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier!); if (!resolvedModule) continue; - addResult(createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*exportClause*/ undefined, createLiteral(getSpecifierForModuleSymbol(resolvedModule, context))), ModifierFlags.None); + addResult(factory.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, /*exportClause*/ undefined, factory.createStringLiteral(getSpecifierForModuleSymbol(resolvedModule, context))), ModifierFlags.None); } } if (needsPostExportDefault) { - addResult(createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportAssignment*/ false, createIdentifier(getInternalSymbolName(symbol, symbolName))), ModifierFlags.None); + addResult(factory.createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportAssignment*/ false, factory.createIdentifier(getInternalSymbolName(symbol, symbolName))), ModifierFlags.None); } else if (needsExportDeclaration) { - addResult(createExportDeclaration( + addResult(factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports([createExportSpecifier(getInternalSymbolName(symbol, symbolName), symbolName)]) + /*isTypeOnly*/ false, + factory.createNamedExports([factory.createExportSpecifier(getInternalSymbolName(symbol, symbolName), symbolName)]) ), ModifierFlags.None); } } @@ -6186,29 +6281,29 @@ namespace ts { } // Prepends a `declare` and/or `export` modifier if the context requires it, and then adds `node` to `result` and returns `node` - // Note: This _mutates_ `node` without using `updateNode` - the assumption being that all nodes should be manufactured fresh by the node builder function addResult(node: Statement, additionalModifierFlags: ModifierFlags) { - let newModifierFlags: ModifierFlags = ModifierFlags.None; - if (additionalModifierFlags & ModifierFlags.Export && - context.enclosingDeclaration && - (isExportingScope(context.enclosingDeclaration) || isModuleDeclaration(context.enclosingDeclaration)) && - canHaveExportModifier(node) - ) { - // Classes, namespaces, variables, functions, interfaces, and types should all be `export`ed in a module context if not private - newModifierFlags |= ModifierFlags.Export; - } - if (addingDeclare && !(newModifierFlags & ModifierFlags.Export) && - (!context.enclosingDeclaration || !(context.enclosingDeclaration.flags & NodeFlags.Ambient)) && - (isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || isClassDeclaration(node) || isModuleDeclaration(node))) { - // Classes, namespaces, variables, enums, and functions all need `declare` modifiers to be valid in a declaration file top-level scope - newModifierFlags |= ModifierFlags.Ambient; - } - if ((additionalModifierFlags & ModifierFlags.Default) && (isClassDeclaration(node) || isInterfaceDeclaration(node) || isFunctionDeclaration(node))) { - newModifierFlags |= ModifierFlags.Default; - } - if (newModifierFlags) { - node.modifiers = createNodeArray(createModifiersFromModifierFlags(newModifierFlags | getEffectiveModifierFlags(node))); - node.modifierFlagsCache = 0; // Reset computed flags cache + if (canHaveModifiers(node)) { + let newModifierFlags: ModifierFlags = ModifierFlags.None; + if (additionalModifierFlags & ModifierFlags.Export && + context.enclosingDeclaration && + (isExportingScope(context.enclosingDeclaration) || isModuleDeclaration(context.enclosingDeclaration)) && + canHaveExportModifier(node) + ) { + // Classes, namespaces, variables, functions, interfaces, and types should all be `export`ed in a module context if not private + newModifierFlags |= ModifierFlags.Export; + } + if (addingDeclare && !(newModifierFlags & ModifierFlags.Export) && + (!context.enclosingDeclaration || !(context.enclosingDeclaration.flags & NodeFlags.Ambient)) && + (isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || isClassDeclaration(node) || isModuleDeclaration(node))) { + // Classes, namespaces, variables, enums, and functions all need `declare` modifiers to be valid in a declaration file top-level scope + newModifierFlags |= ModifierFlags.Ambient; + } + if ((additionalModifierFlags & ModifierFlags.Default) && (isClassDeclaration(node) || isInterfaceDeclaration(node) || isFunctionDeclaration(node))) { + newModifierFlags |= ModifierFlags.Default; + } + if (newModifierFlags) { + node = factory.updateModifiers(node, newModifierFlags | getEffectiveModifierFlags(node)); + } } results.push(node); } @@ -6222,7 +6317,7 @@ namespace ts { const oldFlags = context.flags; context.flags |= NodeBuilderFlags.InTypeAlias; addResult(setSyntheticLeadingComments( - createTypeAliasDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, typeToTypeNodeHelper(aliasType, context)), + factory.createTypeAliasDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, typeToTypeNodeHelper(aliasType, context)), !commentText ? [] : [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }] ), modifierFlags); context.flags = oldFlags; @@ -6239,8 +6334,8 @@ namespace ts { const constructSignatures = serializeSignatures(SignatureKind.Construct, interfaceType, baseType, SyntaxKind.ConstructSignature) as ConstructSignatureDeclaration[]; const indexSignatures = serializeIndexSignatures(interfaceType, baseType); - const heritageClauses = !length(baseTypes) ? undefined : [createHeritageClause(SyntaxKind.ExtendsKeyword, mapDefined(baseTypes, b => trySerializeAsTypeReference(b, SymbolFlags.Value)))]; - addResult(createInterfaceDeclaration( + const heritageClauses = !length(baseTypes) ? undefined : [factory.createHeritageClause(SyntaxKind.ExtendsKeyword, mapDefined(baseTypes, b => trySerializeAsTypeReference(b, SymbolFlags.Value)))]; + addResult(factory.createInterfaceDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), @@ -6274,10 +6369,11 @@ namespace ts { if (length(mergedMembers)) { const containingFile = getSourceFileOfNode(context.enclosingDeclaration); const localName = getInternalSymbolName(symbol, symbolName); - const nsBody = createModuleBlock([createExportDeclaration( + const nsBody = factory.createModuleBlock([factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports(mapDefined(filter(mergedMembers, n => n.escapedName !== InternalSymbolName.ExportEquals), s => { + /*isTypeOnly*/ false, + factory.createNamedExports(mapDefined(filter(mergedMembers, n => n.escapedName !== InternalSymbolName.ExportEquals), s => { const name = unescapeLeadingUnderscores(s.escapedName); const localName = getInternalSymbolName(s, name); const aliasDecl = s.declarations && getDeclarationOfAliasSymbol(s); @@ -6288,13 +6384,13 @@ namespace ts { const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true); includePrivateSymbol(target || s); const targetName = target ? getInternalSymbolName(target, unescapeLeadingUnderscores(target.escapedName)) : localName; - return createExportSpecifier(name === targetName ? undefined : targetName, name); + return factory.createExportSpecifier(name === targetName ? undefined : targetName, name); })) )]); - addResult(createModuleDeclaration( + addResult(factory.createModuleDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createIdentifier(localName), + factory.createIdentifier(localName), nsBody, NodeFlags.Namespace ), ModifierFlags.None); @@ -6302,17 +6398,19 @@ namespace ts { } function serializeEnum(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) { - addResult(createEnumDeclaration( + addResult(factory.createEnumDeclaration( /*decorators*/ undefined, - createModifiersFromModifierFlags(isConstEnumSymbol(symbol) ? ModifierFlags.Const : 0), + factory.createModifiersFromModifierFlags(isConstEnumSymbol(symbol) ? ModifierFlags.Const : 0), getInternalSymbolName(symbol, symbolName), map(filter(getPropertiesOfType(getTypeOfSymbol(symbol)), p => !!(p.flags & SymbolFlags.EnumMember)), p => { // TODO: Handle computed names // I hate that to get the initialized value we need to walk back to the declarations here; but there's no // other way to get the possible const value of an enum member that I'm aware of, as the value is cached // _on the declaration_, not on the declaration's symbol... - const initializedValue = p.declarations && p.declarations[0] && isEnumMember(p.declarations[0]) && getConstantValue(p.declarations[0] as EnumMember); - return createEnumMember(unescapeLeadingUnderscores(p.escapedName), initializedValue === undefined ? undefined : createLiteral(initializedValue)); + const initializedValue = p.declarations && p.declarations[0] && isEnumMember(p.declarations[0]) ? getConstantValue(p.declarations[0] as EnumMember) : undefined; + return factory.createEnumMember(unescapeLeadingUnderscores(p.escapedName), initializedValue === undefined ? undefined : + typeof initializedValue === "string" ? factory.createStringLiteral(initializedValue) : + factory.createNumericLiteral(initializedValue)); }) ), modifierFlags); } @@ -6321,8 +6419,7 @@ namespace ts { const signatures = getSignaturesOfType(type, SignatureKind.Call); for (const sig of signatures) { // Each overload becomes a separate function declaration, in order - const decl = signatureToSignatureDeclarationHelper(sig, SyntaxKind.FunctionDeclaration, context, includePrivateSymbol, bundled) as FunctionDeclaration; - decl.name = createIdentifier(localName); + const decl = signatureToSignatureDeclarationHelper(sig, SyntaxKind.FunctionDeclaration, context, { name: factory.createIdentifier(localName), privateSymbolVisitor: includePrivateSymbol, bundledImports: bundled }) as FunctionDeclaration; // for expressions assigned to `var`s, use the `var` as the text range addResult(setTextRange(decl, sig.declaration && isVariableDeclaration(sig.declaration.parent) && sig.declaration.parent.parent || sig.declaration), modifierFlags); } @@ -6357,11 +6454,12 @@ namespace ts { // emit akin to the above would be needed. // Add a namespace - const fakespace = createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createIdentifier(localName), createModuleBlock([]), NodeFlags.Namespace); - fakespace.flags ^= NodeFlags.Synthesized; // unset synthesized so it is usable as an enclosing declaration - fakespace.parent = enclosingDeclaration as SourceFile | NamespaceDeclaration; + // Create namespace as non-synthetic so it is usable as an enclosing declaration + let fakespace = parseNodeFactory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createIdentifier(localName), factory.createModuleBlock([]), NodeFlags.Namespace); + setParent(fakespace, enclosingDeclaration as SourceFile | NamespaceDeclaration); fakespace.locals = createSymbolTable(props); fakespace.symbol = props[0].parent!; + const oldResults = results; results = []; const oldAddingDeclare = addingDeclare; @@ -6375,17 +6473,20 @@ namespace ts { addingDeclare = oldAddingDeclare; const declarations = results; results = oldResults; - fakespace.flags ^= NodeFlags.Synthesized; // reset synthesized - fakespace.parent = undefined!; - fakespace.locals = undefined!; - fakespace.symbol = undefined!; - const defaultReplaced = map(declarations, d => isExportAssignment(d) && !d.isExportEquals && isIdentifier(d.expression) ? createExportDeclaration( + // replace namespace with synthetic version + const defaultReplaced = map(declarations, d => isExportAssignment(d) && !d.isExportEquals && isIdentifier(d.expression) ? factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports([createExportSpecifier(d.expression, createIdentifier(InternalSymbolName.Default))]) + /*isTypeOnly*/ false, + factory.createNamedExports([factory.createExportSpecifier(d.expression, factory.createIdentifier(InternalSymbolName.Default))]) ) : d); const exportModifierStripped = every(defaultReplaced, d => hasSyntacticModifier(d, ModifierFlags.Export)) ? map(defaultReplaced, removeExportModifier) : defaultReplaced; - fakespace.body = createModuleBlock(exportModifierStripped); + fakespace = factory.updateModuleDeclaration( + fakespace, + fakespace.decorators, + fakespace.modifiers, + fakespace.name, + factory.createModuleBlock(exportModifierStripped)); addResult(fakespace, modifierFlags); // namespaces can never be default exported } } @@ -6406,8 +6507,8 @@ namespace ts { ? getBaseConstructorTypeOfClass(staticType as InterfaceType) : anyType; const heritageClauses = [ - ...!length(baseTypes) ? [] : [createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))], - ...!length(implementsExpressions) ? [] : [createHeritageClause(SyntaxKind.ImplementsKeyword, implementsExpressions)] + ...!length(baseTypes) ? [] : [factory.createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))], + ...!length(implementsExpressions) ? [] : [factory.createHeritageClause(SyntaxKind.ImplementsKeyword, implementsExpressions)] ]; const symbolProps = getNonInterhitedProperties(classType, baseTypes, getPropertiesOfType(classType)); const publicSymbolProps = filter(symbolProps, s => { @@ -6426,10 +6527,10 @@ namespace ts { }); // Boil down all private properties into a single one. const privateProperties = hasPrivateIdentifier ? - [createProperty( + [factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createPrivateIdentifier("#private"), + factory.createPrivateIdentifier("#private"), /*questionOrExclamationToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined, @@ -6449,16 +6550,10 @@ namespace ts { isInJSFile(symbol.valueDeclaration) && !some(getSignaturesOfType(staticType, SignatureKind.Construct)); const constructors = isNonConstructableClassLikeInJsFile ? - [createConstructor(/*decorators*/ undefined, createModifiersFromModifierFlags(ModifierFlags.Private), [], /*body*/ undefined)] : + [factory.createConstructorDeclaration(/*decorators*/ undefined, factory.createModifiersFromModifierFlags(ModifierFlags.Private), [], /*body*/ undefined)] : serializeSignatures(SignatureKind.Construct, staticType, baseTypes[0], SyntaxKind.Constructor) as ConstructorDeclaration[]; - for (const c of constructors) { - // A constructor's return type and type parameters are supposed to be controlled by the enclosing class declaration - // `signatureToSignatureDeclarationHelper` appends them regardless, so for now we delete them here - c.type = undefined; - c.typeParameters = undefined; - } const indexSignatures = serializeIndexSignatures(classType, baseTypes[0]); - addResult(setTextRange(createClassDeclaration( + addResult(setTextRange(factory.createClassDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, localName, @@ -6490,59 +6585,63 @@ namespace ts { // Could be a local `import localName = ns.member` or // an external `import localName = require("whatever")` const isLocalImport = !(target.flags & SymbolFlags.ValueModule); - addResult(createImportEqualsDeclaration( + addResult(factory.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createIdentifier(localName), + factory.createIdentifier(localName), isLocalImport ? symbolToName(target, context, SymbolFlags.All, /*expectsIdentifier*/ false) - : createExternalModuleReference(createLiteral(getSpecifierForModuleSymbol(symbol, context))) + : factory.createExternalModuleReference(factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context))) ), isLocalImport ? modifierFlags : ModifierFlags.None); break; case SyntaxKind.NamespaceExportDeclaration: // export as namespace foo // TODO: Not part of a file's local or export symbol tables // Is bound into file.symbol.globalExports instead, which we don't currently traverse - addResult(createNamespaceExportDeclaration(idText((node as NamespaceExportDeclaration).name)), ModifierFlags.None); + addResult(factory.createNamespaceExportDeclaration(idText((node as NamespaceExportDeclaration).name)), ModifierFlags.None); break; case SyntaxKind.ImportClause: - addResult(createImportDeclaration( + addResult(factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause(createIdentifier(localName), /*namedBindings*/ undefined), + factory.createImportClause(/*isTypeOnly*/ false, factory.createIdentifier(localName), /*namedBindings*/ undefined), // We use `target.parent || target` below as `target.parent` is unset when the target is a module which has been export assigned // And then made into a default by the `esModuleInterop` or `allowSyntheticDefaultImports` flag // In such cases, the `target` refers to the module itself already - createLiteral(getSpecifierForModuleSymbol(target.parent || target, context)) + factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)) ), ModifierFlags.None); break; case SyntaxKind.NamespaceImport: - addResult(createImportDeclaration( + addResult(factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause(/*importClause*/ undefined, createNamespaceImport(createIdentifier(localName))), - createLiteral(getSpecifierForModuleSymbol(target, context)) + factory.createImportClause(/*isTypeOnly*/ false, /*importClause*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName))), + factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)) ), ModifierFlags.None); break; case SyntaxKind.NamespaceExport: - addResult(createExportDeclaration( + addResult(factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamespaceExport(createIdentifier(localName)), - createLiteral(getSpecifierForModuleSymbol(target, context)) + /*isTypeOnly*/ false, + factory.createNamespaceExport(factory.createIdentifier(localName)), + factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)) ), ModifierFlags.None); break; case SyntaxKind.ImportSpecifier: - addResult(createImportDeclaration( + addResult(factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause(/*importClause*/ undefined, createNamedImports([ - createImportSpecifier( - localName !== verbatimTargetName ? createIdentifier(verbatimTargetName) : undefined, - createIdentifier(localName) - ) - ])), - createLiteral(getSpecifierForModuleSymbol(target.parent || target, context)) + factory.createImportClause( + /*isTypeOnly*/ false, + /*importClause*/ undefined, + factory.createNamedImports([ + factory.createImportSpecifier( + localName !== verbatimTargetName ? factory.createIdentifier(verbatimTargetName) : undefined, + factory.createIdentifier(localName) + ) + ])), + factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)) ), ModifierFlags.None); break; case SyntaxKind.ExportSpecifier: @@ -6554,7 +6653,7 @@ namespace ts { serializeExportSpecifier( unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, - specifier && isStringLiteralLike(specifier) ? createLiteral(specifier.text) : undefined + specifier && isStringLiteralLike(specifier) ? factory.createStringLiteral(specifier.text) : undefined ); break; case SyntaxKind.ExportAssignment: @@ -6578,10 +6677,11 @@ namespace ts { } function serializeExportSpecifier(localName: string, targetName: string, specifier?: Expression) { - addResult(createExportDeclaration( + addResult(factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports([createExportSpecifier(localName !== targetName ? targetName : undefined, localName)]), + /*isTypeOnly*/ false, + factory.createNamedExports([factory.createExportSpecifier(localName !== targetName ? targetName : undefined, localName)]), specifier ), ModifierFlags.None); } @@ -6623,7 +6723,7 @@ namespace ts { const oldTrack = context.tracker.trackSymbol; context.tracker.trackSymbol = noop; if (isExportAssignment) { - results.push(createExportAssignment( + results.push(factory.createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, isExportEquals, @@ -6641,10 +6741,10 @@ namespace ts { else { // serialize as `import _Ref = t.arg.et; export { _Ref as name }` const varName = getUnusedName(name, symbol); - addResult(createImportEqualsDeclaration( + addResult(factory.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createIdentifier(varName), + factory.createIdentifier(varName), symbolToName(target, context, SymbolFlags.All, /*expectsIdentifier*/ false) ), ModifierFlags.None); serializeExportSpecifier(name, varName); @@ -6664,17 +6764,17 @@ namespace ts { serializeAsFunctionNamespaceMerge(typeToSerialize, symbol, varName, isExportAssignment ? ModifierFlags.None : ModifierFlags.Export); } else { - const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([ - createVariableDeclaration(varName, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled)) + const statement = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([ + factory.createVariableDeclaration(varName, /*exclamationToken*/ undefined, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled)) ], NodeFlags.Const)); addResult(statement, name === varName ? ModifierFlags.Export : ModifierFlags.None); } if (isExportAssignment) { - results.push(createExportAssignment( + results.push(factory.createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, isExportEquals, - createIdentifier(varName) + factory.createIdentifier(varName) )); return true; } @@ -6710,7 +6810,7 @@ namespace ts { questionOrExclamationToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined - ) => T, methodKind: SyntaxKind, useAccessors: true): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]); + ) => T, methodKind: SignatureDeclaration["kind"], useAccessors: true): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]); function makeSerializePropertySymbol(createProperty: ( decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, @@ -6718,7 +6818,7 @@ namespace ts { questionOrExclamationToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined - ) => T, methodKind: SyntaxKind, useAccessors: false): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | T[]); + ) => T, methodKind: SignatureDeclaration["kind"], useAccessors: false): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | T[]); function makeSerializePropertySymbol(createProperty: ( decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, @@ -6726,8 +6826,8 @@ namespace ts { questionOrExclamationToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined - ) => T, methodKind: SyntaxKind, useAccessors: boolean): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]) { - return function serializePropertySymbol(p: Symbol, isStatic: boolean, baseType: Type | undefined) { + ) => T, methodKind: SignatureDeclaration["kind"], useAccessors: boolean): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | AccessorDeclaration | (T | AccessorDeclaration)[]) { + return function serializePropertySymbol(p: Symbol, isStatic: boolean, baseType: Type | undefined): (T | AccessorDeclaration | (T | AccessorDeclaration)[]) { const modifierFlags = getDeclarationModifierFlagsFromSymbol(p); const isPrivate = !!(modifierFlags & ModifierFlags.Private); if (isStatic && (p.flags & (SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias))) { @@ -6748,11 +6848,11 @@ namespace ts { if (p.flags & SymbolFlags.Accessor && useAccessors) { const result: AccessorDeclaration[] = []; if (p.flags & SymbolFlags.SetAccessor) { - result.push(setTextRange(createSetAccessor( + result.push(setTextRange(factory.createSetAccessorDeclaration( /*decorators*/ undefined, - createModifiersFromModifierFlags(flag), + factory.createModifiersFromModifierFlags(flag), name, - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -6765,9 +6865,9 @@ namespace ts { } if (p.flags & SymbolFlags.GetAccessor) { const isPrivate = modifierFlags & ModifierFlags.Private; - result.push(setTextRange(createGetAccessor( + result.push(setTextRange(factory.createGetAccessorDeclaration( /*decorators*/ undefined, - createModifiersFromModifierFlags(flag), + factory.createModifiersFromModifierFlags(flag), name, [], isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), @@ -6781,9 +6881,9 @@ namespace ts { else if (p.flags & (SymbolFlags.Property | SymbolFlags.Variable)) { return setTextRange(createProperty( /*decorators*/ undefined, - createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | flag), + factory.createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | flag), name, - p.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined, + p.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), // TODO: https://github.com/microsoft/TypeScript/pull/32372#discussion_r328386357 // interface members can't have initializers, however class members _can_ @@ -6796,9 +6896,9 @@ namespace ts { if (flag & ModifierFlags.Private) { return setTextRange(createProperty( /*decorators*/ undefined, - createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | flag), + factory.createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | flag), name, - p.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined, + p.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, /*type*/ undefined, /*initializer*/ undefined ), find(p.declarations, isFunctionLikeDeclaration) || signatures[0] && signatures[0].declaration || p.declarations[0]); @@ -6807,14 +6907,16 @@ namespace ts { const results = []; for (const sig of signatures) { // Each overload becomes a separate method declaration, in order - const decl = signatureToSignatureDeclarationHelper(sig, methodKind, context) as MethodDeclaration; - decl.name = name; // TODO: Clone - if (flag) { - decl.modifiers = createNodeArray(createModifiersFromModifierFlags(flag)); - } - if (p.flags & SymbolFlags.Optional) { - decl.questionToken = createToken(SyntaxKind.QuestionToken); - } + const decl = signatureToSignatureDeclarationHelper( + sig, + methodKind, + context, + { + name, + questionToken: p.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, + modifiers: flag ? factory.createModifiersFromModifierFlags(flag) : undefined + } + ); results.push(setTextRange(decl, sig.declaration)); } return results as unknown as T[]; @@ -6828,7 +6930,7 @@ namespace ts { return serializePropertySymbolForInterfaceWorker(p, /*isStatic*/ false, baseType); } - function serializeSignatures(kind: SignatureKind, input: Type, baseType: Type | undefined, outputKind: SyntaxKind) { + function serializeSignatures(kind: SignatureKind, input: Type, baseType: Type | undefined, outputKind: SignatureDeclaration["kind"]) { const signatures = getSignaturesOfType(input, kind); if (kind === SignatureKind.Construct) { if (!baseType && every(signatures, s => length(s.parameters) === 0)) { @@ -6860,9 +6962,9 @@ namespace ts { } } if (privateProtected) { - return [setTextRange(createConstructor( + return [setTextRange(factory.createConstructorDeclaration( /*decorators*/ undefined, - createModifiersFromModifierFlags(privateProtected), + factory.createModifiersFromModifierFlags(privateProtected), /*parameters*/ [], /*body*/ undefined, ), signatures[0].declaration)]; @@ -6891,7 +6993,7 @@ namespace ts { } } } - results.push(indexInfoToIndexSignatureDeclarationHelper(info, type, context)); + results.push(indexInfoToIndexSignatureDeclarationHelper(info, type, context, /*typeNode*/ undefined)); } } return results; @@ -6903,11 +7005,11 @@ namespace ts { return ref; } const tempName = getUnusedName(`${rootName}_base`); - const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([ - createVariableDeclaration(tempName, typeToTypeNodeHelper(staticType, context)) + const statement = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([ + factory.createVariableDeclaration(tempName, /*exclamationToken*/ undefined, typeToTypeNodeHelper(staticType, context)) ], NodeFlags.Const)); addResult(statement, ModifierFlags.None); - return createExpressionWithTypeArguments(/*typeArgs*/ undefined, createIdentifier(tempName)); + return factory.createExpressionWithTypeArguments(factory.createIdentifier(tempName), /*typeArgs*/ undefined); } function trySerializeAsTypeReference(t: Type, flags: SymbolFlags) { @@ -6924,7 +7026,7 @@ namespace ts { reference = symbolToExpression(t.symbol, context, SymbolFlags.Type); } if (reference) { - return createExpressionWithTypeArguments(typeArgs, reference); + return factory.createExpressionWithTypeArguments(reference, typeArgs); } } @@ -6934,7 +7036,7 @@ namespace ts { return ref; } if (t.symbol) { - return createExpressionWithTypeArguments(/*typeArgs*/ undefined, symbolToExpression(t.symbol, context, SymbolFlags.Type)); + return factory.createExpressionWithTypeArguments(symbolToExpression(t.symbol, context, SymbolFlags.Type), /*typeArgs*/ undefined); } } @@ -6994,9 +7096,9 @@ namespace ts { return writer ? typePredicateToStringWorker(writer).getText() : usingSingleLineStringWriter(typePredicateToStringWorker); function typePredicateToStringWorker(writer: EmitTextWriter) { - const predicate = createTypePredicateNodeWithModifier( - typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? createToken(SyntaxKind.AssertsKeyword) : undefined, - typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(), + const predicate = factory.createTypePredicateNode( + typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? factory.createToken(SyntaxKind.AssertsKeyword) : undefined, + typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? factory.createIdentifier(typePredicate.parameterName) : factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217 ); const printer = createPrinter({ removeComments: true }); @@ -7474,13 +7576,10 @@ namespace ts { if (parentAccess && parentAccess.flowNode) { const propName = getDestructuringPropertyName(node); if (propName) { - const result = createNode(SyntaxKind.ElementAccessExpression, node.pos, node.end); - result.parent = node; - result.expression = parentAccess; - const literal = createNode(SyntaxKind.StringLiteral, node.pos, node.end); - literal.parent = result; - literal.text = propName; - result.argumentExpression = literal; + const literal = setTextRange(parseNodeFactory.createStringLiteral(propName), node); + const result = setTextRange(parseNodeFactory.createElementAccessExpression(parentAccess, literal), node); + setParent(literal, result); + setParent(result, node); result.flowNode = parentAccess.flowNode; return result; } @@ -7770,9 +7869,9 @@ namespace ts { } function getFlowTypeInConstructor(symbol: Symbol, constructor: ConstructorDeclaration) { - const reference = createPropertyAccess(createThis(), unescapeLeadingUnderscores(symbol.escapedName)); - reference.expression.parent = reference; - reference.parent = constructor; + const reference = factory.createPropertyAccessExpression(factory.createThis(), unescapeLeadingUnderscores(symbol.escapedName)); + setParent(reference.expression, reference); + setParent(reference, constructor); reference.flowNode = constructor.returnFlowNode; const flowType = getFlowTypeOfProperty(reference, symbol); if (noImplicitAny && (flowType === autoType || flowType === autoArrayType)) { @@ -9161,7 +9260,6 @@ namespace ts { case SyntaxKind.ObjectKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NullKeyword: case SyntaxKind.NeverKeyword: case SyntaxKind.LiteralType: return true; @@ -13929,6 +14027,9 @@ namespace ts { } function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type { + if (node.literal.kind === SyntaxKind.NullKeyword) { + return nullType; + } const links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal)); @@ -14029,14 +14130,16 @@ namespace ts { return voidType; case SyntaxKind.UndefinedKeyword: return undefinedType; - case SyntaxKind.NullKeyword: + case SyntaxKind.NullKeyword as TypeNodeSyntaxKind: + // TODO(rbuckton): `NullKeyword` is no longer a `TypeNode`, but we defensively allow it here because of incorrect casts in the Language Service. return nullType; case SyntaxKind.NeverKeyword: return neverType; case SyntaxKind.ObjectKeyword: return node.flags & NodeFlags.JavaScriptFile && !noImplicitAny ? anyType : nonPrimitiveType; case SyntaxKind.ThisType: - case SyntaxKind.ThisKeyword: + case SyntaxKind.ThisKeyword as TypeNodeSyntaxKind: + // TODO(rbuckton): `ThisKeyword` is no longer a `TypeNode`, but we defensively allow it here because of incorrect casts in the Language Service and because of `isPartOfTypeNode`. return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode); case SyntaxKind.LiteralType: return getTypeFromLiteralTypeNode(node); @@ -14091,9 +14194,10 @@ namespace ts { case SyntaxKind.ImportType: return getTypeFromImportTypeNode(node); // This function assumes that an identifier or qualified name is a type expression - // Callers should first ensure this by calling isTypeNode - case SyntaxKind.Identifier: - case SyntaxKind.QualifiedName: + // Callers should first ensure this by calling `isPartOfTypeNode` + // TODO(rbuckton): These aren't valid TypeNodes, but we treat them as such because of `isPartOfTypeNode`, which returns `true` for things that aren't `TypeNode`s. + case SyntaxKind.Identifier as TypeNodeSyntaxKind: + case SyntaxKind.QualifiedName as TypeNodeSyntaxKind: const symbol = getSymbolAtLocation(node); return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType; default: @@ -17079,8 +17183,8 @@ namespace ts { const privateIdentifierDescription = unmatchedProperty.valueDeclaration.name.escapedText; const symbolTableKey = getSymbolNameForPrivateIdentifier(source.symbol, privateIdentifierDescription); if (symbolTableKey && getPropertyOfType(source, symbolTableKey)) { - const sourceName = getDeclarationName(source.symbol.valueDeclaration); - const targetName = getDeclarationName(target.symbol.valueDeclaration); + const sourceName = factory.getDeclarationName(source.symbol.valueDeclaration); + const targetName = factory.getDeclarationName(target.symbol.valueDeclaration); reportError( Diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, diagnosticName(privateIdentifierDescription), @@ -23753,8 +23857,8 @@ namespace ts { childrenTypes[0] : (getArrayLiteralTupleTypeIfApplicable(childrenTypes, childrenContextualType, /*hasRestElement*/ false) || createArrayType(getUnionType(childrenTypes))); // Fake up a property declaration for the children - childrenPropSymbol.valueDeclaration = createPropertySignature(/*modifiers*/ undefined, unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined); - childrenPropSymbol.valueDeclaration.parent = attributes; + childrenPropSymbol.valueDeclaration = factory.createPropertySignature(/*modifiers*/ undefined, unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined); + setParent(childrenPropSymbol.valueDeclaration, attributes); childrenPropSymbol.valueDeclaration.symbol = childrenPropSymbol; const childPropMap = createSymbolTable(); childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol); @@ -25617,11 +25721,9 @@ namespace ts { } function createSyntheticExpression(parent: Node, type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { - const result = createNode(SyntaxKind.SyntheticExpression, parent.pos, parent.end); - result.parent = parent; - result.type = type; - result.isSpread = isSpread || false; - result.tupleNameSource = tupleNameSource; + const result = parseNodeFactory.createSyntheticExpression(type, isSpread, tupleNameSource); + setTextRange(result, parent); + setParent(result, parent); return result; } @@ -25807,21 +25909,22 @@ namespace ts { } if (hasRestParameter || hasSpreadArgument) { - spanArray = createNodeArray(args); + spanArray = factory.createNodeArray(args); if (hasSpreadArgument && argCount) { const nextArg = elementAt(args, getSpreadArgumentIndex(args) + 1) || undefined; - spanArray = createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : Math.min(max, args.length - 1))); + spanArray = factory.createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : Math.min(max, args.length - 1))); } } else { - spanArray = createNodeArray(args.slice(max)); + spanArray = factory.createNodeArray(args.slice(max)); } - spanArray.pos = first(spanArray).pos; - spanArray.end = last(spanArray).end; - if (spanArray.end === spanArray.pos) { - spanArray.end++; + const pos = first(spanArray).pos; + let end = last(spanArray).end; + if (end === pos) { + end++; } + setTextRangePosEnd(spanArray, pos, end); const diagnostic = createDiagnosticForNodeArray( getSourceFileOfNode(node), spanArray, error, paramRange, argCount); return related ? addRelatedInfo(diagnostic, related) : diagnostic; @@ -26731,9 +26834,9 @@ namespace ts { // file would probably be preferable. const typeSymbol = exports && getSymbol(exports, JsxNames.Element, SymbolFlags.Type); const returnNode = typeSymbol && nodeBuilder.symbolToEntityName(typeSymbol, SymbolFlags.Type, node); - const declaration = createFunctionTypeNode(/*typeParameters*/ undefined, - [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotdotdot*/ undefined, "props", /*questionMark*/ undefined, nodeBuilder.typeToTypeNode(result, node))], - returnNode ? createTypeReferenceNode(returnNode, /*typeArguments*/ undefined) : createKeywordTypeNode(SyntaxKind.AnyKeyword) + const declaration = factory.createFunctionTypeNode(/*typeParameters*/ undefined, + [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotdotdot*/ undefined, "props", /*questionMark*/ undefined, nodeBuilder.typeToTypeNode(result, node))], + returnNode ? factory.createTypeReferenceNode(returnNode, /*typeArguments*/ undefined) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ); const parameterSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "props" as __String); parameterSymbol.type = result; @@ -29498,7 +29601,7 @@ namespace ts { if (flowInvocationCount !== startInvocationCount) { const cache = flowTypeCache || (flowTypeCache = []); cache[getNodeId(node)] = type; - node.flags |= NodeFlags.TypeCached; + setNodeFlags(node, node.flags | NodeFlags.TypeCached); } return type; } @@ -31322,7 +31425,7 @@ namespace ts { if (typeNode.kind === SyntaxKind.NeverKeyword) { continue; // Always elide `never` from the union/intersection if possible } - if (!strictNullChecks && (typeNode.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) { + if (!strictNullChecks && (typeNode.kind === SyntaxKind.LiteralType && (typeNode as LiteralTypeNode).literal.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) { continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks } const individualEntityName = getEntityNameForDecoratorMetadata(typeNode); @@ -34135,9 +34238,9 @@ namespace ts { } function isPropertyInitializedInConstructor(propName: Identifier | PrivateIdentifier, propType: Type, constructor: ConstructorDeclaration) { - const reference = createPropertyAccess(createThis(), propName); - reference.expression.parent = reference; - reference.parent = constructor; + const reference = factory.createPropertyAccessExpression(factory.createThis(), propName); + setParent(reference.expression, reference); + setParent(reference, constructor); reference.flowNode = constructor.returnFlowNode; const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); return !(getFalsyFlags(flowType) & TypeFlags.Undefined); @@ -36531,7 +36634,7 @@ namespace ts { function createTypeOfDeclaration(declarationIn: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean) { const declaration = getParseTreeNode(declarationIn, isVariableLikeOrAccessor); if (!declaration) { - return createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; + return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; } // Get type of the symbol if this is the valid symbol otherwise get type at location const symbol = getSymbolOfNode(declaration); @@ -36551,7 +36654,7 @@ namespace ts { function createReturnTypeOfSignatureDeclaration(signatureDeclarationIn: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker) { const signatureDeclaration = getParseTreeNode(signatureDeclarationIn, isFunctionLike); if (!signatureDeclaration) { - return createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; + return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; } const signature = getSignatureFromDeclaration(signatureDeclaration); return nodeBuilder.typeToTypeNode(getReturnTypeOfSignature(signature), enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); @@ -36560,7 +36663,7 @@ namespace ts { function createTypeOfExpression(exprIn: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker) { const expr = getParseTreeNode(exprIn, isExpression); if (!expr) { - return createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; + return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; } const type = getWidenedType(getRegularTypeOfExpression(expr)); return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); @@ -36612,8 +36715,12 @@ namespace ts { function literalTypeToNode(type: FreshableType, enclosing: Node, tracker: SymbolTracker): Expression { const enumResult = type.flags & TypeFlags.EnumLiteral ? nodeBuilder.symbolToExpression(type.symbol, SymbolFlags.Value, enclosing, /*flags*/ undefined, tracker) - : type === trueType ? createTrue() : type === falseType && createFalse(); - return enumResult || createLiteral((type as LiteralType).value); + : type === trueType ? factory.createTrue() : type === falseType && factory.createFalse(); + if (enumResult) return enumResult; + const literalValue = (type as LiteralType).value; + return typeof literalValue === "object" ? factory.createBigIntLiteral(literalValue) : + typeof literalValue === "number" ? factory.createNumericLiteral(literalValue) : + factory.createStringLiteral(literalValue); } function createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker) { @@ -36651,19 +36758,19 @@ namespace ts { getReferencedImportDeclaration, getReferencedDeclarationWithCollidingName, isDeclarationWithCollidingName, - isValueAliasDeclaration: node => { - node = getParseTreeNode(node); + isValueAliasDeclaration: nodeIn => { + const node = getParseTreeNode(nodeIn); // Synthesized nodes are always treated like values. return node ? isValueAliasDeclaration(node) : true; }, hasGlobalName, - isReferencedAliasDeclaration: (node, checkChildren?) => { - node = getParseTreeNode(node); + isReferencedAliasDeclaration: (nodeIn, checkChildren?) => { + const node = getParseTreeNode(nodeIn); // Synthesized nodes are always treated as referenced. return node ? isReferencedAliasDeclaration(node, checkChildren) : true; }, - getNodeCheckFlags: node => { - node = getParseTreeNode(node); + getNodeCheckFlags: nodeIn => { + const node = getParseTreeNode(nodeIn); return node ? getNodeCheckFlags(node) : 0; }, isTopLevelValueImportEqualsWithEntityName, diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 651f5fe82de40..9bb8e04e4e900 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1516,6 +1516,20 @@ namespace ts { }; } + /** A version of `memoize` that supports a single primitive argument */ + export function memoizeOne(callback: (arg: A) => T): (arg: A) => T { + const map = createMap(); + return (arg: A) => { + const key = `${typeof arg}:${arg}`; + let value = map.get(key); + if (value === undefined && !map.has(key)) { + value = callback(arg); + map.set(key, value); + } + return value!; + }; + } + /** * High-order function, composes functions. Note that functions are composed inside-out; * for example, `compose(a, b)` is the equivalent of `x => b(a(x))`. diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index 835779639dca7..f77b4bda4c260 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -79,6 +79,7 @@ namespace ts { /** Array that is only intended to be pushed to, never read. */ export interface Push { push(...values: T[]): void; + /* @internal*/ readonly length: number; } /* @internal */ diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 37beb5225b540..62b01e816a977 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -1,12 +1,72 @@ /* @internal */ namespace ts { + export enum LogLevel { + Off, + Error, + Warning, + Info, + Verbose + } + + export interface LoggingHost { + log(level: LogLevel, s: string): void; + } + + export interface DeprecationOptions { + message?: string; + error?: boolean; + since?: Version | string; + warnAfter?: Version | string; + errorAfter?: Version | string; + typeScriptVersion?: Version | string; + } + export namespace Debug { - let currentAssertionLevel = AssertionLevel.None; + let typeScriptVersion: Version | undefined; - // eslint-disable-next-line prefer-const + /* eslint-disable prefer-const */ + let currentAssertionLevel = AssertionLevel.None; + export let currentLogLevel = LogLevel.Warning; export let isDebugging = false; + export let loggingHost: LoggingHost | undefined; + /* eslint-enable prefer-const */ type AssertionKeys = MatchingKeys; + export function getTypeScriptVersion() { + return typeScriptVersion ?? (typeScriptVersion = new Version(version)); + } + + export function shouldLog(level: LogLevel): boolean { + return currentLogLevel <= level; + } + + function logMessage(level: LogLevel, s: string): void { + if (loggingHost && shouldLog(level)) { + loggingHost.log(level, s); + } + } + + export function log(s: string): void { + logMessage(LogLevel.Info, s); + } + + export namespace log { + export function error(s: string): void { + logMessage(LogLevel.Error, s); + } + + export function warn(s: string): void { + logMessage(LogLevel.Warning, s); + } + + export function log(s: string): void { + logMessage(LogLevel.Info, s); + } + + export function trace(s: string): void { + logMessage(LogLevel.Verbose, s); + } + } const assertionCache: Partial> = {}; @@ -385,7 +445,7 @@ namespace ts { if (nodeIsSynthesized(this)) return ""; const parseNode = getParseTreeNode(this); const sourceFile = parseNode && getSourceFileOfNode(parseNode); - return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; + return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode!, includeTrivia) : ""; } } }); @@ -410,5 +470,56 @@ namespace ts { isDebugInfoEnabled = true; } + function formatDeprecationMessage(name: string, error: boolean | undefined, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) { + let deprecationMessage = error ? "DeprecationError: " : "DeprecationWarning: "; + deprecationMessage += `'${name}' `; + deprecationMessage += since ? `has been deprecated since v${since}` : "is deprecated"; + deprecationMessage += error ? " and can no longer be used." : errorAfter ? ` and will no longer be usable after v${errorAfter}.` : "."; + deprecationMessage += message ? ` ${formatStringFromArgs(message, [name], 0)}` : ""; + return deprecationMessage; + } + + function createErrorDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) { + const deprecationMessage = formatDeprecationMessage(name, /*error*/ true, errorAfter, since, message); + return () => { + throw new TypeError(deprecationMessage); + }; + } + + function createWarningDeprecation(name: string, errorAfter: Version | undefined, since: Version | undefined, message: string | undefined) { + let hasWrittenDeprecation = false; + return () => { + if (!hasWrittenDeprecation) { + log.warn(formatDeprecationMessage(name, /*error*/ false, errorAfter, since, message)); + hasWrittenDeprecation = true; + } + }; + } + + function createDeprecation(name: string, options: DeprecationOptions & { error: true }): () => never; + function createDeprecation(name: string, options?: DeprecationOptions): () => void; + function createDeprecation(name: string, options: DeprecationOptions = {}) { + const version = typeof options.typeScriptVersion === "string" ? new Version(options.typeScriptVersion) : options.typeScriptVersion ?? getTypeScriptVersion(); + const errorAfter = typeof options.errorAfter === "string" ? new Version(options.errorAfter) : options.errorAfter; + const warnAfter = typeof options.warnAfter === "string" ? new Version(options.warnAfter) : options.warnAfter; + const since = typeof options.since === "string" ? new Version(options.since) : options.since ?? warnAfter; + const error = options.error || errorAfter && version.compareTo(errorAfter) <= 0; + const warn = !warnAfter || version.compareTo(warnAfter) >= 0; + return error ? createErrorDeprecation(name, errorAfter, since, options.message) : + warn ? createWarningDeprecation(name, errorAfter, since, options.message) : + noop; + } + + function wrapFunction any>(deprecation: () => void, func: F): F { + return function (this: unknown) { + deprecation(); + return func.apply(this, arguments); + } as F; + } + + export function deprecate any>(func: F, options?: DeprecationOptions): F { + const deprecation = createDeprecation(getFunctionName(func), options); + return wrapFunction(deprecation, func); + } } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index aea8ba3875e53..afbcb53f81612 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -28,7 +28,7 @@ namespace ts { if (outFile(options)) { const prepends = host.getPrependNodes(); if (sourceFiles.length || prepends.length) { - const bundle = createBundle(sourceFiles, prepends); + const bundle = factory.createBundle(sourceFiles, prepends); const result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle); if (result) { return result; @@ -356,7 +356,7 @@ namespace ts { return; } // Transform the source files - const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false); + const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false); const printerOptions: PrinterOptions = { removeComments: compilerOptions.removeComments, @@ -404,13 +404,13 @@ namespace ts { const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles; const filesForEmit = forceDtsEmit ? sourceFiles : filter(sourceFiles, isSourceFileNotJson); // Setup and perform the transformation to retrieve declarations from the input files - const inputListOrBundle = outFile(compilerOptions) ? [createBundle(filesForEmit, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : filesForEmit; + const inputListOrBundle = outFile(compilerOptions) ? [factory.createBundle(filesForEmit, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : filesForEmit; if (emitOnlyDtsFiles && !getEmitDeclarations(compilerOptions)) { // Checker wont collect the linked aliases since thats only done when declaration is enabled. // Do that here when emitting only dts files filesForEmit.forEach(collectLinkedAliases); } - const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false); + const declarationTransform = transformNodes(resolver, host, factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false); if (length(declarationTransform.diagnostics)) { for (const diagnostic of declarationTransform.diagnostics!) { emitterDiagnostics.add(diagnostic); @@ -680,30 +680,30 @@ namespace ts { } function createSourceFilesFromBundleBuildInfo(bundle: BundleBuildInfo, buildInfoDirectory: string, host: EmitUsingBuildInfoHost): readonly SourceFile[] { - const sourceFiles = bundle.sourceFiles.map(fileName => { - const sourceFile = createNode(SyntaxKind.SourceFile, 0, 0) as SourceFile; + const jsBundle = Debug.checkDefined(bundle.js); + const prologueMap = jsBundle.sources?.prologues && arrayToMap(jsBundle.sources.prologues, prologueInfo => "" + prologueInfo.file); + return bundle.sourceFiles.map((fileName, index) => { + const prologueInfo = prologueMap?.get("" + index); + const statements = prologueInfo?.directives.map(directive => { + const literal = setTextRange(factory.createStringLiteral(directive.expression.text), directive.expression); + const statement = setTextRange(factory.createExpressionStatement(literal), directive); + setParent(literal, statement); + return statement; + }); + const eofToken = factory.createToken(SyntaxKind.EndOfFileToken); + const sourceFile = factory.createSourceFile(statements ?? [], eofToken, NodeFlags.None); sourceFile.fileName = getRelativePathFromDirectory( host.getCurrentDirectory(), getNormalizedAbsolutePath(fileName, buildInfoDirectory), !host.useCaseSensitiveFileNames() ); - sourceFile.text = ""; - sourceFile.statements = createNodeArray(); + sourceFile.text = prologueInfo?.text ?? ""; + setTextRangePosWidth(sourceFile, 0, prologueInfo?.text.length ?? 0); + setEachParent(sourceFile.statements, sourceFile); + setTextRangePosWidth(eofToken, sourceFile.end, 0); + setParent(eofToken, sourceFile); return sourceFile; }); - const jsBundle = Debug.checkDefined(bundle.js); - forEach(jsBundle.sources && jsBundle.sources.prologues, prologueInfo => { - const sourceFile = sourceFiles[prologueInfo.file]; - sourceFile.text = prologueInfo.text; - sourceFile.end = prologueInfo.text.length; - sourceFile.statements = createNodeArray(prologueInfo.directives.map(directive => { - const statement = createNode(SyntaxKind.ExpressionStatement, directive.pos, directive.end) as PrologueDirective; - statement.expression = createNode(SyntaxKind.StringLiteral, directive.expression.pos, directive.expression.end) as StringLiteral; - statement.expression.text = directive.expression.text; - return statement; - })); - }); - return sourceFiles; } /*@internal*/ @@ -2292,7 +2292,7 @@ namespace ts { function emitPropertyAccessExpression(node: PropertyAccessExpression) { const expression = cast(emitExpression(node.expression), isExpression); - const token = node.questionDotToken || createNode(SyntaxKind.DotToken, node.expression.end, node.name.pos) as DotToken; + const token = node.questionDotToken || setTextRangePosEnd(factory.createToken(SyntaxKind.DotToken) as DotToken, node.expression.end, node.name.pos); const linesBeforeDot = getLinesBetweenNodes(node, node.expression, token); const linesAfterDot = getLinesBetweenNodes(node, token, node.name); @@ -3559,15 +3559,15 @@ namespace ts { } function emitJSDocTypeLiteral(lit: JSDocTypeLiteral) { - emitList(lit, createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment); + emitList(lit, factory.createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment); } function emitJSDocSignature(sig: JSDocSignature) { if (sig.typeParameters) { - emitList(sig, createNodeArray(sig.typeParameters), ListFormat.JSDocComment); + emitList(sig, factory.createNodeArray(sig.typeParameters), ListFormat.JSDocComment); } if (sig.parameters) { - emitList(sig, createNodeArray(sig.parameters), ListFormat.JSDocComment); + emitList(sig, factory.createNodeArray(sig.parameters), ListFormat.JSDocComment); } if (sig.type) { writeLine(); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts deleted file mode 100644 index 795c1cdcea15d..0000000000000 --- a/src/compiler/factory.ts +++ /dev/null @@ -1,1900 +0,0 @@ -/* @internal */ -namespace ts { - export const nullTransformationContext: TransformationContext = { - enableEmitNotification: noop, - enableSubstitution: noop, - endLexicalEnvironment: returnUndefined, - getCompilerOptions: () => ({}), - getEmitHost: notImplemented, - getEmitResolver: notImplemented, - setLexicalEnvironmentFlags: noop, - getLexicalEnvironmentFlags: () => 0, - hoistFunctionDeclaration: noop, - hoistVariableDeclaration: noop, - addInitializationStatement: noop, - isEmitNotificationEnabled: notImplemented, - isSubstitutionEnabled: notImplemented, - onEmitNode: noop, - onSubstituteNode: notImplemented, - readEmitHelpers: notImplemented, - requestEmitHelper: noop, - resumeLexicalEnvironment: noop, - startLexicalEnvironment: noop, - suspendLexicalEnvironment: noop, - addDiagnostic: noop, - }; - - // Compound nodes - - export type TypeOfTag = "undefined" | "number" | "boolean" | "string" | "symbol" | "object" | "function"; - - export function createTypeCheck(value: Expression, tag: TypeOfTag) { - return tag === "undefined" - ? createStrictEquality(value, createVoidZero()) - : createStrictEquality(createTypeOf(value), createLiteral(tag)); - } - - export function createMemberAccessForPropertyName(target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression { - if (isComputedPropertyName(memberName)) { - return setTextRange(createElementAccess(target, memberName.expression), location); - } - else { - const expression = setTextRange( - (isIdentifier(memberName) || isPrivateIdentifier(memberName)) - ? createPropertyAccess(target, memberName) - : createElementAccess(target, memberName), - memberName - ); - getOrCreateEmitNode(expression).flags |= EmitFlags.NoNestedSourceMaps; - return expression; - } - } - - export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: readonly Expression[], location?: TextRange) { - return setTextRange( - createCall( - createPropertyAccess(func, "call"), - /*typeArguments*/ undefined, - [ - thisArg, - ...argumentsList - ]), - location - ); - } - - export function createFunctionApply(func: Expression, thisArg: Expression, argumentsExpression: Expression, location?: TextRange) { - return setTextRange( - createCall( - createPropertyAccess(func, "apply"), - /*typeArguments*/ undefined, - [ - thisArg, - argumentsExpression - ] - ), - location - ); - } - - export function createArraySlice(array: Expression, start?: number | Expression) { - const argumentsList: Expression[] = []; - if (start !== undefined) { - argumentsList.push(typeof start === "number" ? createLiteral(start) : start); - } - - return createCall(createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList); - } - - export function createArrayConcat(array: Expression, values: readonly Expression[]) { - return createCall( - createPropertyAccess(array, "concat"), - /*typeArguments*/ undefined, - values - ); - } - - export function createMathPow(left: Expression, right: Expression, location?: TextRange) { - return setTextRange( - createCall( - createPropertyAccess(createIdentifier("Math"), "pow"), - /*typeArguments*/ undefined, - [left, right] - ), - location - ); - } - - function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment) { - // To ensure the emit resolver can properly resolve the namespace, we need to - // treat this identifier as if it were a source tree node by clearing the `Synthesized` - // flag and setting a parent node. - const react = createIdentifier(reactNamespace || "React"); - react.flags &= ~NodeFlags.Synthesized; - // Set the parent that is in parse tree - // this makes sure that parent chain is intact for checker to traverse complete scope tree - react.parent = getParseTreeNode(parent); - return react; - } - - function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { - if (isQualifiedName(jsxFactory)) { - const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent); - const right = createIdentifier(idText(jsxFactory.right)); - right.escapedText = jsxFactory.right.escapedText; - return createPropertyAccess(left, right); - } - else { - return createReactNamespace(idText(jsxFactory), parent); - } - } - - function createJsxFactoryExpression(jsxFactoryEntity: EntityName | undefined, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { - return jsxFactoryEntity ? - createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) : - createPropertyAccess( - createReactNamespace(reactNamespace, parent), - "createElement" - ); - } - - export function createExpressionForJsxElement(jsxFactoryEntity: EntityName | undefined, reactNamespace: string, tagName: Expression, props: Expression, children: readonly Expression[], parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression { - const argumentsList = [tagName]; - if (props) { - argumentsList.push(props); - } - - if (children && children.length > 0) { - if (!props) { - argumentsList.push(createNull()); - } - - if (children.length > 1) { - for (const child of children) { - startOnNewLine(child); - argumentsList.push(child); - } - } - else { - argumentsList.push(children[0]); - } - } - - return setTextRange( - createCall( - createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), - /*typeArguments*/ undefined, - argumentsList - ), - location - ); - } - - export function createExpressionForJsxFragment(jsxFactoryEntity: EntityName | undefined, reactNamespace: string, children: readonly Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression { - const tagName = createPropertyAccess( - createReactNamespace(reactNamespace, parentElement), - "Fragment" - ); - - const argumentsList = [tagName]; - argumentsList.push(createNull()); - - if (children && children.length > 0) { - if (children.length > 1) { - for (const child of children) { - startOnNewLine(child); - argumentsList.push(child); - } - } - else { - argumentsList.push(children[0]); - } - } - - return setTextRange( - createCall( - createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), - /*typeArguments*/ undefined, - argumentsList - ), - location - ); - } - - // Helpers - - /** - * Gets an identifier for the name of an *unscoped* emit helper. - */ - export function getUnscopedHelperName(name: string) { - return setEmitFlags(createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode); - } - - export const valuesHelper: UnscopedEmitHelper = { - name: "typescript:values", - importName: "__values", - scoped: false, - text: ` - var __values = (this && this.__values) || function(o) { - var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; - if (m) return m.call(o); - if (o && typeof o.length === "number") return { - next: function () { - if (o && i >= o.length) o = void 0; - return { value: o && o[i++], done: !o }; - } - }; - throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); - };` - }; - - export function createValuesHelper(context: TransformationContext, expression: Expression, location?: TextRange) { - context.requestEmitHelper(valuesHelper); - return setTextRange( - createCall( - getUnscopedHelperName("__values"), - /*typeArguments*/ undefined, - [expression] - ), - location - ); - } - - export const readHelper: UnscopedEmitHelper = { - name: "typescript:read", - importName: "__read", - scoped: false, - text: ` - var __read = (this && this.__read) || function (o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; - };` - }; - - export function createReadHelper(context: TransformationContext, iteratorRecord: Expression, count: number | undefined, location?: TextRange) { - context.requestEmitHelper(readHelper); - return setTextRange( - createCall( - getUnscopedHelperName("__read"), - /*typeArguments*/ undefined, - count !== undefined - ? [iteratorRecord, createLiteral(count)] - : [iteratorRecord] - ), - location - ); - } - - export const spreadHelper: UnscopedEmitHelper = { - name: "typescript:spread", - importName: "__spread", - scoped: false, - dependencies: [readHelper], - text: ` - var __spread = (this && this.__spread) || function () { - for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); - return ar; - };` - }; - - export function createSpreadHelper(context: TransformationContext, argumentList: readonly Expression[], location?: TextRange) { - context.requestEmitHelper(spreadHelper); - return setTextRange( - createCall( - getUnscopedHelperName("__spread"), - /*typeArguments*/ undefined, - argumentList - ), - location - ); - } - - export const spreadArraysHelper: UnscopedEmitHelper = { - name: "typescript:spreadArrays", - importName: "__spreadArrays", - scoped: false, - text: ` - var __spreadArrays = (this && this.__spreadArrays) || function () { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; - };` - }; - - export function createSpreadArraysHelper(context: TransformationContext, argumentList: readonly Expression[], location?: TextRange) { - context.requestEmitHelper(spreadArraysHelper); - return setTextRange( - createCall( - getUnscopedHelperName("__spreadArrays"), - /*typeArguments*/ undefined, - argumentList - ), - location - ); - } - - // Utilities - - export function createForOfBindingStatement(node: ForInitializer, boundValue: Expression): Statement { - if (isVariableDeclarationList(node)) { - const firstDeclaration = first(node.declarations); - const updatedDeclaration = updateVariableDeclaration( - firstDeclaration, - firstDeclaration.name, - /*typeNode*/ undefined, - boundValue - ); - return setTextRange( - createVariableStatement( - /*modifiers*/ undefined, - updateVariableDeclarationList(node, [updatedDeclaration]) - ), - /*location*/ node - ); - } - else { - const updatedExpression = setTextRange(createAssignment(node, boundValue), /*location*/ node); - return setTextRange(createStatement(updatedExpression), /*location*/ node); - } - } - - export function insertLeadingStatement(dest: Statement, source: Statement) { - if (isBlock(dest)) { - return updateBlock(dest, setTextRange(createNodeArray([source, ...dest.statements]), dest.statements)); - } - else { - return createBlock(createNodeArray([dest, source]), /*multiLine*/ true); - } - } - - export function restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement | undefined, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement { - if (!outermostLabeledStatement) { - return node; - } - const updated = updateLabel( - outermostLabeledStatement, - outermostLabeledStatement.label, - outermostLabeledStatement.statement.kind === SyntaxKind.LabeledStatement - ? restoreEnclosingLabel(node, outermostLabeledStatement.statement) - : node - ); - if (afterRestoreLabelCallback) { - afterRestoreLabelCallback(outermostLabeledStatement); - } - return updated; - } - - export interface CallBinding { - target: LeftHandSideExpression; - thisArg: Expression; - } - - function shouldBeCapturedInTempVariable(node: Expression, cacheIdentifiers: boolean): boolean { - const target = skipParentheses(node); - switch (target.kind) { - case SyntaxKind.Identifier: - return cacheIdentifiers; - case SyntaxKind.ThisKeyword: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.StringLiteral: - return false; - case SyntaxKind.ArrayLiteralExpression: - const elements = (target).elements; - if (elements.length === 0) { - return false; - } - return true; - case SyntaxKind.ObjectLiteralExpression: - return (target).properties.length > 0; - default: - return true; - } - } - - export function createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers = false): CallBinding { - const callee = skipOuterExpressions(expression, OuterExpressionKinds.All); - let thisArg: Expression; - let target: LeftHandSideExpression; - if (isSuperProperty(callee)) { - thisArg = createThis(); - target = callee; - } - else if (callee.kind === SyntaxKind.SuperKeyword) { - thisArg = createThis(); - target = languageVersion! < ScriptTarget.ES2015 - ? setTextRange(createIdentifier("_super"), callee) - : callee; - } - else if (getEmitFlags(callee) & EmitFlags.HelperName) { - thisArg = createVoidZero(); - target = parenthesizeForAccess(callee); - } - else { - switch (callee.kind) { - case SyntaxKind.PropertyAccessExpression: { - if (shouldBeCapturedInTempVariable((callee).expression, cacheIdentifiers)) { - // for `a.b()` target is `(_a = a).b` and thisArg is `_a` - thisArg = createTempVariable(recordTempVariable); - target = createPropertyAccess( - setTextRange( - createAssignment( - thisArg, - (callee).expression - ), - (callee).expression - ), - (callee).name - ); - setTextRange(target, callee); - } - else { - thisArg = (callee).expression; - target = callee; - } - break; - } - - case SyntaxKind.ElementAccessExpression: { - if (shouldBeCapturedInTempVariable((callee).expression, cacheIdentifiers)) { - // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a` - thisArg = createTempVariable(recordTempVariable); - target = createElementAccess( - setTextRange( - createAssignment( - thisArg, - (callee).expression - ), - (callee).expression - ), - (callee).argumentExpression - ); - setTextRange(target, callee); - } - else { - thisArg = (callee).expression; - target = callee; - } - - break; - } - - default: { - // for `a()` target is `a` and thisArg is `void 0` - thisArg = createVoidZero(); - target = parenthesizeForAccess(expression); - break; - } - } - } - - return { target, thisArg }; - } - - export function inlineExpressions(expressions: readonly Expression[]) { - // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call - // stack size exceeded" errors. - return expressions.length > 10 - ? createCommaList(expressions) - : reduceLeft(expressions, createComma)!; - } - - export function createExpressionFromEntityName(node: EntityName | Expression): Expression { - if (isQualifiedName(node)) { - const left = createExpressionFromEntityName(node.left); - const right = getMutableClone(node.right); - return setTextRange(createPropertyAccess(left, right), node); - } - else { - return getMutableClone(node); - } - } - - export function createExpressionForPropertyName(memberName: Exclude): Expression { - if (isIdentifier(memberName)) { - return createLiteral(memberName); - } - else if (isComputedPropertyName(memberName)) { - return getMutableClone(memberName.expression); - } - else { - return getMutableClone(memberName); - } - } - - export function createExpressionForObjectLiteralElementLike(node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression | undefined { - if (property.name && isPrivateIdentifier(property.name)) { - Debug.failBadSyntaxKind(property.name, "Private identifiers are not allowed in object literals."); - } - switch (property.kind) { - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return createExpressionForAccessorDeclaration(node.properties, property as typeof property & { name: Exclude; }, receiver, !!node.multiLine); - case SyntaxKind.PropertyAssignment: - return createExpressionForPropertyAssignment(property, receiver); - case SyntaxKind.ShorthandPropertyAssignment: - return createExpressionForShorthandPropertyAssignment(property, receiver); - case SyntaxKind.MethodDeclaration: - return createExpressionForMethodDeclaration(property, receiver); - } - } - - function createExpressionForAccessorDeclaration(properties: NodeArray, property: AccessorDeclaration & { name: Exclude; }, receiver: Expression, multiLine: boolean) { - const { firstAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(properties, property); - if (property === firstAccessor) { - const properties: ObjectLiteralElementLike[] = []; - if (getAccessor) { - const getterFunction = createFunctionExpression( - getAccessor.modifiers, - /*asteriskToken*/ undefined, - /*name*/ undefined, - /*typeParameters*/ undefined, - getAccessor.parameters, - /*type*/ undefined, - getAccessor.body! // TODO: GH#18217 - ); - setTextRange(getterFunction, getAccessor); - setOriginalNode(getterFunction, getAccessor); - const getter = createPropertyAssignment("get", getterFunction); - properties.push(getter); - } - - if (setAccessor) { - const setterFunction = createFunctionExpression( - setAccessor.modifiers, - /*asteriskToken*/ undefined, - /*name*/ undefined, - /*typeParameters*/ undefined, - setAccessor.parameters, - /*type*/ undefined, - setAccessor.body! // TODO: GH#18217 - ); - setTextRange(setterFunction, setAccessor); - setOriginalNode(setterFunction, setAccessor); - const setter = createPropertyAssignment("set", setterFunction); - properties.push(setter); - } - - properties.push(createPropertyAssignment("enumerable", getAccessor || setAccessor ? createFalse() : createTrue())); - properties.push(createPropertyAssignment("configurable", createTrue())); - - const expression = setTextRange( - createCall( - createPropertyAccess(createIdentifier("Object"), "defineProperty"), - /*typeArguments*/ undefined, - [ - receiver, - createExpressionForPropertyName(property.name), - createObjectLiteral(properties, multiLine) - ] - ), - /*location*/ firstAccessor - ); - - return aggregateTransformFlags(expression); - } - - return undefined; - } - - function createExpressionForPropertyAssignment(property: PropertyAssignment, receiver: Expression) { - return aggregateTransformFlags( - setOriginalNode( - setTextRange( - createAssignment( - createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), - property.initializer - ), - property - ), - property - ) - ); - } - - function createExpressionForShorthandPropertyAssignment(property: ShorthandPropertyAssignment, receiver: Expression) { - return aggregateTransformFlags( - setOriginalNode( - setTextRange( - createAssignment( - createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), - getSynthesizedClone(property.name) - ), - /*location*/ property - ), - /*original*/ property - ) - ); - } - - function createExpressionForMethodDeclaration(method: MethodDeclaration, receiver: Expression) { - return aggregateTransformFlags( - setOriginalNode( - setTextRange( - createAssignment( - createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), - setOriginalNode( - setTextRange( - createFunctionExpression( - method.modifiers, - method.asteriskToken, - /*name*/ undefined, - /*typeParameters*/ undefined, - method.parameters, - /*type*/ undefined, - method.body! // TODO: GH#18217 - ), - /*location*/ method - ), - /*original*/ method - ) - ), - /*location*/ method - ), - /*original*/ method - ) - ); - } - - /** - * Gets the internal name of a declaration. This is primarily used for declarations that can be - * referred to by name in the body of an ES5 class function body. An internal name will *never* - * be prefixed with an module or namespace export modifier like "exports." when emitted as an - * expression. An internal name will also *never* be renamed due to a collision with a block - * scoped variable. - * - * @param node The declaration. - * @param allowComments A value indicating whether comments may be emitted for the name. - * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. - */ - export function getInternalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { - return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName | EmitFlags.InternalName); - } - - /** - * Gets whether an identifier should only be referred to by its internal name. - */ - export function isInternalName(node: Identifier) { - return (getEmitFlags(node) & EmitFlags.InternalName) !== 0; - } - - /** - * Gets the local name of a declaration. This is primarily used for declarations that can be - * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A - * local name will *never* be prefixed with an module or namespace export modifier like - * "exports." when emitted as an expression. - * - * @param node The declaration. - * @param allowComments A value indicating whether comments may be emitted for the name. - * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. - */ - export function getLocalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { - return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName); - } - - /** - * Gets whether an identifier should only be referred to by its local name. - */ - export function isLocalName(node: Identifier) { - return (getEmitFlags(node) & EmitFlags.LocalName) !== 0; - } - - /** - * Gets the export name of a declaration. This is primarily used for declarations that can be - * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An - * export name will *always* be prefixed with an module or namespace export modifier like - * `"exports."` when emitted as an expression if the name points to an exported symbol. - * - * @param node The declaration. - * @param allowComments A value indicating whether comments may be emitted for the name. - * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. - */ - export function getExportName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier { - return getName(node, allowComments, allowSourceMaps, EmitFlags.ExportName); - } - - /** - * Gets whether an identifier should only be referred to by its export representation if the - * name points to an exported symbol. - */ - export function isExportName(node: Identifier) { - return (getEmitFlags(node) & EmitFlags.ExportName) !== 0; - } - - /** - * Gets the name of a declaration for use in declarations. - * - * @param node The declaration. - * @param allowComments A value indicating whether comments may be emitted for the name. - * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. - */ - export function getDeclarationName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { - return getName(node, allowComments, allowSourceMaps); - } - - function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags: EmitFlags = 0) { - const nodeName = getNameOfDeclaration(node); - if (nodeName && isIdentifier(nodeName) && !isGeneratedIdentifier(nodeName)) { - const name = getMutableClone(nodeName); - emitFlags |= getEmitFlags(nodeName); - if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; - if (!allowComments) emitFlags |= EmitFlags.NoComments; - if (emitFlags) setEmitFlags(name, emitFlags); - return name; - } - return getGeneratedNameForNode(node); - } - - /** - * Gets the exported name of a declaration for use in expressions. - * - * An exported name will *always* be prefixed with an module or namespace export modifier like - * "exports." if the name points to an exported symbol. - * - * @param ns The namespace identifier. - * @param node The declaration. - * @param allowComments A value indicating whether comments may be emitted for the name. - * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. - */ - export function getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression { - if (ns && hasSyntacticModifier(node, ModifierFlags.Export)) { - return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps); - } - return getExportName(node, allowComments, allowSourceMaps); - } - - /** - * Gets a namespace-qualified name for use in expressions. - * - * @param ns The namespace identifier. - * @param name The name. - * @param allowComments A value indicating whether comments may be emitted for the name. - * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. - */ - export function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression { - const qualifiedName = createPropertyAccess(ns, nodeIsSynthesized(name) ? name : getSynthesizedClone(name)); - setTextRange(qualifiedName, name); - let emitFlags: EmitFlags = 0; - if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; - if (!allowComments) emitFlags |= EmitFlags.NoComments; - if (emitFlags) setEmitFlags(qualifiedName, emitFlags); - return qualifiedName; - } - - export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean): Block { - return isBlock(node) ? node : setTextRange(createBlock([setTextRange(createReturn(node), node)], multiLine), node); - } - - export function convertFunctionDeclarationToExpression(node: FunctionDeclaration) { - if (!node.body) return Debug.fail(); - const updated = createFunctionExpression( - node.modifiers, - node.asteriskToken, - node.name, - node.typeParameters, - node.parameters, - node.type, - node.body - ); - setOriginalNode(updated, node); - setTextRange(updated, node); - if (getStartsOnNewLine(node)) { - setStartsOnNewLine(updated, /*newLine*/ true); - } - aggregateTransformFlags(updated); - return updated; - } - - function isUseStrictPrologue(node: ExpressionStatement): boolean { - return isStringLiteral(node.expression) && node.expression.text === "use strict"; - } - - /** - * Add any necessary prologue-directives into target statement-array. - * The function needs to be called during each transformation step. - * This function needs to be called whenever we transform the statement - * list of a source file, namespace, or function-like body. - * - * @param target: result statements array - * @param source: origin statements array - * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives - * @param visitor: Optional callback used to visit any custom prologue directives. - */ - export function addPrologue(target: Statement[], source: readonly Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number { - const offset = addStandardPrologue(target, source, ensureUseStrict); - return addCustomPrologue(target, source, offset, visitor); - } - - /** - * Add just the standard (string-expression) prologue-directives into target statement-array. - * The function needs to be called during each transformation step. - * This function needs to be called whenever we transform the statement - * list of a source file, namespace, or function-like body. - */ - export function addStandardPrologue(target: Statement[], source: readonly Statement[], ensureUseStrict?: boolean): number { - Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array"); - let foundUseStrict = false; - let statementOffset = 0; - const numStatements = source.length; - while (statementOffset < numStatements) { - const statement = source[statementOffset]; - if (isPrologueDirective(statement)) { - if (isUseStrictPrologue(statement)) { - foundUseStrict = true; - } - target.push(statement); - } - else { - break; - } - statementOffset++; - } - if (ensureUseStrict && !foundUseStrict) { - target.push(startOnNewLine(createStatement(createLiteral("use strict")))); - } - return statementOffset; - } - - /** - * Add just the custom prologue-directives into target statement-array. - * The function needs to be called during each transformation step. - * This function needs to be called whenever we transform the statement - * list of a source file, namespace, or function-like body. - */ - export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number; - export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number | undefined; - export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter: (node: Node) => boolean = returnTrue): number | undefined { - const numStatements = source.length; - while (statementOffset !== undefined && statementOffset < numStatements) { - const statement = source[statementOffset]; - if (getEmitFlags(statement) & EmitFlags.CustomPrologue && filter(statement)) { - append(target, visitor ? visitNode(statement, visitor, isStatement) : statement); - } - else { - break; - } - statementOffset++; - } - return statementOffset; - } - - export function findUseStrictPrologue(statements: readonly Statement[]): Statement | undefined { - for (const statement of statements) { - if (isPrologueDirective(statement)) { - if (isUseStrictPrologue(statement)) { - return statement; - } - } - else { - break; - } - } - return undefined; - } - - export function startsWithUseStrict(statements: readonly Statement[]) { - const firstStatement = firstOrUndefined(statements); - return firstStatement !== undefined - && isPrologueDirective(firstStatement) - && isUseStrictPrologue(firstStatement); - } - - /** - * Ensures "use strict" directive is added - * - * @param statements An array of statements - */ - export function ensureUseStrict(statements: NodeArray): NodeArray { - const foundUseStrict = findUseStrictPrologue(statements); - - if (!foundUseStrict) { - return setTextRange( - createNodeArray([ - startOnNewLine(createStatement(createLiteral("use strict"))), - ...statements - ]), - statements - ); - } - - return statements; - } - - /** - * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended - * order of operations. - * - * @param binaryOperator The operator for the BinaryExpression. - * @param operand The operand for the BinaryExpression. - * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the - * BinaryExpression. - */ - export function parenthesizeBinaryOperand(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand?: Expression) { - const skipped = skipPartiallyEmittedExpressions(operand); - - // If the resulting expression is already parenthesized, we do not need to do any further processing. - if (skipped.kind === SyntaxKind.ParenthesizedExpression) { - return operand; - } - - return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) - ? createParen(operand) - : operand; - } - - /** - * Determines whether the operand to a BinaryExpression needs to be parenthesized. - * - * @param binaryOperator The operator for the BinaryExpression. - * @param operand The operand for the BinaryExpression. - * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the - * BinaryExpression. - */ - function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand: Expression | undefined) { - // If the operand has lower precedence, then it needs to be parenthesized to preserve the - // intent of the expression. For example, if the operand is `a + b` and the operator is - // `*`, then we need to parenthesize the operand to preserve the intended order of - // operations: `(a + b) * x`. - // - // If the operand has higher precedence, then it does not need to be parenthesized. For - // example, if the operand is `a * b` and the operator is `+`, then we do not need to - // parenthesize to preserve the intended order of operations: `a * b + x`. - // - // If the operand has the same precedence, then we need to check the associativity of - // the operator based on whether this is the left or right operand of the expression. - // - // For example, if `a / d` is on the right of operator `*`, we need to parenthesize - // to preserve the intended order of operations: `x * (a / d)` - // - // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve - // the intended order of operations: `(a ** b) ** c` - const binaryOperatorPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, binaryOperator); - const binaryOperatorAssociativity = getOperatorAssociativity(SyntaxKind.BinaryExpression, binaryOperator); - const emittedOperand = skipPartiallyEmittedExpressions(operand); - if (!isLeftSideOfBinary && operand.kind === SyntaxKind.ArrowFunction && binaryOperatorPrecedence > 3) { - // We need to parenthesize arrow functions on the right side to avoid it being - // parsed as parenthesized expression: `a && (() => {})` - return true; - } - const operandPrecedence = getExpressionPrecedence(emittedOperand); - switch (compareValues(operandPrecedence, binaryOperatorPrecedence)) { - case Comparison.LessThan: - // If the operand is the right side of a right-associative binary operation - // and is a yield expression, then we do not need parentheses. - if (!isLeftSideOfBinary - && binaryOperatorAssociativity === Associativity.Right - && operand.kind === SyntaxKind.YieldExpression) { - return false; - } - - return true; - - case Comparison.GreaterThan: - return false; - - case Comparison.EqualTo: - if (isLeftSideOfBinary) { - // No need to parenthesize the left operand when the binary operator is - // left associative: - // (a*b)/x -> a*b/x - // (a**b)/x -> a**b/x - // - // Parentheses are needed for the left operand when the binary operator is - // right associative: - // (a/b)**x -> (a/b)**x - // (a**b)**x -> (a**b)**x - return binaryOperatorAssociativity === Associativity.Right; - } - else { - if (isBinaryExpression(emittedOperand) - && emittedOperand.operatorToken.kind === binaryOperator) { - // No need to parenthesize the right operand when the binary operator and - // operand are the same and one of the following: - // x*(a*b) => x*a*b - // x|(a|b) => x|a|b - // x&(a&b) => x&a&b - // x^(a^b) => x^a^b - if (operatorHasAssociativeProperty(binaryOperator)) { - return false; - } - - // No need to parenthesize the right operand when the binary operator - // is plus (+) if both the left and right operands consist solely of either - // literals of the same kind or binary plus (+) expressions for literals of - // the same kind (recursively). - // "a"+(1+2) => "a"+(1+2) - // "a"+("b"+"c") => "a"+"b"+"c" - if (binaryOperator === SyntaxKind.PlusToken) { - const leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : SyntaxKind.Unknown; - if (isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) { - return false; - } - } - } - - // No need to parenthesize the right operand when the operand is right - // associative: - // x/(a**b) -> x/a**b - // x**(a**b) -> x**a**b - // - // Parentheses are needed for the right operand when the operand is left - // associative: - // x/(a*b) -> x/(a*b) - // x**(a/b) -> x**(a/b) - const operandAssociativity = getExpressionAssociativity(emittedOperand); - return operandAssociativity === Associativity.Left; - } - } - } - - /** - * Determines whether a binary operator is mathematically associative. - * - * @param binaryOperator The binary operator. - */ - function operatorHasAssociativeProperty(binaryOperator: SyntaxKind) { - // The following operators are associative in JavaScript: - // (a*b)*c -> a*(b*c) -> a*b*c - // (a|b)|c -> a|(b|c) -> a|b|c - // (a&b)&c -> a&(b&c) -> a&b&c - // (a^b)^c -> a^(b^c) -> a^b^c - // - // While addition is associative in mathematics, JavaScript's `+` is not - // guaranteed to be associative as it is overloaded with string concatenation. - return binaryOperator === SyntaxKind.AsteriskToken - || binaryOperator === SyntaxKind.BarToken - || binaryOperator === SyntaxKind.AmpersandToken - || binaryOperator === SyntaxKind.CaretToken; - } - - interface BinaryPlusExpression extends BinaryExpression { - cachedLiteralKind: SyntaxKind; - } - - /** - * This function determines whether an expression consists of a homogeneous set of - * literal expressions or binary plus expressions that all share the same literal kind. - * It is used to determine whether the right-hand operand of a binary plus expression can be - * emitted without parentheses. - */ - function getLiteralKindOfBinaryPlusOperand(node: Expression): SyntaxKind { - node = skipPartiallyEmittedExpressions(node); - - if (isLiteralKind(node.kind)) { - return node.kind; - } - - if (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.PlusToken) { - if ((node).cachedLiteralKind !== undefined) { - return (node).cachedLiteralKind; - } - - const leftKind = getLiteralKindOfBinaryPlusOperand((node).left); - const literalKind = isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand((node).right) ? leftKind : - SyntaxKind.Unknown; - - (node).cachedLiteralKind = literalKind; - return literalKind; - } - - return SyntaxKind.Unknown; - } - - export function parenthesizeForConditionalHead(condition: Expression) { - const conditionalPrecedence = getOperatorPrecedence(SyntaxKind.ConditionalExpression, SyntaxKind.QuestionToken); - const emittedCondition = skipPartiallyEmittedExpressions(condition); - const conditionPrecedence = getExpressionPrecedence(emittedCondition); - if (compareValues(conditionPrecedence, conditionalPrecedence) !== Comparison.GreaterThan) { - return createParen(condition); - } - return condition; - } - - export function parenthesizeSubexpressionOfConditionalExpression(e: Expression): Expression { - // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions - // so in case when comma expression is introduced as a part of previous transformations - // if should be wrapped in parens since comma operator has the lowest precedence - const emittedExpression = skipPartiallyEmittedExpressions(e); - return isCommaSequence(emittedExpression) - ? createParen(e) - : e; - } - - /** - * [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but - * has a lookahead restriction for `function`, `async function`, and `class`. - * - * Basically, that means we need to parenthesize in the following cases: - * - * - BinaryExpression of CommaToken - * - CommaList (synthetic list of multiple comma expressions) - * - FunctionExpression - * - ClassExpression - */ - export function parenthesizeDefaultExpression(e: Expression) { - const check = skipPartiallyEmittedExpressions(e); - let needsParens = isCommaSequence(check); - if (!needsParens) { - switch (getLeftmostExpression(check, /*stopAtCallExpression*/ false).kind) { - case SyntaxKind.ClassExpression: - case SyntaxKind.FunctionExpression: - needsParens = true; - } - } - return needsParens ? createParen(e) : e; - } - - /** - * Wraps an expression in parentheses if it is needed in order to use the expression - * as the expression of a NewExpression node. - * - * @param expression The Expression node. - */ - export function parenthesizeForNew(expression: Expression): LeftHandSideExpression { - const leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true); - switch (leftmostExpr.kind) { - case SyntaxKind.CallExpression: - return createParen(expression); - - case SyntaxKind.NewExpression: - return !(leftmostExpr as NewExpression).arguments - ? createParen(expression) - : expression; - } - - return parenthesizeForAccess(expression); - } - - /** - * Wraps an expression in parentheses if it is needed in order to use the expression for - * property or element access. - * - * @param expr The expression node. - */ - export function parenthesizeForAccess(expression: Expression): LeftHandSideExpression { - // isLeftHandSideExpression is almost the correct criterion for when it is not necessary - // to parenthesize the expression before a dot. The known exception is: - // - // NewExpression: - // new C.x -> not the same as (new C).x - // - const emittedExpression = skipPartiallyEmittedExpressions(expression); - if (isLeftHandSideExpression(emittedExpression) - && (emittedExpression.kind !== SyntaxKind.NewExpression || (emittedExpression).arguments)) { - return expression; - } - - return setTextRange(createParen(expression), expression); - } - - export function parenthesizePostfixOperand(operand: Expression) { - return isLeftHandSideExpression(operand) - ? operand - : setTextRange(createParen(operand), operand); - } - - export function parenthesizePrefixOperand(operand: Expression) { - return isUnaryExpression(operand) - ? operand - : setTextRange(createParen(operand), operand); - } - - export function parenthesizeListElements(elements: NodeArray) { - let result: Expression[] | undefined; - for (let i = 0; i < elements.length; i++) { - const element = parenthesizeExpressionForList(elements[i]); - if (result !== undefined || element !== elements[i]) { - if (result === undefined) { - result = elements.slice(0, i); - } - - result.push(element); - } - } - - if (result !== undefined) { - return setTextRange(createNodeArray(result, elements.hasTrailingComma), elements); - } - - return elements; - } - - export function parenthesizeExpressionForList(expression: Expression) { - const emittedExpression = skipPartiallyEmittedExpressions(expression); - const expressionPrecedence = getExpressionPrecedence(emittedExpression); - const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken); - return expressionPrecedence > commaPrecedence - ? expression - : setTextRange(createParen(expression), expression); - } - - export function parenthesizeExpressionForExpressionStatement(expression: Expression) { - const emittedExpression = skipPartiallyEmittedExpressions(expression); - if (isCallExpression(emittedExpression)) { - const callee = emittedExpression.expression; - const kind = skipPartiallyEmittedExpressions(callee).kind; - if (kind === SyntaxKind.FunctionExpression || kind === SyntaxKind.ArrowFunction) { - const mutableCall = getMutableClone(emittedExpression); - mutableCall.expression = setTextRange(createParen(callee), callee); - return recreateOuterExpressions(expression, mutableCall, OuterExpressionKinds.PartiallyEmittedExpressions); - } - } - - const leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind; - if (leftmostExpressionKind === SyntaxKind.ObjectLiteralExpression || leftmostExpressionKind === SyntaxKind.FunctionExpression) { - return setTextRange(createParen(expression), expression); - } - - return expression; - } - - export function parenthesizeConditionalTypeMember(member: TypeNode) { - return member.kind === SyntaxKind.ConditionalType ? createParenthesizedType(member) : member; - } - - export function parenthesizeElementTypeMember(member: TypeNode) { - switch (member.kind) { - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - return createParenthesizedType(member); - } - return parenthesizeConditionalTypeMember(member); - } - - export function parenthesizeArrayTypeMember(member: TypeNode) { - switch (member.kind) { - case SyntaxKind.TypeQuery: - case SyntaxKind.TypeOperator: - case SyntaxKind.InferType: - return createParenthesizedType(member); - } - return parenthesizeElementTypeMember(member); - } - - export function parenthesizeElementTypeMembers(members: readonly TypeNode[]) { - return createNodeArray(sameMap(members, parenthesizeElementTypeMember)); - } - - export function parenthesizeTypeParameters(typeParameters: readonly TypeNode[] | undefined) { - if (some(typeParameters)) { - const params: TypeNode[] = []; - for (let i = 0; i < typeParameters.length; ++i) { - const entry = typeParameters[i]; - params.push(i === 0 && isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ? - createParenthesizedType(entry) : - entry); - } - - return createNodeArray(params); - } - } - - export function getLeftmostExpression(node: Expression, stopAtCallExpressions: boolean) { - while (true) { - switch (node.kind) { - case SyntaxKind.PostfixUnaryExpression: - node = (node).operand; - continue; - - case SyntaxKind.BinaryExpression: - node = (node).left; - continue; - - case SyntaxKind.ConditionalExpression: - node = (node).condition; - continue; - - case SyntaxKind.TaggedTemplateExpression: - node = (node).tag; - continue; - - case SyntaxKind.CallExpression: - if (stopAtCallExpressions) { - return node; - } - // falls through - case SyntaxKind.AsExpression: - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.NonNullExpression: - case SyntaxKind.PartiallyEmittedExpression: - node = (node).expression; - continue; - } - - return node; - } - - } - - export function parenthesizeConciseBody(body: ConciseBody): ConciseBody { - if (!isBlock(body) && (isCommaSequence(body) || getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === SyntaxKind.ObjectLiteralExpression)) { - return setTextRange(createParen(body), body); - } - - return body; - } - - export function isCommaSequence(node: Expression): node is BinaryExpression & {operatorToken: Token} | CommaListExpression { - return node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.CommaToken || - node.kind === SyntaxKind.CommaListExpression; - } - - export const enum OuterExpressionKinds { - Parentheses = 1 << 0, - TypeAssertions = 1 << 1, - NonNullAssertions = 1 << 2, - PartiallyEmittedExpressions = 1 << 3, - - Assertions = TypeAssertions | NonNullAssertions, - All = Parentheses | Assertions | PartiallyEmittedExpressions - } - - export type OuterExpression = ParenthesizedExpression | TypeAssertion | AsExpression | NonNullExpression | PartiallyEmittedExpression; - - export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression { - switch (node.kind) { - case SyntaxKind.ParenthesizedExpression: - return (kinds & OuterExpressionKinds.Parentheses) !== 0; - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - return (kinds & OuterExpressionKinds.TypeAssertions) !== 0; - case SyntaxKind.NonNullExpression: - return (kinds & OuterExpressionKinds.NonNullAssertions) !== 0; - case SyntaxKind.PartiallyEmittedExpression: - return (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) !== 0; - } - return false; - } - - export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; - export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node; - export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) { - while (isOuterExpression(node, kinds)) { - node = node.expression; - } - return node; - } - - export function skipAssertions(node: Expression): Expression; - export function skipAssertions(node: Node): Node; - export function skipAssertions(node: Node): Node { - return skipOuterExpressions(node, OuterExpressionKinds.Assertions); - } - - function updateOuterExpression(outerExpression: OuterExpression, expression: Expression) { - switch (outerExpression.kind) { - case SyntaxKind.ParenthesizedExpression: return updateParen(outerExpression, expression); - case SyntaxKind.TypeAssertionExpression: return updateTypeAssertion(outerExpression, outerExpression.type, expression); - case SyntaxKind.AsExpression: return updateAsExpression(outerExpression, expression, outerExpression.type); - case SyntaxKind.NonNullExpression: return updateNonNullExpression(outerExpression, expression); - case SyntaxKind.PartiallyEmittedExpression: return updatePartiallyEmittedExpression(outerExpression, expression); - } - } - - /** - * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions. - * - * A parenthesized expression can be ignored when all of the following are true: - * - * - It's `pos` and `end` are not -1 - * - It does not have a custom source map range - * - It does not have a custom comment range - * - It does not have synthetic leading or trailing comments - * - * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around - * the expression to maintain precedence, a new parenthesized expression should be created automatically when - * the containing expression is created/updated. - */ - function isIgnorableParen(node: Expression) { - return node.kind === SyntaxKind.ParenthesizedExpression - && nodeIsSynthesized(node) - && nodeIsSynthesized(getSourceMapRange(node)) - && nodeIsSynthesized(getCommentRange(node)) - && !some(getSyntheticLeadingComments(node)) - && !some(getSyntheticTrailingComments(node)); - } - - export function recreateOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression { - if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { - return updateOuterExpression( - outerExpression, - recreateOuterExpressions(outerExpression.expression, innerExpression) - ); - } - return innerExpression; - } - - export function startOnNewLine(node: T): T { - return setStartsOnNewLine(node, /*newLine*/ true); - } - - export function getExternalHelpersModuleName(node: SourceFile) { - const parseNode = getOriginalNode(node, isSourceFile); - const emitNode = parseNode && parseNode.emitNode; - return emitNode && emitNode.externalHelpersModuleName; - } - - export function hasRecordedExternalHelpers(sourceFile: SourceFile) { - const parseNode = getOriginalNode(sourceFile, isSourceFile); - const emitNode = parseNode && parseNode.emitNode; - return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers); - } - - export function createExternalHelpersImportDeclarationIfNeeded(sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) { - if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) { - let namedBindings: NamedImportBindings | undefined; - const moduleKind = getEmitModuleKind(compilerOptions); - if (moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) { - // use named imports - const helpers = getEmitHelpers(sourceFile); - if (helpers) { - const helperNames: string[] = []; - for (const helper of helpers) { - if (!helper.scoped) { - const importName = (helper as UnscopedEmitHelper).importName; - if (importName) { - pushIfUnique(helperNames, importName); - } - } - } - if (some(helperNames)) { - helperNames.sort(compareStringsCaseSensitive); - // Alias the imports if the names are used somewhere in the file. - // NOTE: We don't need to care about global import collisions as this is a module. - namedBindings = createNamedImports( - map(helperNames, name => isFileLevelUniqueName(sourceFile, name) - ? createImportSpecifier(/*propertyName*/ undefined, createIdentifier(name)) - : createImportSpecifier(createIdentifier(name), getUnscopedHelperName(name)) - ) - ); - const parseNode = getOriginalNode(sourceFile, isSourceFile); - const emitNode = getOrCreateEmitNode(parseNode); - emitNode.externalHelpers = true; - } - } - } - else { - // use a namespace import - const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar || hasImportDefault); - if (externalHelpersModuleName) { - namedBindings = createNamespaceImport(externalHelpersModuleName); - } - } - if (namedBindings) { - const externalHelpersImportDeclaration = createImportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - createImportClause(/*name*/ undefined, namedBindings), - createLiteral(externalHelpersModuleNameText) - ); - addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper); - return externalHelpersImportDeclaration; - } - } - } - - export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) { - if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) { - const externalHelpersModuleName = getExternalHelpersModuleName(node); - if (externalHelpersModuleName) { - return externalHelpersModuleName; - } - - const moduleKind = getEmitModuleKind(compilerOptions); - let create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault)) - && moduleKind !== ModuleKind.System - && moduleKind < ModuleKind.ES2015; - if (!create) { - const helpers = getEmitHelpers(node); - if (helpers) { - for (const helper of helpers) { - if (!helper.scoped) { - create = true; - break; - } - } - } - } - - if (create) { - const parseNode = getOriginalNode(node, isSourceFile); - const emitNode = getOrCreateEmitNode(parseNode); - return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText)); - } - } - } - - /** - * Get the name of that target module from an import or export declaration - */ - export function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier | undefined { - const namespaceDeclaration = getNamespaceDeclarationNode(node); - if (namespaceDeclaration && !isDefaultImport(node)) { - const name = namespaceDeclaration.name; - return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name)); - } - if (node.kind === SyntaxKind.ImportDeclaration && node.importClause) { - return getGeneratedNameForNode(node); - } - if (node.kind === SyntaxKind.ExportDeclaration && node.moduleSpecifier) { - return getGeneratedNameForNode(node); - } - return undefined; - } - - /** - * Get the name of a target module from an import/export declaration as should be written in the emitted output. - * The emitted output name can be different from the input if: - * 1. The module has a /// - * 2. --out or --outFile is used, making the name relative to the rootDir - * 3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System). - * Otherwise, a new StringLiteral node representing the module name will be returned. - */ - export function getExternalModuleNameLiteral(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { - const moduleName = getExternalModuleName(importNode)!; // TODO: GH#18217 - if (moduleName.kind === SyntaxKind.StringLiteral) { - return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions) - || tryRenameExternalModule(moduleName, sourceFile) - || getSynthesizedClone(moduleName); - } - - return undefined; - } - - /** - * Some bundlers (SystemJS builder) sometimes want to rename dependencies. - * Here we check if alternative name was provided for a given moduleName and return it if possible. - */ - function tryRenameExternalModule(moduleName: LiteralExpression, sourceFile: SourceFile) { - const rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text); - return rename && createLiteral(rename); - } - - /** - * Get the name of a module as should be written in the emitted output. - * The emitted output name can be different from the input if: - * 1. The module has a /// - * 2. --out or --outFile is used, making the name relative to the rootDir - * Otherwise, a new StringLiteral node representing the module name will be returned. - */ - export function tryGetModuleNameFromFile(file: SourceFile | undefined, host: EmitHost, options: CompilerOptions): StringLiteral | undefined { - if (!file) { - return undefined; - } - if (file.moduleName) { - return createLiteral(file.moduleName); - } - if (!file.isDeclarationFile && outFile(options)) { - return createLiteral(getExternalModuleNameFromPath(host, file.fileName)); - } - return undefined; - } - - function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { - return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions); - } - - /** - * Gets the initializer of an BindingOrAssignmentElement. - */ - export function getInitializerOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Expression | undefined { - if (isDeclarationBindingElement(bindingElement)) { - // `1` in `let { a = 1 } = ...` - // `1` in `let { a: b = 1 } = ...` - // `1` in `let { a: {b} = 1 } = ...` - // `1` in `let { a: [b] = 1 } = ...` - // `1` in `let [a = 1] = ...` - // `1` in `let [{a} = 1] = ...` - // `1` in `let [[a] = 1] = ...` - return bindingElement.initializer; - } - - if (isPropertyAssignment(bindingElement)) { - // `1` in `({ a: b = 1 } = ...)` - // `1` in `({ a: {b} = 1 } = ...)` - // `1` in `({ a: [b] = 1 } = ...)` - const initializer = bindingElement.initializer; - return isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true) - ? initializer.right - : undefined; - } - - if (isShorthandPropertyAssignment(bindingElement)) { - // `1` in `({ a = 1 } = ...)` - return bindingElement.objectAssignmentInitializer; - } - - if (isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { - // `1` in `[a = 1] = ...` - // `1` in `[{a} = 1] = ...` - // `1` in `[[a] = 1] = ...` - return bindingElement.right; - } - - if (isSpreadElement(bindingElement)) { - // Recovery consistent with existing emit. - return getInitializerOfBindingOrAssignmentElement(bindingElement.expression); - } - } - - /** - * Gets the name of an BindingOrAssignmentElement. - */ - export function getTargetOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementTarget | undefined { - if (isDeclarationBindingElement(bindingElement)) { - // `a` in `let { a } = ...` - // `a` in `let { a = 1 } = ...` - // `b` in `let { a: b } = ...` - // `b` in `let { a: b = 1 } = ...` - // `a` in `let { ...a } = ...` - // `{b}` in `let { a: {b} } = ...` - // `{b}` in `let { a: {b} = 1 } = ...` - // `[b]` in `let { a: [b] } = ...` - // `[b]` in `let { a: [b] = 1 } = ...` - // `a` in `let [a] = ...` - // `a` in `let [a = 1] = ...` - // `a` in `let [...a] = ...` - // `{a}` in `let [{a}] = ...` - // `{a}` in `let [{a} = 1] = ...` - // `[a]` in `let [[a]] = ...` - // `[a]` in `let [[a] = 1] = ...` - return bindingElement.name; - } - - if (isObjectLiteralElementLike(bindingElement)) { - switch (bindingElement.kind) { - case SyntaxKind.PropertyAssignment: - // `b` in `({ a: b } = ...)` - // `b` in `({ a: b = 1 } = ...)` - // `{b}` in `({ a: {b} } = ...)` - // `{b}` in `({ a: {b} = 1 } = ...)` - // `[b]` in `({ a: [b] } = ...)` - // `[b]` in `({ a: [b] = 1 } = ...)` - // `b.c` in `({ a: b.c } = ...)` - // `b.c` in `({ a: b.c = 1 } = ...)` - // `b[0]` in `({ a: b[0] } = ...)` - // `b[0]` in `({ a: b[0] = 1 } = ...)` - return getTargetOfBindingOrAssignmentElement(bindingElement.initializer); - - case SyntaxKind.ShorthandPropertyAssignment: - // `a` in `({ a } = ...)` - // `a` in `({ a = 1 } = ...)` - return bindingElement.name; - - case SyntaxKind.SpreadAssignment: - // `a` in `({ ...a } = ...)` - return getTargetOfBindingOrAssignmentElement(bindingElement.expression); - } - - // no target - return undefined; - } - - if (isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { - // `a` in `[a = 1] = ...` - // `{a}` in `[{a} = 1] = ...` - // `[a]` in `[[a] = 1] = ...` - // `a.b` in `[a.b = 1] = ...` - // `a[0]` in `[a[0] = 1] = ...` - return getTargetOfBindingOrAssignmentElement(bindingElement.left); - } - - if (isSpreadElement(bindingElement)) { - // `a` in `[...a] = ...` - return getTargetOfBindingOrAssignmentElement(bindingElement.expression); - } - - // `a` in `[a] = ...` - // `{a}` in `[{a}] = ...` - // `[a]` in `[[a]] = ...` - // `a.b` in `[a.b] = ...` - // `a[0]` in `[a[0]] = ...` - return bindingElement; - } - - /** - * Determines whether an BindingOrAssignmentElement is a rest element. - */ - export function getRestIndicatorOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementRestIndicator | undefined { - switch (bindingElement.kind) { - case SyntaxKind.Parameter: - case SyntaxKind.BindingElement: - // `...` in `let [...a] = ...` - return bindingElement.dotDotDotToken; - - case SyntaxKind.SpreadElement: - case SyntaxKind.SpreadAssignment: - // `...` in `[...a] = ...` - return bindingElement; - } - - return undefined; - } - - /** - * Gets the property name of a BindingOrAssignmentElement - */ - export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { - const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement); - Debug.assert(!!propertyName || isSpreadAssignment(bindingElement), "Invalid property name for binding element."); - return propertyName; - } - - export function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { - switch (bindingElement.kind) { - case SyntaxKind.BindingElement: - // `a` in `let { a: b } = ...` - // `[a]` in `let { [a]: b } = ...` - // `"a"` in `let { "a": b } = ...` - // `1` in `let { 1: b } = ...` - if (bindingElement.propertyName) { - const propertyName = bindingElement.propertyName; - if (isPrivateIdentifier(propertyName)) { - return Debug.failBadSyntaxKind(propertyName); - } - return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) - ? propertyName.expression - : propertyName; - } - - break; - - case SyntaxKind.PropertyAssignment: - // `a` in `({ a: b } = ...)` - // `[a]` in `({ [a]: b } = ...)` - // `"a"` in `({ "a": b } = ...)` - // `1` in `({ 1: b } = ...)` - if (bindingElement.name) { - const propertyName = bindingElement.name; - if (isPrivateIdentifier(propertyName)) { - return Debug.failBadSyntaxKind(propertyName); - } - return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) - ? propertyName.expression - : propertyName; - } - - break; - - case SyntaxKind.SpreadAssignment: - // `a` in `({ ...a } = ...)` - if (bindingElement.name && isPrivateIdentifier(bindingElement.name)) { - return Debug.failBadSyntaxKind(bindingElement.name); - } - return bindingElement.name; - } - - const target = getTargetOfBindingOrAssignmentElement(bindingElement); - if (target && isPropertyName(target)) { - return target; - } - } - - function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral { - const kind = node.kind; - return kind === SyntaxKind.StringLiteral - || kind === SyntaxKind.NumericLiteral; - } - - /** - * Gets the elements of a BindingOrAssignmentPattern - */ - export function getElementsOfBindingOrAssignmentPattern(name: BindingOrAssignmentPattern): readonly BindingOrAssignmentElement[] { - switch (name.kind) { - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ArrayLiteralExpression: - // `a` in `{a}` - // `a` in `[a]` - return name.elements; - - case SyntaxKind.ObjectLiteralExpression: - // `a` in `{a}` - return name.properties; - } - } - - export function convertToArrayAssignmentElement(element: BindingOrAssignmentElement) { - if (isBindingElement(element)) { - if (element.dotDotDotToken) { - Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(setTextRange(createSpread(element.name), element), element); - } - const expression = convertToAssignmentElementTarget(element.name); - return element.initializer - ? setOriginalNode( - setTextRange( - createAssignment(expression, element.initializer), - element - ), - element - ) - : expression; - } - Debug.assertNode(element, isExpression); - return element; - } - - export function convertToObjectAssignmentElement(element: BindingOrAssignmentElement) { - if (isBindingElement(element)) { - if (element.dotDotDotToken) { - Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(setTextRange(createSpreadAssignment(element.name), element), element); - } - if (element.propertyName) { - const expression = convertToAssignmentElementTarget(element.name); - return setOriginalNode(setTextRange(createPropertyAssignment(element.propertyName, element.initializer ? createAssignment(expression, element.initializer) : expression), element), element); - } - Debug.assertNode(element.name, isIdentifier); - return setOriginalNode(setTextRange(createShorthandPropertyAssignment(element.name, element.initializer), element), element); - } - Debug.assertNode(element, isObjectLiteralElementLike); - return element; - } - - export function convertToAssignmentPattern(node: BindingOrAssignmentPattern): AssignmentPattern { - switch (node.kind) { - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.ArrayLiteralExpression: - return convertToArrayAssignmentPattern(node); - - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ObjectLiteralExpression: - return convertToObjectAssignmentPattern(node); - } - } - - export function convertToObjectAssignmentPattern(node: ObjectBindingOrAssignmentPattern) { - if (isObjectBindingPattern(node)) { - return setOriginalNode( - setTextRange( - createObjectLiteral(map(node.elements, convertToObjectAssignmentElement)), - node - ), - node - ); - } - Debug.assertNode(node, isObjectLiteralExpression); - return node; - } - - export function convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern) { - if (isArrayBindingPattern(node)) { - return setOriginalNode( - setTextRange( - createArrayLiteral(map(node.elements, convertToArrayAssignmentElement)), - node - ), - node - ); - } - Debug.assertNode(node, isArrayLiteralExpression); - return node; - } - - export function convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression { - if (isBindingPattern(node)) { - return convertToAssignmentPattern(node); - } - - Debug.assertNode(node, isExpression); - return node; - } -} diff --git a/src/compiler/factory/baseNodeFactory.ts b/src/compiler/factory/baseNodeFactory.ts new file mode 100644 index 0000000000000..26be7e95ef237 --- /dev/null +++ b/src/compiler/factory/baseNodeFactory.ts @@ -0,0 +1,56 @@ +/* @internal */ +namespace ts { + /** + * A `BaseNodeFactory` is an abstraction over an `ObjectAllocator` that handles caching `Node` constructors + * and allocating `Node` instances based on a set of predefined types. + */ + /* @internal */ + export interface BaseNodeFactory { + createBaseSourceFileNode(kind: SyntaxKind): Node; + createBaseIdentifierNode(kind: SyntaxKind): Node; + createBasePrivateIdentifierNode(kind: SyntaxKind): Node; + createBaseTokenNode(kind: SyntaxKind): Node; + createBaseNode(kind: SyntaxKind): Node; + } + + /** + * Creates a `BaseNodeFactory` which can be used to create `Node` instances from the constructors provided by the object allocator. + */ + export function createBaseNodeFactory(): BaseNodeFactory { + // tslint:disable variable-name + let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + // tslint:enable variable-name + + return { + createBaseSourceFileNode, + createBaseIdentifierNode, + createBasePrivateIdentifierNode, + createBaseTokenNode, + createBaseNode + }; + + function createBaseSourceFileNode(kind: SyntaxKind): Node { + return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + } + + function createBaseIdentifierNode(kind: SyntaxKind): Node { + return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + } + + function createBasePrivateIdentifierNode(kind: SyntaxKind): Node { + return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + } + + function createBaseTokenNode(kind: SyntaxKind): Node { + return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + } + + function createBaseNode(kind: SyntaxKind): Node { + return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, /*pos*/ -1, /*end*/ -1); + } + } +} \ No newline at end of file diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts new file mode 100644 index 0000000000000..9a76e759a2671 --- /dev/null +++ b/src/compiler/factory/emitHelpers.ts @@ -0,0 +1,890 @@ +/* @internal */ +namespace ts { + export interface EmitHelperFactory { + getUnscopedHelperName(name: string): Identifier; + // TypeScript Helpers + createDecorateHelper(decoratorExpressions: readonly Expression[], target: Expression, memberName?: Expression, descriptor?: Expression): Expression; + createMetadataHelper(metadataKey: string, metadataValue: Expression): Expression; + createParamHelper(expression: Expression, parameterOffset: number): Expression; + // ES2018 Helpers + createAssignHelper(attributesSegments: readonly Expression[]): Expression; + createAwaitHelper(expression: Expression): Expression; + createAsyncGeneratorHelper(generatorFunc: FunctionExpression, hasLexicalThis: boolean): Expression; + createAsyncDelegatorHelper(expression: Expression): Expression; + createAsyncValuesHelper(expression: Expression): Expression; + // ES2018 Destructuring Helpers + createRestHelper(value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[] | undefined, location: TextRange): Expression; + // ES2017 Helpers + createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block): Expression; + // ES2015 Helpers + createExtendsHelper(name: Identifier): Expression; + createTemplateObjectHelper(cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression): Expression; + createSpreadHelper(argumentList: readonly Expression[]): Expression; + createSpreadArraysHelper(argumentList: readonly Expression[]): Expression; + // ES2015 Destructuring Helpers + createValuesHelper(expression: Expression): Expression; + createReadHelper(iteratorRecord: Expression, count: number | undefined): Expression; + // ES2015 Generator Helpers + createGeneratorHelper(body: FunctionExpression): Expression; + // ES Module Helpers + createCreateBindingHelper(module: Expression, inputName: Expression, outputName: Expression | undefined): Expression; + createImportStarHelper(expression: Expression): Expression; + createImportStarCallbackHelper(): Expression; + createImportDefaultHelper(expression: Expression): Expression; + // Class Fields Helpers + createClassPrivateFieldGetHelper(receiver: Expression, privateField: Identifier): Expression; + createClassPrivateFieldSetHelper(receiver: Expression, privateField: Identifier, value: Expression): Expression; + } + + export function createEmitHelperFactory(context: TransformationContext): EmitHelperFactory { + const factory = context.factory; + return { + getUnscopedHelperName, + // TypeScript Helpers + createDecorateHelper, + createMetadataHelper, + createParamHelper, + // ES2018 Helpers + createAssignHelper, + createAwaitHelper, + createAsyncGeneratorHelper, + createAsyncDelegatorHelper, + createAsyncValuesHelper, + // ES2018 Destructuring Helpers + createRestHelper, + // ES2017 Helpers + createAwaiterHelper, + // ES2015 Helpers + createExtendsHelper, + createTemplateObjectHelper, + createSpreadHelper, + createSpreadArraysHelper, + // ES2015 Destructuring Helpers + createValuesHelper, + createReadHelper, + // ES2015 Generator Helpers + createGeneratorHelper, + // ES Module Helpers + createCreateBindingHelper, + createImportStarHelper, + createImportStarCallbackHelper, + createImportDefaultHelper, + // Class Fields Helpers + createClassPrivateFieldGetHelper, + createClassPrivateFieldSetHelper, + }; + + /** + * Gets an identifier for the name of an *unscoped* emit helper. + */ + function getUnscopedHelperName(name: string) { + return setEmitFlags(factory.createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode); + } + + // TypeScript Helpers + + function createDecorateHelper(decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression) { + context.requestEmitHelper(decorateHelper); + + const argumentsArray: Expression[] = []; + argumentsArray.push(factory.createArrayLiteralExpression(decoratorExpressions, /*multiLine*/ true)); + argumentsArray.push(target); + if (memberName) { + argumentsArray.push(memberName); + if (descriptor) { + argumentsArray.push(descriptor); + } + } + + return factory.createCallExpression( + getUnscopedHelperName("__decorate"), + /*typeArguments*/ undefined, + argumentsArray + ); + } + + function createMetadataHelper(metadataKey: string, metadataValue: Expression) { + context.requestEmitHelper(metadataHelper); + return factory.createCallExpression( + getUnscopedHelperName("__metadata"), + /*typeArguments*/ undefined, + [ + factory.createStringLiteral(metadataKey), + metadataValue + ] + ); + } + + function createParamHelper(expression: Expression, parameterOffset: number, location?: TextRange) { + context.requestEmitHelper(paramHelper); + return setTextRange( + factory.createCallExpression( + getUnscopedHelperName("__param"), + /*typeArguments*/ undefined, + [ + factory.createNumericLiteral(parameterOffset + ""), + expression + ] + ), + location + ); + } + + // ES2018 Helpers + + function createAssignHelper(attributesSegments: Expression[]) { + if (context.getCompilerOptions().target! >= ScriptTarget.ES2015) { + return factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "assign"), + /*typeArguments*/ undefined, + attributesSegments); + } + context.requestEmitHelper(assignHelper); + return factory.createCallExpression( + getUnscopedHelperName("__assign"), + /*typeArguments*/ undefined, + attributesSegments + ); + } + + function createAwaitHelper(expression: Expression) { + context.requestEmitHelper(awaitHelper); + return factory.createCallExpression(getUnscopedHelperName("__await"), /*typeArguments*/ undefined, [expression]); + } + + function createAsyncGeneratorHelper(generatorFunc: FunctionExpression, hasLexicalThis: boolean) { + context.requestEmitHelper(awaitHelper); + context.requestEmitHelper(asyncGeneratorHelper); + + // Mark this node as originally an async function + (generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; + + return factory.createCallExpression( + getUnscopedHelperName("__asyncGenerator"), + /*typeArguments*/ undefined, + [ + hasLexicalThis ? factory.createThis() : factory.createVoidZero(), + factory.createIdentifier("arguments"), + generatorFunc + ] + ); + } + + function createAsyncDelegatorHelper(expression: Expression) { + context.requestEmitHelper(awaitHelper); + context.requestEmitHelper(asyncDelegator); + return factory.createCallExpression( + getUnscopedHelperName("__asyncDelegator"), + /*typeArguments*/ undefined, + [expression] + ); + } + + function createAsyncValuesHelper(expression: Expression) { + context.requestEmitHelper(asyncValues); + return factory.createCallExpression( + getUnscopedHelperName("__asyncValues"), + /*typeArguments*/ undefined, + [expression] + ); + } + + // ES2018 Destructuring Helpers + + /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement + * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);` + */ + function createRestHelper(value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[] | undefined, location: TextRange): Expression { + context.requestEmitHelper(restHelper); + const propertyNames: Expression[] = []; + let computedTempVariableOffset = 0; + for (let i = 0; i < elements.length - 1; i++) { + const propertyName = getPropertyNameOfBindingOrAssignmentElement(elements[i]); + if (propertyName) { + if (isComputedPropertyName(propertyName)) { + Debug.assertIsDefined(computedTempVariables, "Encountered computed property name but 'computedTempVariables' argument was not provided."); + const temp = computedTempVariables[computedTempVariableOffset]; + computedTempVariableOffset++; + // typeof _tmp === "symbol" ? _tmp : _tmp + "" + propertyNames.push( + factory.createConditionalExpression( + factory.createTypeCheck(temp, "symbol"), + /*questionToken*/ undefined, + temp, + /*colonToken*/ undefined, + factory.createAdd(temp, factory.createStringLiteral("")) + ) + ); + } + else { + propertyNames.push(factory.createStringLiteralFromNode(propertyName)); + } + } + } + return factory.createCallExpression( + getUnscopedHelperName("__rest"), + /*typeArguments*/ undefined, + [ + value, + setTextRange( + factory.createArrayLiteralExpression(propertyNames), + location + )] + ); + } + + // ES2017 Helpers + + function createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block) { + context.requestEmitHelper(awaiterHelper); + + const generatorFunc = factory.createFunctionExpression( + /*modifiers*/ undefined, + factory.createToken(SyntaxKind.AsteriskToken), + /*name*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ [], + /*type*/ undefined, + body + ); + + // Mark this node as originally an async function + (generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; + + return factory.createCallExpression( + getUnscopedHelperName("__awaiter"), + /*typeArguments*/ undefined, + [ + hasLexicalThis ? factory.createThis() : factory.createVoidZero(), + hasLexicalArguments ? factory.createIdentifier("arguments") : factory.createVoidZero(), + promiseConstructor ? createExpressionFromEntityName(factory, promiseConstructor) : factory.createVoidZero(), + generatorFunc + ] + ); + } + + // ES2015 Helpers + + function createExtendsHelper(name: Identifier) { + context.requestEmitHelper(extendsHelper); + return factory.createCallExpression( + getUnscopedHelperName("__extends"), + /*typeArguments*/ undefined, + [name, factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)] + ); + } + + function createTemplateObjectHelper(cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression) { + context.requestEmitHelper(templateObjectHelper); + return factory.createCallExpression( + getUnscopedHelperName("__makeTemplateObject"), + /*typeArguments*/ undefined, + [cooked, raw] + ); + } + + function createSpreadHelper(argumentList: readonly Expression[]) { + context.requestEmitHelper(readHelper); + context.requestEmitHelper(spreadHelper); + return factory.createCallExpression( + getUnscopedHelperName("__spread"), + /*typeArguments*/ undefined, + argumentList + ); + } + + function createSpreadArraysHelper(argumentList: readonly Expression[]) { + context.requestEmitHelper(spreadArraysHelper); + return factory.createCallExpression( + getUnscopedHelperName("__spreadArrays"), + /*typeArguments*/ undefined, + argumentList + ); + } + + // ES2015 Destructuring Helpers + + function createValuesHelper(expression: Expression) { + context.requestEmitHelper(valuesHelper); + return factory.createCallExpression( + getUnscopedHelperName("__values"), + /*typeArguments*/ undefined, + [expression] + ); + } + + function createReadHelper(iteratorRecord: Expression, count: number | undefined) { + context.requestEmitHelper(readHelper); + return factory.createCallExpression( + getUnscopedHelperName("__read"), + /*typeArguments*/ undefined, + count !== undefined + ? [iteratorRecord, factory.createNumericLiteral(count + "")] + : [iteratorRecord] + ); + } + + // ES2015 Generator Helpers + + function createGeneratorHelper(body: FunctionExpression) { + context.requestEmitHelper(generatorHelper); + return factory.createCallExpression( + getUnscopedHelperName("__generator"), + /*typeArguments*/ undefined, + [factory.createThis(), body]); + } + + // ES Module Helpers + + function createCreateBindingHelper(module: Expression, inputName: Expression, outputName: Expression | undefined) { + context.requestEmitHelper(createBindingHelper); + return factory.createCallExpression( + getUnscopedHelperName("__createBinding"), + /*typeArguments*/ undefined, + [factory.createIdentifier("exports"), module, inputName, ...(outputName ? [outputName] : [])]); + } + + function createImportStarHelper(expression: Expression) { + context.requestEmitHelper(importStarHelper); + return factory.createCallExpression( + getUnscopedHelperName("__importStar"), + /*typeArguments*/ undefined, + [expression] + ); + } + + function createImportStarCallbackHelper() { + context.requestEmitHelper(importStarHelper); + return getUnscopedHelperName("__importStar"); + } + + function createImportDefaultHelper(expression: Expression) { + context.requestEmitHelper(importDefaultHelper); + return factory.createCallExpression( + getUnscopedHelperName("__importDefault"), + /*typeArguments*/ undefined, + [expression] + ); + } + + // Class Fields Helpers + + function createClassPrivateFieldGetHelper(receiver: Expression, privateField: Identifier) { + context.requestEmitHelper(classPrivateFieldGetHelper); + return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldGet"), /*typeArguments*/ undefined, [receiver, privateField]); + } + + function createClassPrivateFieldSetHelper(receiver: Expression, privateField: Identifier, value: Expression) { + context.requestEmitHelper(classPrivateFieldSetHelper); + return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldSet"), /*typeArguments*/ undefined, [receiver, privateField, value]); + } + } + + /* @internal */ + export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) { + if (x === y) return Comparison.EqualTo; + if (x.priority === y.priority) return Comparison.EqualTo; + if (x.priority === undefined) return Comparison.GreaterThan; + if (y.priority === undefined) return Comparison.LessThan; + return compareValues(x.priority, y.priority); + } + + /** + * @param input Template string input strings + * @param args Names which need to be made file-level unique + */ + export function helperString(input: TemplateStringsArray, ...args: string[]) { + return (uniqueName: EmitHelperUniqueNameCallback) => { + let result = ""; + for (let i = 0; i < args.length; i++) { + result += input[i]; + result += uniqueName(args[i]); + } + result += input[input.length - 1]; + return result; + }; + } + + // TypeScript Helpers + + export const decorateHelper: UnscopedEmitHelper = { + name: "typescript:decorate", + importName: "__decorate", + scoped: false, + priority: 2, + text: ` + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + };` + }; + + export const metadataHelper: UnscopedEmitHelper = { + name: "typescript:metadata", + importName: "__metadata", + scoped: false, + priority: 3, + text: ` + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + };` + }; + + export const paramHelper: UnscopedEmitHelper = { + name: "typescript:param", + importName: "__param", + scoped: false, + priority: 4, + text: ` + var __param = (this && this.__param) || function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } + };` + }; + + // ES2018 Helpers + + export const assignHelper: UnscopedEmitHelper = { + name: "typescript:assign", + importName: "__assign", + scoped: false, + priority: 1, + text: ` + var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + };` + }; + + export const awaitHelper: UnscopedEmitHelper = { + name: "typescript:await", + importName: "__await", + scoped: false, + text: ` + var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }` + }; + + export const asyncGeneratorHelper: UnscopedEmitHelper = { + name: "typescript:asyncGenerator", + importName: "__asyncGenerator", + scoped: false, + dependencies: [awaitHelper], + text: ` + var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } + };` + }; + + export const asyncDelegator: UnscopedEmitHelper = { + name: "typescript:asyncDelegator", + importName: "__asyncDelegator", + scoped: false, + dependencies: [awaitHelper], + text: ` + var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } + };` + }; + + export const asyncValues: UnscopedEmitHelper = { + name: "typescript:asyncValues", + importName: "__asyncValues", + scoped: false, + text: ` + var __asyncValues = (this && this.__asyncValues) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } + };` + }; + + // ES2018 Destructuring Helpers + + export const restHelper: UnscopedEmitHelper = { + name: "typescript:rest", + importName: "__rest", + scoped: false, + text: ` + var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + };` + }; + + // ES2017 Helpers + + export const awaiterHelper: UnscopedEmitHelper = { + name: "typescript:awaiter", + importName: "__awaiter", + scoped: false, + priority: 5, + text: ` + var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + };` + }; + + // ES2015 Helpers + + export const extendsHelper: UnscopedEmitHelper = { + name: "typescript:extends", + importName: "__extends", + scoped: false, + priority: 0, + text: ` + var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + })();` + }; + + export const templateObjectHelper: UnscopedEmitHelper = { + name: "typescript:makeTemplateObject", + importName: "__makeTemplateObject", + scoped: false, + priority: 0, + text: ` + var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; + };` + }; + + export const readHelper: UnscopedEmitHelper = { + name: "typescript:read", + importName: "__read", + scoped: false, + text: ` + var __read = (this && this.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; + };` + }; + + export const spreadHelper: UnscopedEmitHelper = { + name: "typescript:spread", + importName: "__spread", + scoped: false, + dependencies: [readHelper], + text: ` + var __spread = (this && this.__spread) || function () { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + return ar; + };` + }; + + export const spreadArraysHelper: UnscopedEmitHelper = { + name: "typescript:spreadArrays", + importName: "__spreadArrays", + scoped: false, + text: ` + var __spreadArrays = (this && this.__spreadArrays) || function () { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; + };` + }; + + // ES2015 Destructuring Helpers + + export const valuesHelper: UnscopedEmitHelper = { + name: "typescript:values", + importName: "__values", + scoped: false, + text: ` + var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + };` + }; + + // ES2015 Generator Helpers + + // The __generator helper is used by down-level transformations to emulate the runtime + // semantics of an ES2015 generator function. When called, this helper returns an + // object that implements the Iterator protocol, in that it has `next`, `return`, and + // `throw` methods that step through the generator when invoked. + // + // parameters: + // @param thisArg The value to use as the `this` binding for the transformed generator body. + // @param body A function that acts as the transformed generator body. + // + // variables: + // _ Persistent state for the generator that is shared between the helper and the + // generator body. The state object has the following members: + // sent() - A method that returns or throws the current completion value. + // label - The next point at which to resume evaluation of the generator body. + // trys - A stack of protected regions (try/catch/finally blocks). + // ops - A stack of pending instructions when inside of a finally block. + // f A value indicating whether the generator is executing. + // y An iterator to delegate for a yield*. + // t A temporary variable that holds one of the following values (note that these + // cases do not overlap): + // - The completion value when resuming from a `yield` or `yield*`. + // - The error value for a catch block. + // - The current protected region (array of try/catch/finally/end labels). + // - The verb (`next`, `throw`, or `return` method) to delegate to the expression + // of a `yield*`. + // - The result of evaluating the verb delegated to the expression of a `yield*`. + // + // functions: + // verb(n) Creates a bound callback to the `step` function for opcode `n`. + // step(op) Evaluates opcodes in a generator body until execution is suspended or + // completed. + // + // The __generator helper understands a limited set of instructions: + // 0: next(value?) - Start or resume the generator with the specified value. + // 1: throw(error) - Resume the generator with an exception. If the generator is + // suspended inside of one or more protected regions, evaluates + // any intervening finally blocks between the current label and + // the nearest catch block or function boundary. If uncaught, the + // exception is thrown to the caller. + // 2: return(value?) - Resume the generator as if with a return. If the generator is + // suspended inside of one or more protected regions, evaluates any + // intervening finally blocks. + // 3: break(label) - Jump to the specified label. If the label is outside of the + // current protected region, evaluates any intervening finally + // blocks. + // 4: yield(value?) - Yield execution to the caller with an optional value. When + // resumed, the generator will continue at the next label. + // 5: yield*(value) - Delegates evaluation to the supplied iterator. When + // delegation completes, the generator will continue at the next + // label. + // 6: catch(error) - Handles an exception thrown from within the generator body. If + // the current label is inside of one or more protected regions, + // evaluates any intervening finally blocks between the current + // label and the nearest catch block or function boundary. If + // uncaught, the exception is thrown to the caller. + // 7: endfinally - Ends a finally block, resuming the last instruction prior to + // entering a finally block. + // + // For examples of how these are used, see the comments in ./transformers/generators.ts + export const generatorHelper: UnscopedEmitHelper = { + name: "typescript:generator", + importName: "__generator", + scoped: false, + priority: 6, + text: ` + var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } + };` + }; + + // ES Module Helpers + + export const createBindingHelper: UnscopedEmitHelper = { + name: "typescript:commonjscreatebinding", + importName: "__createBinding", + scoped: false, + priority: 1, + text: ` + var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }));` + }; + + export const setModuleDefaultHelper: UnscopedEmitHelper = { + name: "typescript:commonjscreatevalue", + importName: "__setModuleDefault", + scoped: false, + priority: 1, + text: ` + var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + });` + }; + + // emit helper for `import * as Name from "foo"` + export const importStarHelper: UnscopedEmitHelper = { + name: "typescript:commonjsimportstar", + importName: "__importStar", + scoped: false, + dependencies: [createBindingHelper, setModuleDefaultHelper], + priority: 2, + text: ` + var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; + };` + }; + + // emit helper for `import Name from "foo"` + export const importDefaultHelper: UnscopedEmitHelper = { + name: "typescript:commonjsimportdefault", + importName: "__importDefault", + scoped: false, + text: ` + var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + };` + }; + + // Class fields helpers + export const classPrivateFieldGetHelper: UnscopedEmitHelper = { + name: "typescript:classPrivateFieldGet", + scoped: false, + text: ` + var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); + };` + }; + + export const classPrivateFieldSetHelper: UnscopedEmitHelper = { + name: "typescript:classPrivateFieldSet", + scoped: false, + text: ` + var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; + };` + }; + + let allUnscopedEmitHelpers: ReadonlyMap | undefined; + + export function getAllUnscopedEmitHelpers() { + return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = arrayToMap([ + decorateHelper, + metadataHelper, + paramHelper, + assignHelper, + awaitHelper, + asyncGeneratorHelper, + asyncDelegator, + asyncValues, + restHelper, + awaiterHelper, + extendsHelper, + templateObjectHelper, + spreadHelper, + spreadArraysHelper, + valuesHelper, + readHelper, + generatorHelper, + importStarHelper, + importDefaultHelper, + classPrivateFieldGetHelper, + classPrivateFieldSetHelper, + createBindingHelper, + setModuleDefaultHelper + ], helper => helper.name)); + } + + export const asyncSuperHelper: EmitHelper = { + name: "typescript:async-super", + scoped: true, + text: helperString` + const ${"_superIndex"} = name => super[name];` + }; + + export const advancedAsyncSuperHelper: EmitHelper = { + name: "typescript:advanced-async-super", + scoped: true, + text: helperString` + const ${"_superIndex"} = (function (geti, seti) { + const cache = Object.create(null); + return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); + })(name => super[name], (name, value) => super[name] = value);` + }; +} \ No newline at end of file diff --git a/src/compiler/factory/emitNode.ts b/src/compiler/factory/emitNode.ts new file mode 100644 index 0000000000000..1da968d027dec --- /dev/null +++ b/src/compiler/factory/emitNode.ts @@ -0,0 +1,262 @@ +namespace ts { + /** + * Associates a node with the current transformation, initializing + * various transient transformation properties. + * @internal + */ + export function getOrCreateEmitNode(node: Node): EmitNode { + if (!node.emitNode) { + if (isParseTreeNode(node)) { + // To avoid holding onto transformation artifacts, we keep track of any + // parse tree node we are annotating. This allows us to clean them up after + // all transformations have completed. + if (node.kind === SyntaxKind.SourceFile) { + return node.emitNode = { annotatedNodes: [node] } as EmitNode; + } + + const sourceFile = getSourceFileOfNode(getParseTreeNode(getSourceFileOfNode(node))) ?? Debug.fail("Could not determine parsed source file."); + getOrCreateEmitNode(sourceFile).annotatedNodes!.push(node); + } + + node.emitNode = {} as EmitNode; + } + + return node.emitNode; + } + + /** + * Clears any `EmitNode` entries from parse-tree nodes. + * @param sourceFile A source file. + */ + export function disposeEmitNodes(sourceFile: SourceFile | undefined) { + // During transformation we may need to annotate a parse tree node with transient + // transformation properties. As parse tree nodes live longer than transformation + // nodes, we need to make sure we reclaim any memory allocated for custom ranges + // from these nodes to ensure we do not hold onto entire subtrees just for position + // information. We also need to reset these nodes to a pre-transformation state + // for incremental parsing scenarios so that we do not impact later emit. + const annotatedNodes = getSourceFileOfNode(getParseTreeNode(sourceFile))?.emitNode?.annotatedNodes; + if (annotatedNodes) { + for (const node of annotatedNodes) { + node.emitNode = undefined; + } + } + } + + /** + * Sets `EmitFlags.NoComments` on a node and removes any leading and trailing synthetic comments. + * @internal + */ + export function removeAllComments(node: T): T { + const emitNode = getOrCreateEmitNode(node); + emitNode.flags |= EmitFlags.NoComments; + emitNode.leadingComments = undefined; + emitNode.trailingComments = undefined; + return node; + } + + /** + * Sets flags that control emit behavior of a node. + */ + export function setEmitFlags(node: T, emitFlags: EmitFlags) { + getOrCreateEmitNode(node).flags = emitFlags; + return node; + } + + /** + * Sets flags that control emit behavior of a node. + */ + /* @internal */ + export function addEmitFlags(node: T, emitFlags: EmitFlags) { + const emitNode = getOrCreateEmitNode(node); + emitNode.flags = emitNode.flags | emitFlags; + return node; + } + + /** + * Gets a custom text range to use when emitting source maps. + */ + export function getSourceMapRange(node: Node): SourceMapRange { + return node.emitNode?.sourceMapRange ?? node; + } + + /** + * Sets a custom text range to use when emitting source maps. + */ + export function setSourceMapRange(node: T, range: SourceMapRange | undefined) { + getOrCreateEmitNode(node).sourceMapRange = range; + return node; + } + + /** + * Gets the TextRange to use for source maps for a token of a node. + */ + export function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined { + return node.emitNode?.tokenSourceMapRanges?.[token]; + } + + /** + * Sets the TextRange to use for source maps for a token of a node. + */ + export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined) { + const emitNode = getOrCreateEmitNode(node); + const tokenSourceMapRanges = emitNode.tokenSourceMapRanges ?? (emitNode.tokenSourceMapRanges = []); + tokenSourceMapRanges[token] = range; + return node; + } + + /** + * Gets a custom text range to use when emitting comments. + */ + /*@internal*/ + export function getStartsOnNewLine(node: Node) { + return node.emitNode?.startsOnNewLine; + } + + /** + * Sets a custom text range to use when emitting comments. + */ + /*@internal*/ + export function setStartsOnNewLine(node: T, newLine: boolean) { + getOrCreateEmitNode(node).startsOnNewLine = newLine; + return node; + } + + /** + * Gets a custom text range to use when emitting comments. + */ + export function getCommentRange(node: Node) { + return node.emitNode?.commentRange ?? node; + } + + /** + * Sets a custom text range to use when emitting comments. + */ + export function setCommentRange(node: T, range: TextRange) { + getOrCreateEmitNode(node).commentRange = range; + return node; + } + + export function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined { + return node.emitNode?.leadingComments; + } + + export function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined) { + getOrCreateEmitNode(node).leadingComments = comments; + return node; + } + + export function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { + return setSyntheticLeadingComments(node, append(getSyntheticLeadingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); + } + + export function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined { + return node.emitNode?.trailingComments; + } + + export function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined) { + getOrCreateEmitNode(node).trailingComments = comments; + return node; + } + + export function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { + return setSyntheticTrailingComments(node, append(getSyntheticTrailingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); + } + + export function moveSyntheticComments(node: T, original: Node): T { + setSyntheticLeadingComments(node, getSyntheticLeadingComments(original)); + setSyntheticTrailingComments(node, getSyntheticTrailingComments(original)); + const emit = getOrCreateEmitNode(original); + emit.leadingComments = undefined; + emit.trailingComments = undefined; + return node; + } + + /** + * Gets the constant value to emit for an expression representing an enum. + */ + export function getConstantValue(node: AccessExpression): string | number | undefined { + return node.emitNode?.constantValue; + } + + /** + * Sets the constant value to emit for an expression. + */ + export function setConstantValue(node: AccessExpression, value: string | number): AccessExpression { + const emitNode = getOrCreateEmitNode(node); + emitNode.constantValue = value; + return node; + } + + /** + * Adds an EmitHelper to a node. + */ + export function addEmitHelper(node: T, helper: EmitHelper): T { + const emitNode = getOrCreateEmitNode(node); + emitNode.helpers = append(emitNode.helpers, helper); + return node; + } + + /** + * Add EmitHelpers to a node. + */ + export function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T { + if (some(helpers)) { + const emitNode = getOrCreateEmitNode(node); + for (const helper of helpers) { + emitNode.helpers = appendIfUnique(emitNode.helpers, helper); + } + } + return node; + } + + /** + * Removes an EmitHelper from a node. + */ + export function removeEmitHelper(node: Node, helper: EmitHelper): boolean { + const helpers = node.emitNode?.helpers; + if (helpers) { + return orderedRemoveItem(helpers, helper); + } + return false; + } + + /** + * Gets the EmitHelpers of a node. + */ + export function getEmitHelpers(node: Node): EmitHelper[] | undefined { + return node.emitNode?.helpers; + } + + /** + * Moves matching emit helpers from a source node to a target node. + */ + export function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean) { + const sourceEmitNode = source.emitNode; + const sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers; + if (!some(sourceEmitHelpers)) return; + + const targetEmitNode = getOrCreateEmitNode(target); + let helpersRemoved = 0; + for (let i = 0; i < sourceEmitHelpers.length; i++) { + const helper = sourceEmitHelpers[i]; + if (predicate(helper)) { + helpersRemoved++; + targetEmitNode.helpers = appendIfUnique(targetEmitNode.helpers, helper); + } + else if (helpersRemoved > 0) { + sourceEmitHelpers[i - helpersRemoved] = helper; + } + } + + if (helpersRemoved > 0) { + sourceEmitHelpers.length -= helpersRemoved; + } + } + + /* @internal */ + export function ignoreSourceNewlines(node: T): T { + getOrCreateEmitNode(node).flags |= EmitFlags.IgnoreSourceNewlines; + return node; + } +} \ No newline at end of file diff --git a/src/compiler/factory/nodeConverters.ts b/src/compiler/factory/nodeConverters.ts new file mode 100644 index 0000000000000..08aff2a91cd87 --- /dev/null +++ b/src/compiler/factory/nodeConverters.ts @@ -0,0 +1,137 @@ +/* @internal */ +namespace ts { + export function createNodeConverters(factory: NodeFactory): NodeConverters { + return { + convertToFunctionBlock, + convertToFunctionExpression, + convertToArrayAssignmentElement, + convertToObjectAssignmentElement, + convertToAssignmentPattern, + convertToObjectAssignmentPattern, + convertToArrayAssignmentPattern, + convertToAssignmentElementTarget, + }; + + function convertToFunctionBlock(node: ConciseBody, multiLine?: boolean): Block { + if (isBlock(node)) return node; + const returnStatement = factory.createReturnStatement(node); + setTextRange(returnStatement, node); + const body = factory.createBlock([returnStatement], multiLine); + setTextRange(body, node); + return body; + } + + function convertToFunctionExpression(node: FunctionDeclaration) { + if (!node.body) return Debug.fail(`Cannot convert a FunctionDeclaration without a body`); + const updated = factory.createFunctionExpression( + node.modifiers, + node.asteriskToken, + node.name, + node.typeParameters, + node.parameters, + node.type, + node.body + ); + setOriginalNode(updated, node); + setTextRange(updated, node); + if (getStartsOnNewLine(node)) { + setStartsOnNewLine(updated, /*newLine*/ true); + } + return updated; + } + + function convertToArrayAssignmentElement(element: ArrayBindingOrAssignmentElement) { + if (isBindingElement(element)) { + if (element.dotDotDotToken) { + Debug.assertNode(element.name, isIdentifier); + return setOriginalNode(setTextRange(factory.createSpreadElement(element.name), element), element); + } + const expression = convertToAssignmentElementTarget(element.name); + return element.initializer + ? setOriginalNode( + setTextRange( + factory.createAssignment(expression, element.initializer), + element + ), + element + ) + : expression; + } + return cast(element, isExpression); + } + + function convertToObjectAssignmentElement(element: ObjectBindingOrAssignmentElement) { + if (isBindingElement(element)) { + if (element.dotDotDotToken) { + Debug.assertNode(element.name, isIdentifier); + return setOriginalNode(setTextRange(factory.createSpreadAssignment(element.name), element), element); + } + if (element.propertyName) { + const expression = convertToAssignmentElementTarget(element.name); + return setOriginalNode(setTextRange(factory.createPropertyAssignment(element.propertyName, element.initializer ? factory.createAssignment(expression, element.initializer) : expression), element), element); + } + Debug.assertNode(element.name, isIdentifier); + return setOriginalNode(setTextRange(factory.createShorthandPropertyAssignment(element.name, element.initializer), element), element); + } + + return cast(element, isObjectLiteralElementLike); + } + + function convertToAssignmentPattern(node: BindingOrAssignmentPattern): AssignmentPattern { + switch (node.kind) { + case SyntaxKind.ArrayBindingPattern: + case SyntaxKind.ArrayLiteralExpression: + return convertToArrayAssignmentPattern(node); + + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ObjectLiteralExpression: + return convertToObjectAssignmentPattern(node); + } + } + + function convertToObjectAssignmentPattern(node: ObjectBindingOrAssignmentPattern) { + if (isObjectBindingPattern(node)) { + return setOriginalNode( + setTextRange( + factory.createObjectLiteralExpression(map(node.elements, convertToObjectAssignmentElement)), + node + ), + node + ); + } + return cast(node, isObjectLiteralExpression); + } + + function convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern) { + if (isArrayBindingPattern(node)) { + return setOriginalNode( + setTextRange( + factory.createArrayLiteralExpression(map(node.elements, convertToArrayAssignmentElement)), + node + ), + node + ); + } + return cast(node, isArrayLiteralExpression); + } + + function convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression { + if (isBindingPattern(node)) { + return convertToAssignmentPattern(node); + } + + return cast(node, isExpression); + } + } + + export const nullNodeConverters: NodeConverters = { + convertToFunctionBlock: notImplemented, + convertToFunctionExpression: notImplemented, + convertToArrayAssignmentElement: notImplemented, + convertToObjectAssignmentElement: notImplemented, + convertToAssignmentPattern: notImplemented, + convertToObjectAssignmentPattern: notImplemented, + convertToArrayAssignmentPattern: notImplemented, + convertToAssignmentElementTarget: notImplemented, + }; +} \ No newline at end of file diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts new file mode 100644 index 0000000000000..4814bf679e074 --- /dev/null +++ b/src/compiler/factory/nodeFactory.ts @@ -0,0 +1,6216 @@ +namespace ts { + let nextAutoGenerateId = 0; + + /* @internal */ + export const enum NodeFactoryFlags { + None = 0, + // Disables the parenthesizer rules for the factory. + NoParenthesizerRules = 1 << 0, + // Disables the node converters for the factory. + NoNodeConverters = 1 << 1, + // Ensures new `PropertyAccessExpression` nodes are created with the `NoIndentation` emit flag set. + NoIndentationOnFreshPropertyAccess = 1 << 2, + // Do not set an `original` pointer when updating a node. + NoOriginalNode = 1 << 3, + } + + /** + * Creates a `NodeFactory` that can be used to create and update a syntax tree. + * @param flags Flags that control factory behavior. + * @param baseFactory A `BaseNodeFactory` used to create the base `Node` objects. + */ + /* @internal */ + export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNodeFactory): NodeFactory { + const update = flags & NodeFactoryFlags.NoOriginalNode ? updateWithoutOriginal : updateWithOriginal; + + // Lazily load the parenthesizer, node converters, and some factory methods until they are used. + const parenthesizerRules = memoize(() => flags & NodeFactoryFlags.NoParenthesizerRules ? nullParenthesizerRules : createParenthesizerRules(factory)); + const converters = memoize(() => flags & NodeFactoryFlags.NoNodeConverters ? nullNodeConverters : createNodeConverters(factory)); + + // lazy initializaton of common operator factories + const getBinaryCreateFunction = memoizeOne((operator: BinaryOperator) => (left: Expression, right: Expression) => createBinaryExpression(left, operator, right)); + const getPrefixUnaryCreateFunction = memoizeOne((operator: PrefixUnaryOperator) => (operand: Expression) => createPrefixUnaryExpression(operator, operand)); + const getPostfixUnaryCreateFunction = memoizeOne((operator: PostfixUnaryOperator) => (operand: Expression) => createPostfixUnaryExpression(operand, operator)); + const getJSDocPrimaryTypeCreateFunction = memoizeOne((kind: T["kind"]) => () => createJSDocPrimaryTypeWorker(kind)); + const getJSDocUnaryTypeCreateFunction = memoizeOne((kind: T["kind"]) => (type: T["type"]) => createJSDocUnaryTypeWorker(kind, type)); + const getJSDocUnaryTypeUpdateFunction = memoizeOne((kind: T["kind"]) => (node: T, type: T["type"]) => updateJSDocUnaryTypeWorker(kind, node, type)); + const getJSDocSimpleTagCreateFunction = memoizeOne((kind: T["kind"]) => (tagName: Identifier | undefined, comment?: string) => createJSDocSimpleTagWorker(kind, tagName, comment)); + const getJSDocSimpleTagUpdateFunction = memoizeOne((kind: T["kind"]) => (node: T, tagName: Identifier | undefined, comment?: string) => updateJSDocSimpleTagWorker(kind, node, tagName, comment)); + const getJSDocTypeLikeTagCreateFunction = memoizeOne((kind: T["kind"]) => (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string) => createJSDocTypeLikeTagWorker(kind, tagName, typeExpression, comment)); + const getJSDocTypeLikeTagUpdateFunction = memoizeOne((kind: T["kind"]) => (node: T, tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string) => updateJSDocTypeLikeTagWorker(kind, node, tagName, typeExpression, comment)); + + const factory: NodeFactory = { + get parenthesizer() { return parenthesizerRules(); }, + get converters() { return converters(); }, + createNodeArray, + createNumericLiteral, + createBigIntLiteral, + createStringLiteral, + createStringLiteralFromNode, + createRegularExpressionLiteral, + createLiteralLikeNode, + createIdentifier, + updateIdentifier, + createTempVariable, + createLoopVariable, + createUniqueName, + getGeneratedNameForNode, + createPrivateIdentifier, + createToken, + createSuper, + createThis, + createNull, + createTrue, + createFalse, + createModifier, + createModifiersFromModifierFlags, + createQualifiedName, + updateQualifiedName, + createComputedPropertyName, + updateComputedPropertyName, + createTypeParameterDeclaration, + updateTypeParameterDeclaration, + createParameterDeclaration, + updateParameterDeclaration, + createDecorator, + updateDecorator, + createPropertySignature, + updatePropertySignature, + createPropertyDeclaration, + updatePropertyDeclaration, + createMethodSignature, + updateMethodSignature, + createMethodDeclaration, + updateMethodDeclaration, + createConstructorDeclaration, + updateConstructorDeclaration, + createGetAccessorDeclaration, + updateGetAccessorDeclaration, + createSetAccessorDeclaration, + updateSetAccessorDeclaration, + createCallSignature, + updateCallSignature, + createConstructSignature, + updateConstructSignature, + createIndexSignature, + updateIndexSignature, + createKeywordTypeNode, + createTypePredicateNode, + updateTypePredicateNode, + createTypeReferenceNode, + updateTypeReferenceNode, + createFunctionTypeNode, + updateFunctionTypeNode, + createConstructorTypeNode, + updateConstructorTypeNode, + createTypeQueryNode, + updateTypeQueryNode, + createTypeLiteralNode, + updateTypeLiteralNode, + createArrayTypeNode, + updateArrayTypeNode, + createTupleTypeNode, + updateTupleTypeNode, + createNamedTupleMember, + updateNamedTupleMember, + createOptionalTypeNode, + updateOptionalTypeNode, + createRestTypeNode, + updateRestTypeNode, + createUnionTypeNode, + updateUnionTypeNode, + createIntersectionTypeNode, + updateIntersectionTypeNode, + createConditionalTypeNode, + updateConditionalTypeNode, + createInferTypeNode, + updateInferTypeNode, + createImportTypeNode, + updateImportTypeNode, + createParenthesizedType, + updateParenthesizedType, + createThisTypeNode, + createTypeOperatorNode, + updateTypeOperatorNode, + createIndexedAccessTypeNode, + updateIndexedAccessTypeNode, + createMappedTypeNode, + updateMappedTypeNode, + createLiteralTypeNode, + updateLiteralTypeNode, + createObjectBindingPattern, + updateObjectBindingPattern, + createArrayBindingPattern, + updateArrayBindingPattern, + createBindingElement, + updateBindingElement, + createArrayLiteralExpression, + updateArrayLiteralExpression, + createObjectLiteralExpression, + updateObjectLiteralExpression, + createPropertyAccessExpression: flags & NodeFactoryFlags.NoIndentationOnFreshPropertyAccess ? + (expression, name) => setEmitFlags(createPropertyAccessExpression(expression, name), EmitFlags.NoIndentation) : + createPropertyAccessExpression, + updatePropertyAccessExpression, + createPropertyAccessChain: flags & NodeFactoryFlags.NoIndentationOnFreshPropertyAccess ? + (expression, questionDotToken, name) => setEmitFlags(createPropertyAccessChain(expression, questionDotToken, name), EmitFlags.NoIndentation) : + createPropertyAccessChain, + updatePropertyAccessChain, + createElementAccessExpression, + updateElementAccessExpression, + createElementAccessChain, + updateElementAccessChain, + createCallExpression, + updateCallExpression, + createCallChain, + updateCallChain, + createNewExpression, + updateNewExpression, + createTaggedTemplateExpression, + updateTaggedTemplateExpression, + createTypeAssertion, + updateTypeAssertion, + createParenthesizedExpression, + updateParenthesizedExpression, + createFunctionExpression, + updateFunctionExpression, + createArrowFunction, + updateArrowFunction, + createDeleteExpression, + updateDeleteExpression, + createTypeOfExpression, + updateTypeOfExpression, + createVoidExpression, + updateVoidExpression, + createAwaitExpression, + updateAwaitExpression, + createPrefixUnaryExpression, + updatePrefixUnaryExpression, + createPostfixUnaryExpression, + updatePostfixUnaryExpression, + createBinaryExpression, + updateBinaryExpression, + createConditionalExpression, + updateConditionalExpression, + createTemplateExpression, + updateTemplateExpression, + createTemplateHead, + createTemplateMiddle, + createTemplateTail, + createNoSubstitutionTemplateLiteral, + createTemplateLiteralLikeNode, + createYieldExpression, + updateYieldExpression, + createSpreadElement, + updateSpreadElement, + createClassExpression, + updateClassExpression, + createOmittedExpression, + createExpressionWithTypeArguments, + updateExpressionWithTypeArguments, + createAsExpression, + updateAsExpression, + createNonNullExpression, + updateNonNullExpression, + createNonNullChain, + updateNonNullChain, + createMetaProperty, + updateMetaProperty, + createTemplateSpan, + updateTemplateSpan, + createSemicolonClassElement, + createBlock, + updateBlock, + createVariableStatement, + updateVariableStatement, + createEmptyStatement, + createExpressionStatement, + updateExpressionStatement, + createIfStatement, + updateIfStatement, + createDoStatement, + updateDoStatement, + createWhileStatement, + updateWhileStatement, + createForStatement, + updateForStatement, + createForInStatement, + updateForInStatement, + createForOfStatement, + updateForOfStatement, + createContinueStatement, + updateContinueStatement, + createBreakStatement, + updateBreakStatement, + createReturnStatement, + updateReturnStatement, + createWithStatement, + updateWithStatement, + createSwitchStatement, + updateSwitchStatement, + createLabeledStatement, + updateLabeledStatement, + createThrowStatement, + updateThrowStatement, + createTryStatement, + updateTryStatement, + createDebuggerStatement, + createVariableDeclaration, + updateVariableDeclaration, + createVariableDeclarationList, + updateVariableDeclarationList, + createFunctionDeclaration, + updateFunctionDeclaration, + createClassDeclaration, + updateClassDeclaration, + createInterfaceDeclaration, + updateInterfaceDeclaration, + createTypeAliasDeclaration, + updateTypeAliasDeclaration, + createEnumDeclaration, + updateEnumDeclaration, + createModuleDeclaration, + updateModuleDeclaration, + createModuleBlock, + updateModuleBlock, + createCaseBlock, + updateCaseBlock, + createNamespaceExportDeclaration, + updateNamespaceExportDeclaration, + createImportEqualsDeclaration, + updateImportEqualsDeclaration, + createImportDeclaration, + updateImportDeclaration, + createImportClause, + updateImportClause, + createNamespaceImport, + updateNamespaceImport, + createNamespaceExport, + updateNamespaceExport, + createNamedImports, + updateNamedImports, + createImportSpecifier, + updateImportSpecifier, + createExportAssignment, + updateExportAssignment, + createExportDeclaration, + updateExportDeclaration, + createNamedExports, + updateNamedExports, + createExportSpecifier, + updateExportSpecifier, + createMissingDeclaration, + createExternalModuleReference, + updateExternalModuleReference, + // lazily load factory members for JSDoc types with similar structure + get createJSDocAllType() { return getJSDocPrimaryTypeCreateFunction(SyntaxKind.JSDocAllType); }, + get createJSDocUnknownType() { return getJSDocPrimaryTypeCreateFunction(SyntaxKind.JSDocUnknownType); }, + get createJSDocNonNullableType() { return getJSDocUnaryTypeCreateFunction(SyntaxKind.JSDocNonNullableType); }, + get updateJSDocNonNullableType() { return getJSDocUnaryTypeUpdateFunction(SyntaxKind.JSDocNonNullableType); }, + get createJSDocNullableType() { return getJSDocUnaryTypeCreateFunction(SyntaxKind.JSDocNullableType); }, + get updateJSDocNullableType() { return getJSDocUnaryTypeUpdateFunction(SyntaxKind.JSDocNullableType); }, + get createJSDocOptionalType() { return getJSDocUnaryTypeCreateFunction(SyntaxKind.JSDocOptionalType); }, + get updateJSDocOptionalType() { return getJSDocUnaryTypeUpdateFunction(SyntaxKind.JSDocOptionalType); }, + get createJSDocVariadicType() { return getJSDocUnaryTypeCreateFunction(SyntaxKind.JSDocVariadicType); }, + get updateJSDocVariadicType() { return getJSDocUnaryTypeUpdateFunction(SyntaxKind.JSDocVariadicType); }, + get createJSDocNamepathType() { return getJSDocUnaryTypeCreateFunction(SyntaxKind.JSDocNamepathType); }, + get updateJSDocNamepathType() { return getJSDocUnaryTypeUpdateFunction(SyntaxKind.JSDocNamepathType); }, + createJSDocFunctionType, + updateJSDocFunctionType, + createJSDocTypeLiteral, + updateJSDocTypeLiteral, + createJSDocTypeExpression, + updateJSDocTypeExpression, + createJSDocSignature, + updateJSDocSignature, + createJSDocTemplateTag, + updateJSDocTemplateTag, + createJSDocTypedefTag, + updateJSDocTypedefTag, + createJSDocParameterTag, + updateJSDocParameterTag, + createJSDocPropertyTag, + updateJSDocPropertyTag, + createJSDocCallbackTag, + updateJSDocCallbackTag, + createJSDocAugmentsTag, + updateJSDocAugmentsTag, + createJSDocImplementsTag, + updateJSDocImplementsTag, + // lazily load factory members for JSDoc tags with similar structure + get createJSDocTypeTag() { return getJSDocTypeLikeTagCreateFunction(SyntaxKind.JSDocTypeTag); }, + get updateJSDocTypeTag() { return getJSDocTypeLikeTagUpdateFunction(SyntaxKind.JSDocTypeTag); }, + get createJSDocReturnTag() { return getJSDocTypeLikeTagCreateFunction(SyntaxKind.JSDocReturnTag); }, + get updateJSDocReturnTag() { return getJSDocTypeLikeTagUpdateFunction(SyntaxKind.JSDocReturnTag); }, + get createJSDocThisTag() { return getJSDocTypeLikeTagCreateFunction(SyntaxKind.JSDocThisTag); }, + get updateJSDocThisTag() { return getJSDocTypeLikeTagUpdateFunction(SyntaxKind.JSDocThisTag); }, + get createJSDocEnumTag() { return getJSDocTypeLikeTagCreateFunction(SyntaxKind.JSDocEnumTag); }, + get updateJSDocEnumTag() { return getJSDocTypeLikeTagUpdateFunction(SyntaxKind.JSDocEnumTag); }, + get createJSDocAuthorTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocAuthorTag); }, + get updateJSDocAuthorTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocAuthorTag); }, + get createJSDocClassTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocClassTag); }, + get updateJSDocClassTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocClassTag); }, + get createJSDocPublicTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocPublicTag); }, + get updateJSDocPublicTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocPublicTag); }, + get createJSDocPrivateTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocPrivateTag); }, + get updateJSDocPrivateTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocPrivateTag); }, + get createJSDocProtectedTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocProtectedTag); }, + get updateJSDocProtectedTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocProtectedTag); }, + get createJSDocReadonlyTag() { return getJSDocSimpleTagCreateFunction(SyntaxKind.JSDocReadonlyTag); }, + get updateJSDocReadonlyTag() { return getJSDocSimpleTagUpdateFunction(SyntaxKind.JSDocReadonlyTag); }, + createJSDocUnknownTag, + updateJSDocUnknownTag, + createJSDocComment, + updateJSDocComment, + createJsxElement, + updateJsxElement, + createJsxSelfClosingElement, + updateJsxSelfClosingElement, + createJsxOpeningElement, + updateJsxOpeningElement, + createJsxClosingElement, + updateJsxClosingElement, + createJsxFragment, + createJsxText, + updateJsxText, + createJsxOpeningFragment, + createJsxJsxClosingFragment, + updateJsxFragment, + createJsxAttribute, + updateJsxAttribute, + createJsxAttributes, + updateJsxAttributes, + createJsxSpreadAttribute, + updateJsxSpreadAttribute, + createJsxExpression, + updateJsxExpression, + createCaseClause, + updateCaseClause, + createDefaultClause, + updateDefaultClause, + createHeritageClause, + updateHeritageClause, + createCatchClause, + updateCatchClause, + createPropertyAssignment, + updatePropertyAssignment, + createShorthandPropertyAssignment, + updateShorthandPropertyAssignment, + createSpreadAssignment, + updateSpreadAssignment, + createEnumMember, + updateEnumMember, + createSourceFile, + updateSourceFile, + createBundle, + updateBundle, + createUnparsedSource, + createUnparsedPrologue, + createUnparsedPrepend, + createUnparsedTextLike, + createUnparsedSyntheticReference, + createInputFiles, + createSyntheticExpression, + createSyntaxList, + createNotEmittedStatement, + createPartiallyEmittedExpression, + updatePartiallyEmittedExpression, + createCommaListExpression, + updateCommaListExpression, + createEndOfDeclarationMarker, + createMergeDeclarationMarker, + createSyntheticReferenceExpression, + updateSyntheticReferenceExpression, + cloneNode, + + // Lazily load factory methods for common operator factories and utilities + get createComma() { return getBinaryCreateFunction(SyntaxKind.CommaToken); }, + get createAssignment() { return getBinaryCreateFunction(SyntaxKind.EqualsToken) as NodeFactory["createAssignment"]; }, + get createLogicalOr() { return getBinaryCreateFunction(SyntaxKind.BarBarToken); }, + get createLogicalAnd() { return getBinaryCreateFunction(SyntaxKind.AmpersandAmpersandToken); }, + get createBitwiseOr() { return getBinaryCreateFunction(SyntaxKind.BarToken); }, + get createBitwiseXor() { return getBinaryCreateFunction(SyntaxKind.CaretToken); }, + get createBitwiseAnd() { return getBinaryCreateFunction(SyntaxKind.AmpersandToken); }, + get createStrictEquality() { return getBinaryCreateFunction(SyntaxKind.EqualsEqualsEqualsToken); }, + get createStrictInequality() { return getBinaryCreateFunction(SyntaxKind.ExclamationEqualsEqualsToken); }, + get createEquality() { return getBinaryCreateFunction(SyntaxKind.EqualsEqualsToken); }, + get createInequality() { return getBinaryCreateFunction(SyntaxKind.ExclamationEqualsToken); }, + get createLessThan() { return getBinaryCreateFunction(SyntaxKind.LessThanToken); }, + get createLessThanEquals() { return getBinaryCreateFunction(SyntaxKind.LessThanEqualsToken); }, + get createGreaterThan() { return getBinaryCreateFunction(SyntaxKind.GreaterThanToken); }, + get createGreaterThanEquals() { return getBinaryCreateFunction(SyntaxKind.GreaterThanEqualsToken); }, + get createLeftShift() { return getBinaryCreateFunction(SyntaxKind.LessThanLessThanToken); }, + get createRightShift() { return getBinaryCreateFunction(SyntaxKind.GreaterThanGreaterThanToken); }, + get createUnsignedRightShift() { return getBinaryCreateFunction(SyntaxKind.GreaterThanGreaterThanGreaterThanToken); }, + get createAdd() { return getBinaryCreateFunction(SyntaxKind.PlusToken); }, + get createSubtract() { return getBinaryCreateFunction(SyntaxKind.MinusToken); }, + get createMultiply() { return getBinaryCreateFunction(SyntaxKind.AsteriskToken); }, + get createDivide() { return getBinaryCreateFunction(SyntaxKind.SlashToken); }, + get createModulo() { return getBinaryCreateFunction(SyntaxKind.PercentToken); }, + get createExponent() { return getBinaryCreateFunction(SyntaxKind.AsteriskAsteriskToken); }, + get createPrefixPlus() { return getPrefixUnaryCreateFunction(SyntaxKind.PlusToken); }, + get createPrefixMinus() { return getPrefixUnaryCreateFunction(SyntaxKind.MinusToken); }, + get createPrefixIncrement() { return getPrefixUnaryCreateFunction(SyntaxKind.PlusPlusToken); }, + get createPrefixDecrement() { return getPrefixUnaryCreateFunction(SyntaxKind.MinusMinusToken); }, + get createBitwiseNot() { return getPrefixUnaryCreateFunction(SyntaxKind.TildeToken); }, + get createLogicalNot() { return getPrefixUnaryCreateFunction(SyntaxKind.ExclamationToken); }, + get createPostfixIncrement() { return getPostfixUnaryCreateFunction(SyntaxKind.PlusPlusToken); }, + get createPostfixDecrement() { return getPostfixUnaryCreateFunction(SyntaxKind.MinusMinusToken); }, + + // Compound nodes + createImmediatelyInvokedFunctionExpression, + createImmediatelyInvokedArrowFunction, + createVoidZero, + createExportDefault, + createExternalModuleExport, + createTypeCheck, + createMethodCall, + createGlobalMethodCall, + createFunctionBindCall, + createFunctionCallCall, + createFunctionApplyCall, + createArraySliceCall, + createArrayConcatCall, + createObjectDefinePropertyCall, + createPropertyDescriptor, + createCallBinding, + + // Utilities + inlineExpressions, + getInternalName, + getLocalName, + getExportName, + getDeclarationName, + getNamespaceMemberName, + getExternalModuleOrNamespaceExportName, + restoreOuterExpressions, + restoreEnclosingLabel, + createUseStrictPrologue, + copyPrologue, + copyStandardPrologue, + copyCustomPrologue, + ensureUseStrict, + liftToBlock, + mergeLexicalEnvironment, + updateModifiers, + }; + + return factory; + + // @api + function createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray { + if (elements === undefined || elements === emptyArray) { + elements = []; + } + else if (isNodeArray(elements)) { + // Ensure the transform flags have been aggregated for this NodeArray + if (elements.transformFlags === undefined) { + aggregateChildrenFlags(elements as MutableNodeArray); + } + return elements; + } + + // Since the element list of a node array is typically created by starting with an empty array and + // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for + // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation. + const length = elements.length; + const array = >(length >= 1 && length <= 4 ? elements.slice() : elements); + setTextRangePosEnd(array, -1, -1); + array.hasTrailingComma = !!hasTrailingComma; + aggregateChildrenFlags(array); + return array; + } + + function createBaseNode(kind: T["kind"]) { + return baseFactory.createBaseNode(kind) as Mutable; + } + + function createBaseDeclaration( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined + ) { + const node = createBaseNode(kind); + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.transformFlags |= + propagateChildrenFlags(node.decorators) | + propagateChildrenFlags(node.modifiers); + // NOTE: The following properties are commonly set by the binder and are added here to + // ensure declarations have a stable shape. + node.symbol = undefined!; // initialized by binder + node.localSymbol = undefined!; // initialized by binder + node.locals = undefined!; // initialized by binder + node.nextContainer = undefined!; // initialized by binder + return node; + } + + function createBaseNamedDeclaration( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined + ) { + const node = createBaseDeclaration( + kind, + decorators, + modifiers + ); + node.name = asName(name); + node.transformFlags |= propagateChildFlags(node.name); + return node; + } + + function createBaseGenericNamedDeclaration }>( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined + ) { + const node = createBaseNamedDeclaration( + kind, + decorators, + modifiers, + name + ); + node.typeParameters = asNodeArray(typeParameters); + node.transformFlags |= propagateChildrenFlags(node.typeParameters); + if (typeParameters) node.transformFlags |= TransformFlags.ContainsTypeScript; + return node; + } + + function createBaseSignatureDeclaration( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[] | undefined, + type: TypeNode | undefined + ) { + const node = createBaseGenericNamedDeclaration( + kind, + decorators, + modifiers, + name, + typeParameters + ); + node.parameters = createNodeArray(parameters); + node.type = type; + node.transformFlags |= + propagateChildrenFlags(node.parameters) | + propagateChildFlags(node.type); + if (type) node.transformFlags |= TransformFlags.ContainsTypeScript; + return node; + } + + function updateBaseSignatureDeclaration(updated: Mutable, original: T) { + // copy children used only for error reporting + if (original.typeArguments) updated.typeArguments = original.typeArguments; + return update(updated, original); + } + + function createBaseFunctionLikeDeclaration( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern | string | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[] | undefined, + type: TypeNode | undefined, + body: T["body"] + ) { + const node = createBaseSignatureDeclaration( + kind, + decorators, + modifiers, + name, + typeParameters, + parameters, + type + ); + node.body = body; + node.transformFlags |= propagateChildFlags(node.body); + if (!body) node.transformFlags |= TransformFlags.ContainsTypeScript; + return node; + } + + function updateBaseFunctionLikeDeclaration(updated: Mutable, original: T) { + // copy children used only for error reporting + if (original.exclamationToken) updated.exclamationToken = original.exclamationToken; + if (original.typeArguments) updated.typeArguments = original.typeArguments; + return updateBaseSignatureDeclaration(updated, original); + } + + function createBaseInterfaceOrClassLikeDeclaration( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined + ) { + const node = createBaseGenericNamedDeclaration( + kind, + decorators, + modifiers, + name, + typeParameters + ); + node.heritageClauses = asNodeArray(heritageClauses); + node.transformFlags |= propagateChildrenFlags(node.heritageClauses); + return node; + } + + function createBaseClassLikeDeclaration( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly ClassElement[] + ) { + const node = createBaseInterfaceOrClassLikeDeclaration( + kind, + decorators, + modifiers, + name, + typeParameters, + heritageClauses + ); + node.members = createNodeArray(members); + node.transformFlags |= propagateChildrenFlags(node.members); + return node; + } + + function createBaseBindingLikeDeclaration( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | T["name"] | undefined, + initializer: Expression | undefined + ) { + const node = createBaseNamedDeclaration( + kind, + decorators, + modifiers, + name + ); + node.initializer = initializer; + node.transformFlags |= propagateChildFlags(node.initializer); + return node; + } + + function createBaseVariableLikeDeclaration( + kind: T["kind"], + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | T["name"] | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined + ) { + const node = createBaseBindingLikeDeclaration( + kind, + decorators, + modifiers, + name, + initializer + ); + node.type = type; + node.transformFlags |= propagateChildFlags(type); + if (type) node.transformFlags |= TransformFlags.ContainsTypeScript; + return node; + } + + // + // Literals + // + + function createBaseLiteral( + kind: T["kind"], + text: string + ) { + const node = createBaseToken(kind); + node.text = text; + return node; + } + + // @api + function createNumericLiteral(value: string | number, numericLiteralFlags: TokenFlags = TokenFlags.None): NumericLiteral { + const node = createBaseLiteral(SyntaxKind.NumericLiteral, typeof value === "number" ? value + "" : value); + node.numericLiteralFlags = numericLiteralFlags; + if (numericLiteralFlags & TokenFlags.BinaryOrOctalSpecifier) node.transformFlags |= TransformFlags.ContainsES2015; + return node; + } + + // @api + function createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral { + const node = createBaseLiteral(SyntaxKind.BigIntLiteral, typeof value === "string" ? value : pseudoBigIntToString(value) + "n"); + node.transformFlags |= TransformFlags.ContainsESNext; + return node; + } + + function createBaseStringLiteral(text: string, isSingleQuote?: boolean) { + const node = createBaseLiteral(SyntaxKind.StringLiteral, text); + node.singleQuote = isSingleQuote; + return node; + } + + // @api + function createStringLiteral(text: string, isSingleQuote?: boolean, hasExtendedUnicodeEscape?: boolean): StringLiteral { + const node = createBaseStringLiteral(text, isSingleQuote); + node.hasExtendedUnicodeEscape = hasExtendedUnicodeEscape; + if (hasExtendedUnicodeEscape) node.transformFlags |= TransformFlags.ContainsES2015; + return node; + } + + // @api + function createStringLiteralFromNode(sourceNode: PropertyNameLiteral): StringLiteral { + const node = createBaseStringLiteral(getTextOfIdentifierOrLiteral(sourceNode), /*isSingleQuote*/ undefined); + node.textSourceNode = sourceNode; + return node; + } + + // @api + function createRegularExpressionLiteral(text: string): RegularExpressionLiteral { + const node = createBaseLiteral(SyntaxKind.RegularExpressionLiteral, text); + return node; + } + + // @api + function createLiteralLikeNode(kind: LiteralToken["kind"] | SyntaxKind.JsxTextAllWhiteSpaces, text: string): LiteralToken { + switch (kind) { + case SyntaxKind.NumericLiteral: return createNumericLiteral(text, /*numericLiteralFlags*/ 0); + case SyntaxKind.BigIntLiteral: return createBigIntLiteral(text); + case SyntaxKind.StringLiteral: return createStringLiteral(text, /*isSingleQuote*/ undefined); + case SyntaxKind.JsxText: return createJsxText(text, /*containsOnlyTriviaWhiteSpaces*/ false); + case SyntaxKind.JsxTextAllWhiteSpaces: return createJsxText(text, /*containsOnlyTriviaWhiteSpaces*/ true); + case SyntaxKind.RegularExpressionLiteral: return createRegularExpressionLiteral(text); + case SyntaxKind.NoSubstitutionTemplateLiteral: return createTemplateLiteralLikeNode(kind, text, /*rawText*/ undefined, /*templateFlags*/ 0) as NoSubstitutionTemplateLiteral; + } + } + + // + // Identifiers + // + + function createBaseIdentifier(text: string, originalKeywordKind: SyntaxKind | undefined) { + if (originalKeywordKind === undefined && text) { + originalKeywordKind = stringToToken(text); + } + if (originalKeywordKind === SyntaxKind.Identifier) { + originalKeywordKind = undefined; + } + const node = baseFactory.createBaseIdentifierNode(SyntaxKind.Identifier) as Mutable; + node.originalKeywordKind = originalKeywordKind; + node.escapedText = escapeLeadingUnderscores(text); + return node; + } + + function createBaseGeneratedIdentifier(text: string, autoGenerateFlags: GeneratedIdentifierFlags) { + const node = createBaseIdentifier(text, /*originalKeywordKind*/ undefined) as Mutable; + node.autoGenerateFlags = autoGenerateFlags; + node.autoGenerateId = nextAutoGenerateId; + nextAutoGenerateId++; + return node; + } + + // @api + function createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[], originalKeywordKind?: SyntaxKind): Identifier { + const node = createBaseIdentifier(text, originalKeywordKind); + if (typeArguments) { + // NOTE: we do not use `setChildren` here because typeArguments in an identifier do not contribute to transformations + node.typeArguments = createNodeArray(typeArguments); + } + return node; + } + + // @api + function updateIdentifier(node: Identifier, typeArguments?: NodeArray | undefined): Identifier { + return node.typeArguments !== typeArguments + ? update(createIdentifier(idText(node), typeArguments), node) + : node; + } + + // @api + function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): GeneratedIdentifier { + let flags = GeneratedIdentifierFlags.Auto; + if (reservedInNestedScopes) flags |= GeneratedIdentifierFlags.ReservedInNestedScopes; + const name = createBaseGeneratedIdentifier("", flags); + if (recordTempVariable) { + recordTempVariable(name); + } + return name; + } + + /** Create a unique temporary variable for use in a loop. */ + // @api + function createLoopVariable(): Identifier { + return createBaseGeneratedIdentifier("", GeneratedIdentifierFlags.Loop); + } + + /** Create a unique name based on the supplied text. */ + // @api + function createUniqueName(text: string, flags: GeneratedIdentifierFlags = GeneratedIdentifierFlags.None): Identifier { + Debug.assert(!(flags & GeneratedIdentifierFlags.KindMask), "Argument out of range: flags"); + Debug.assert((flags & (GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)) !== GeneratedIdentifierFlags.FileLevel, "GeneratedIdentifierFlags.FileLevel cannot be set without also setting GeneratedIdentifierFlags.Optimistic"); + return createBaseGeneratedIdentifier(text, GeneratedIdentifierFlags.Unique | flags); + } + + /** Create a unique name generated for a node. */ + // @api + function getGeneratedNameForNode(node: Node | undefined, flags: GeneratedIdentifierFlags = 0): Identifier { + Debug.assert(!(flags & GeneratedIdentifierFlags.KindMask), "Argument out of range: flags"); + const name = createBaseGeneratedIdentifier(node && isIdentifier(node) ? idText(node) : "", GeneratedIdentifierFlags.Node | flags); + name.original = node; + return name; + } + + // @api + function createPrivateIdentifier(text: string): PrivateIdentifier { + if (!startsWith(text, "#")) Debug.fail("First character of private identifier must be #: " + text); + const node = baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as Mutable; + node.escapedText = escapeLeadingUnderscores(text); + node.transformFlags |= TransformFlags.ContainsClassFields; + return node; + } + + // + // Punctuation + // + + function createBaseToken(kind: T["kind"]) { + return baseFactory.createBaseTokenNode(kind) as Mutable; + } + + // @api + function createToken(token: SyntaxKind.SuperKeyword): SuperExpression; + function createToken(token: SyntaxKind.ThisKeyword): ThisExpression; + function createToken(token: SyntaxKind.NullKeyword): NullLiteral; + function createToken(token: SyntaxKind.TrueKeyword): TrueLiteral; + function createToken(token: SyntaxKind.FalseKeyword): FalseLiteral; + function createToken(token: TKind): PunctuationToken; + function createToken(token: TKind): KeywordTypeNode; + function createToken(token: TKind): ModifierToken; + function createToken(token: TKind): KeywordToken; + function createToken(token: TKind): Token; + function createToken(token: TKind): Token; + function createToken(token: TKind) { + Debug.assert(token >= SyntaxKind.FirstToken && token <= SyntaxKind.LastToken, "Invalid token"); + Debug.assert(token <= SyntaxKind.FirstTemplateToken || token >= SyntaxKind.LastTemplateToken, "Invalid token. Use 'createTemplateLiteralLikeNode' to create template literals."); + Debug.assert(token <= SyntaxKind.FirstLiteralToken || token >= SyntaxKind.LastLiteralToken, "Invalid token. Use 'createLiteralLikeNode' to create literals."); + Debug.assert(token !== SyntaxKind.Identifier, "Invalid token. Use 'createIdentifier' to create identifiers"); + const node = createBaseToken>(token); + let transformFlags = TransformFlags.None; + switch (token) { + case SyntaxKind.AsyncKeyword: + // 'async' modifier is ES2017 (async functions) or ES2018 (async generators) + transformFlags = + TransformFlags.ContainsES2017 | + TransformFlags.ContainsES2018; + break; + + case SyntaxKind.PublicKeyword: + case SyntaxKind.PrivateKeyword: + case SyntaxKind.ProtectedKeyword: + case SyntaxKind.ReadonlyKeyword: + case SyntaxKind.AbstractKeyword: + case SyntaxKind.DeclareKeyword: + case SyntaxKind.ConstKeyword: + case SyntaxKind.AnyKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.BigIntKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.ObjectKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.VoidKeyword: + case SyntaxKind.UnknownKeyword: + case SyntaxKind.UndefinedKeyword: // `undefined` is an Identifier in the expression case. + transformFlags = TransformFlags.ContainsTypeScript; + break; + case SyntaxKind.StaticKeyword: + case SyntaxKind.SuperKeyword: + transformFlags = TransformFlags.ContainsES2015; + break; + case SyntaxKind.ThisKeyword: + // 'this' indicates a lexical 'this' + transformFlags = TransformFlags.ContainsLexicalThis; + break; + } + if (transformFlags) { + node.transformFlags |= transformFlags; + } + return node; + } + + // + // Reserved words + // + + // @api + function createSuper() { + return createToken(SyntaxKind.SuperKeyword); + } + + // @api + function createThis() { + return createToken(SyntaxKind.ThisKeyword); + } + + // @api + function createNull() { + return createToken(SyntaxKind.NullKeyword); + } + + // @api + function createTrue() { + return createToken(SyntaxKind.TrueKeyword); + } + + // @api + function createFalse() { + return createToken(SyntaxKind.FalseKeyword); + } + + // + // Modifiers + // + + // @api + function createModifier(kind: T) { + return createToken(kind); + } + + // @api + function createModifiersFromModifierFlags(flags: ModifierFlags) { + const result: Modifier[] = []; + if (flags & ModifierFlags.Export) { result.push(createModifier(SyntaxKind.ExportKeyword)); } + if (flags & ModifierFlags.Ambient) { result.push(createModifier(SyntaxKind.DeclareKeyword)); } + if (flags & ModifierFlags.Default) { result.push(createModifier(SyntaxKind.DefaultKeyword)); } + if (flags & ModifierFlags.Const) { result.push(createModifier(SyntaxKind.ConstKeyword)); } + if (flags & ModifierFlags.Public) { result.push(createModifier(SyntaxKind.PublicKeyword)); } + if (flags & ModifierFlags.Private) { result.push(createModifier(SyntaxKind.PrivateKeyword)); } + if (flags & ModifierFlags.Protected) { result.push(createModifier(SyntaxKind.ProtectedKeyword)); } + if (flags & ModifierFlags.Abstract) { result.push(createModifier(SyntaxKind.AbstractKeyword)); } + if (flags & ModifierFlags.Static) { result.push(createModifier(SyntaxKind.StaticKeyword)); } + if (flags & ModifierFlags.Readonly) { result.push(createModifier(SyntaxKind.ReadonlyKeyword)); } + if (flags & ModifierFlags.Async) { result.push(createModifier(SyntaxKind.AsyncKeyword)); } + return result; + } + + // + // Names + // + + // @api + function createQualifiedName(left: EntityName, right: string | Identifier) { + const node = createBaseNode(SyntaxKind.QualifiedName); + node.left = left; + node.right = asName(right); + node.transformFlags |= + propagateChildFlags(node.left) | + propagateChildFlags(node.right); + return node; + } + + // @api + function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier) { + return node.left !== left + || node.right !== right + ? update(createQualifiedName(left, right), node) + : node; + } + + // @api + function createComputedPropertyName(expression: Expression) { + const node = createBaseNode(SyntaxKind.ComputedPropertyName); + node.expression = parenthesizerRules().parenthesizeExpressionOfComputedPropertyName(expression); + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsES2015 | + TransformFlags.ContainsComputedPropertyName; + return node; + } + + // @api + function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression) { + return node.expression !== expression + ? update(createComputedPropertyName(expression), node) + : node; + } + + // + // Signature elements + // + + // @api + function createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode) { + const node = createBaseNamedDeclaration( + SyntaxKind.TypeParameter, + /*decorators*/ undefined, + /*modifiers*/ undefined, + name + ); + node.constraint = constraint; + node.default = defaultType; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) { + return node.name !== name + || node.constraint !== constraint + || node.default !== defaultType + ? update(createTypeParameterDeclaration(name, constraint, defaultType), node) + : node; + } + + // @api + function createParameterDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + dotDotDotToken: DotDotDotToken | undefined, + name: string | BindingName, + questionToken?: QuestionToken, + type?: TypeNode, + initializer?: Expression + ) { + const node = createBaseVariableLikeDeclaration( + SyntaxKind.Parameter, + decorators, + modifiers, + name, + type, + initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer) + ); + node.dotDotDotToken = dotDotDotToken; + node.questionToken = questionToken; + if (isThisIdentifier(node.name)) { + node.transformFlags = TransformFlags.ContainsTypeScript; + } + else { + node.transformFlags |= + propagateChildFlags(node.dotDotDotToken) | + propagateChildFlags(node.questionToken); + if (questionToken) node.transformFlags |= TransformFlags.ContainsTypeScript; + if (modifiersToFlags(node.modifiers) & ModifierFlags.ParameterPropertyModifier) node.transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax; + if (initializer || dotDotDotToken) node.transformFlags |= TransformFlags.ContainsES2015; + } + return node; + } + + // @api + function updateParameterDeclaration( + node: ParameterDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + dotDotDotToken: DotDotDotToken | undefined, + name: string | BindingName, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.dotDotDotToken !== dotDotDotToken + || node.name !== name + || node.questionToken !== questionToken + || node.type !== type + || node.initializer !== initializer + ? update(createParameterDeclaration(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) + : node; + } + + // @api + function createDecorator(expression: Expression) { + const node = createBaseNode(SyntaxKind.Decorator); + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsTypeScript | + TransformFlags.ContainsTypeScriptClassSyntax; + return node; + } + + // @api + function updateDecorator(node: Decorator, expression: Expression) { + return node.expression !== expression + ? update(createDecorator(expression), node) + : node; + } + + // + // Type Elements + // + + // @api + function createPropertySignature( + modifiers: readonly Modifier[] | undefined, + name: PropertyName | string, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined + ): PropertySignature { + const node = createBaseNamedDeclaration( + SyntaxKind.PropertySignature, + /*decorators*/ undefined, + modifiers, + name + ); + node.type = type; + node.questionToken = questionToken; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updatePropertySignature( + node: PropertySignature, + modifiers: readonly Modifier[] | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined + ) { + return node.modifiers !== modifiers + || node.name !== name + || node.questionToken !== questionToken + || node.type !== type + ? update(createPropertySignature(modifiers, name, questionToken, type), node) + : node; + } + + // @api + function createPropertyDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | PropertyName, + questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined + ) { + const node = createBaseVariableLikeDeclaration( + SyntaxKind.PropertyDeclaration, + decorators, + modifiers, + name, + type, + initializer + ); + node.questionToken = questionOrExclamationToken && isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; + node.exclamationToken = questionOrExclamationToken && isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined; + node.transformFlags |= + propagateChildFlags(node.questionToken) | + propagateChildFlags(node.exclamationToken) | + TransformFlags.ContainsClassFields; + if (isComputedPropertyName(node.name) || (hasStaticModifier(node) && node.initializer)) { + node.transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax; + } + if (questionOrExclamationToken || modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + return node; + } + + // @api + function updatePropertyDeclaration( + node: PropertyDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | PropertyName, + questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.questionToken !== (questionOrExclamationToken !== undefined && isQuestionToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined) + || node.exclamationToken !== (questionOrExclamationToken !== undefined && isExclamationToken(questionOrExclamationToken) ? questionOrExclamationToken : undefined) + || node.type !== type + || node.initializer !== initializer + ? update(createPropertyDeclaration(decorators, modifiers, name, questionOrExclamationToken, type, initializer), node) + : node; + } + + // @api + function createMethodSignature( + modifiers: readonly Modifier[] | undefined, + name: string | PropertyName, + questionToken: QuestionToken | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined + ) { + const node = createBaseSignatureDeclaration( + SyntaxKind.MethodSignature, + /*decorators*/ undefined, + modifiers, + name, + typeParameters, + parameters, + type + ); + node.questionToken = questionToken; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateMethodSignature( + node: MethodSignature, + modifiers: readonly Modifier[] | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + typeParameters: NodeArray | undefined, + parameters: NodeArray, + type: TypeNode | undefined + ) { + return node.modifiers !== modifiers + || node.name !== name + || node.questionToken !== questionToken + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateBaseSignatureDeclaration(createMethodSignature(modifiers, name, questionToken, typeParameters, parameters, type), node) + : node; + } + + // @api + function createMethodDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + asteriskToken: AsteriskToken | undefined, + name: string | PropertyName, + questionToken: QuestionToken | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + body: Block | undefined + ) { + const node = createBaseFunctionLikeDeclaration( + SyntaxKind.MethodDeclaration, + decorators, + modifiers, + name, + typeParameters, + parameters, + type, + body + ); + node.asteriskToken = asteriskToken; + node.questionToken = questionToken; + node.transformFlags |= + propagateChildFlags(node.asteriskToken) | + propagateChildFlags(node.questionToken) | + TransformFlags.ContainsES2015; + if (questionToken) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { + if (asteriskToken) { + node.transformFlags |= TransformFlags.ContainsES2018; + } + else { + node.transformFlags |= TransformFlags.ContainsES2017; + } + } + else if (asteriskToken) { + node.transformFlags |= TransformFlags.ContainsGenerator; + } + return node; + } + + // @api + function updateMethodDeclaration( + node: MethodDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + asteriskToken: AsteriskToken | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + body: Block | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.asteriskToken !== asteriskToken + || node.name !== name + || node.questionToken !== questionToken + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateBaseFunctionLikeDeclaration(createMethodDeclaration(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) + : node; + } + + // @api + function createConstructorDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + parameters: readonly ParameterDeclaration[], + body: Block | undefined + ) { + const node = createBaseFunctionLikeDeclaration( + SyntaxKind.Constructor, + decorators, + modifiers, + /*name*/ undefined, + /*typeParameters*/ undefined, + parameters, + /*type*/ undefined, + body + ); + node.transformFlags |= TransformFlags.ContainsES2015; + return node; + } + + // @api + function updateConstructorDeclaration( + node: ConstructorDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + parameters: readonly ParameterDeclaration[], + body: Block | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.parameters !== parameters + || node.body !== body + ? updateBaseFunctionLikeDeclaration(createConstructorDeclaration(decorators, modifiers, parameters, body), node) + : node; + } + + // @api + function createGetAccessorDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | PropertyName, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + body: Block | undefined + ) { + return createBaseFunctionLikeDeclaration( + SyntaxKind.GetAccessor, + decorators, + modifiers, + name, + /*typeParameters*/ undefined, + parameters, + type, + body + ); + } + + // @api + function updateGetAccessorDeclaration( + node: GetAccessorDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: PropertyName, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + body: Block | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateBaseFunctionLikeDeclaration(createGetAccessorDeclaration(decorators, modifiers, name, parameters, type, body), node) + : node; + } + + // @api + function createSetAccessorDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | PropertyName, + parameters: readonly ParameterDeclaration[], + body: Block | undefined + ) { + return createBaseFunctionLikeDeclaration( + SyntaxKind.SetAccessor, + decorators, + modifiers, + name, + /*typeParameters*/ undefined, + parameters, + /*type*/ undefined, + body + ); + } + + // @api + function updateSetAccessorDeclaration( + node: SetAccessorDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: PropertyName, + parameters: readonly ParameterDeclaration[], + body: Block | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.parameters !== parameters + || node.body !== body + ? updateBaseFunctionLikeDeclaration(createSetAccessorDeclaration(decorators, modifiers, name, parameters, body), node) + : node; + } + + // @api + function createCallSignature( + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined + ): CallSignatureDeclaration { + const node = createBaseSignatureDeclaration( + SyntaxKind.CallSignature, + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*name*/ undefined, + typeParameters, + parameters, + type + ); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateCallSignature( + node: CallSignatureDeclaration, + typeParameters: NodeArray | undefined, + parameters: NodeArray, + type: TypeNode | undefined + ) { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateBaseSignatureDeclaration(createCallSignature(typeParameters, parameters, type), node) + : node; + } + + // @api + function createConstructSignature( + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined + ): ConstructSignatureDeclaration { + const node = createBaseSignatureDeclaration( + SyntaxKind.ConstructSignature, + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*name*/ undefined, + typeParameters, + parameters, + type + ); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateConstructSignature( + node: ConstructSignatureDeclaration, + typeParameters: NodeArray | undefined, + parameters: NodeArray, + type: TypeNode | undefined + ) { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateBaseSignatureDeclaration(createConstructSignature(typeParameters, parameters, type), node) + : node; + } + + // @api + function createIndexSignature( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined + ): IndexSignatureDeclaration { + const node = createBaseSignatureDeclaration( + SyntaxKind.IndexSignature, + decorators, + modifiers, + /*name*/ undefined, + /*typeParameters*/ undefined, + parameters, + type + ); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateIndexSignature( + node: IndexSignatureDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode + ) { + return node.parameters !== parameters + || node.type !== type + || node.decorators !== decorators + || node.modifiers !== modifiers + ? updateBaseSignatureDeclaration(createIndexSignature(decorators, modifiers, parameters, type), node) + : node; + } + + // + // Types + // + + // @api + function createKeywordTypeNode(kind: TKind) { + return createToken(kind); + } + + // @api + function createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { + const node = createBaseNode(SyntaxKind.TypePredicate); + node.assertsModifier = assertsModifier; + node.parameterName = asName(parameterName); + node.type = type; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) { + return node.assertsModifier !== assertsModifier + || node.parameterName !== parameterName + || node.type !== type + ? update(createTypePredicateNode(assertsModifier, parameterName, type), node) + : node; + } + + // @api + function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined) { + const node = createBaseNode(SyntaxKind.TypeReference); + node.typeName = asName(typeName); + node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(createNodeArray(typeArguments)); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) { + return node.typeName !== typeName + || node.typeArguments !== typeArguments + ? update(createTypeReferenceNode(typeName, typeArguments), node) + : node; + } + + // @api + function createFunctionTypeNode( + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined + ): FunctionTypeNode { + const node = createBaseSignatureDeclaration( + SyntaxKind.FunctionType, + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*name*/ undefined, + typeParameters, + parameters, + type + ); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateFunctionTypeNode( + node: FunctionTypeNode, + typeParameters: NodeArray | undefined, + parameters: NodeArray, + type: TypeNode | undefined + ) { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateBaseSignatureDeclaration(createFunctionTypeNode(typeParameters, parameters, type), node) + : node; + } + + // @api + function createConstructorTypeNode( + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined + ): ConstructorTypeNode { + const node = createBaseSignatureDeclaration( + SyntaxKind.ConstructorType, + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*name*/ undefined, + typeParameters, + parameters, + type + ); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateConstructorTypeNode( + node: ConstructorTypeNode, + typeParameters: NodeArray | undefined, + parameters: NodeArray, + type: TypeNode | undefined + ) { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateBaseSignatureDeclaration(createConstructorTypeNode(typeParameters, parameters, type), node) + : node; + } + + // @api + function createTypeQueryNode(exprName: EntityName) { + const node = createBaseNode(SyntaxKind.TypeQuery); + node.exprName = exprName; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) { + return node.exprName !== exprName + ? update(createTypeQueryNode(exprName), node) + : node; + } + + // @api + function createTypeLiteralNode(members: readonly TypeElement[] | undefined) { + const node = createBaseNode(SyntaxKind.TypeLiteral); + node.members = createNodeArray(members); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray) { + return node.members !== members + ? update(createTypeLiteralNode(members), node) + : node; + } + + // @api + function createArrayTypeNode(elementType: TypeNode) { + const node = createBaseNode(SyntaxKind.ArrayType); + node.elementType = parenthesizerRules().parenthesizeElementTypeOfArrayType(elementType); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode { + return node.elementType !== elementType + ? update(createArrayTypeNode(elementType), node) + : node; + } + + // @api + function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]) { + const node = createBaseNode(SyntaxKind.TupleType); + node.elements = createNodeArray(elements); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]) { + return node.elements !== elements + ? update(createTupleTypeNode(elements), node) + : node; + } + + // @api + function createNamedTupleMember(dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode) { + const node = createBaseNode(SyntaxKind.NamedTupleMember); + node.dotDotDotToken = dotDotDotToken; + node.name = name; + node.questionToken = questionToken; + node.type = type; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode) { + return node.dotDotDotToken !== dotDotDotToken + || node.name !== name + || node.questionToken !== questionToken + || node.type !== type + ? update(createNamedTupleMember(dotDotDotToken, name, questionToken, type), node) + : node; + } + + // @api + function createOptionalTypeNode(type: TypeNode) { + const node = createBaseNode(SyntaxKind.OptionalType); + node.type = parenthesizerRules().parenthesizeElementTypeOfArrayType(type); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode { + return node.type !== type + ? update(createOptionalTypeNode(type), node) + : node; + } + + // @api + function createRestTypeNode(type: TypeNode) { + const node = createBaseNode(SyntaxKind.RestType); + node.type = type; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode { + return node.type !== type + ? update(createRestTypeNode(type), node) + : node; + } + + function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: readonly TypeNode[]) { + const node = createBaseNode(kind); + node.types = parenthesizerRules().parenthesizeConstituentTypesOfUnionOrIntersectionType(types); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + function updateUnionOrIntersectionTypeNode(node: T, types: NodeArray): T { + return node.types !== types + ? update(createUnionOrIntersectionTypeNode(node.kind, types), node) + : node; + } + + // @api + function createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode { + return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, types); + } + + // @api + function updateUnionTypeNode(node: UnionTypeNode, types: NodeArray) { + return updateUnionOrIntersectionTypeNode(node, types); + } + + // @api + function createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode { + return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, types); + } + + // @api + function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray) { + return updateUnionOrIntersectionTypeNode(node, types); + } + + // @api + function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { + const node = createBaseNode(SyntaxKind.ConditionalType); + node.checkType = parenthesizerRules().parenthesizeMemberOfConditionalType(checkType); + node.extendsType = parenthesizerRules().parenthesizeMemberOfConditionalType(extendsType); + node.trueType = trueType; + node.falseType = falseType; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { + return node.checkType !== checkType + || node.extendsType !== extendsType + || node.trueType !== trueType + || node.falseType !== falseType + ? update(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node) + : node; + } + + // @api + function createInferTypeNode(typeParameter: TypeParameterDeclaration) { + const node = createBaseNode(SyntaxKind.InferType); + node.typeParameter = typeParameter; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration) { + return node.typeParameter !== typeParameter + ? update(createInferTypeNode(typeParameter), node) + : node; + } + + // @api + function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf = false) { + const node = createBaseNode(SyntaxKind.ImportType); + node.argument = argument; + node.qualifier = qualifier; + node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); + node.isTypeOf = isTypeOf; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf = node.isTypeOf) { + return node.argument !== argument + || node.qualifier !== qualifier + || node.typeArguments !== typeArguments + || node.isTypeOf !== isTypeOf + ? update(createImportTypeNode(argument, qualifier, typeArguments, isTypeOf), node) + : node; + } + + // @api + function createParenthesizedType(type: TypeNode) { + const node = createBaseNode(SyntaxKind.ParenthesizedType); + node.type = type; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode) { + return node.type !== type + ? update(createParenthesizedType(type), node) + : node; + } + + // @api + function createThisTypeNode() { + const node = createBaseNode(SyntaxKind.ThisType); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode { + const node = createBaseNode(SyntaxKind.TypeOperator); + node.operator = operator; + node.type = parenthesizerRules().parenthesizeMemberOfElementType(type); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) { + return node.type !== type + ? update(createTypeOperatorNode(node.operator, type), node) + : node; + } + + // @api + function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) { + const node = createBaseNode(SyntaxKind.IndexedAccessType); + node.objectType = parenthesizerRules().parenthesizeMemberOfElementType(objectType); + node.indexType = indexType; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) { + return node.objectType !== objectType + || node.indexType !== indexType + ? update(createIndexedAccessTypeNode(objectType, indexType), node) + : node; + } + + // @api + function createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode { + const node = createBaseNode(SyntaxKind.MappedType); + node.readonlyToken = readonlyToken; + node.typeParameter = typeParameter; + node.questionToken = questionToken; + node.type = type; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode { + return node.readonlyToken !== readonlyToken + || node.typeParameter !== typeParameter + || node.questionToken !== questionToken + || node.type !== type + ? update(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node) + : node; + } + + // @api + function createLiteralTypeNode(literal: LiteralTypeNode["literal"]) { + const node = createBaseNode(SyntaxKind.LiteralType); + node.literal = literal; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]) { + return node.literal !== literal + ? update(createLiteralTypeNode(literal), node) + : node; + } + + // + // Binding Patterns + // + + // @api + function createObjectBindingPattern(elements: readonly BindingElement[]) { + const node = createBaseNode(SyntaxKind.ObjectBindingPattern); + node.elements = createNodeArray(elements); + node.transformFlags |= + propagateChildrenFlags(node.elements) | + TransformFlags.ContainsES2015 | + TransformFlags.ContainsBindingPattern; + if (node.transformFlags & TransformFlags.ContainsRestOrSpread) { + node.transformFlags |= + TransformFlags.ContainsES2018 | + TransformFlags.ContainsObjectRestOrSpread; + } + return node; + } + + // @api + function updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]) { + return node.elements !== elements + ? update(createObjectBindingPattern(elements), node) + : node; + } + + // @api + function createArrayBindingPattern(elements: readonly ArrayBindingElement[]) { + const node = createBaseNode(SyntaxKind.ArrayBindingPattern); + node.elements = createNodeArray(elements); + node.transformFlags |= + propagateChildrenFlags(node.elements) | + TransformFlags.ContainsES2015 | + TransformFlags.ContainsBindingPattern; + return node; + } + + // @api + function updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]) { + return node.elements !== elements + ? update(createArrayBindingPattern(elements), node) + : node; + } + + // @api + function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression) { + const node = createBaseBindingLikeDeclaration( + SyntaxKind.BindingElement, + /*decorators*/ undefined, + /*modifiers*/ undefined, + name, + initializer + ); + node.propertyName = asName(propertyName); + node.dotDotDotToken = dotDotDotToken; + node.transformFlags |= + propagateChildFlags(node.propertyName) | + propagateChildFlags(node.dotDotDotToken) | + TransformFlags.ContainsES2015; + if (dotDotDotToken) node.transformFlags |= TransformFlags.ContainsRestOrSpread; + return node; + } + + // @api + function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined) { + return node.propertyName !== propertyName + || node.dotDotDotToken !== dotDotDotToken + || node.name !== name + || node.initializer !== initializer + ? update(createBindingElement(dotDotDotToken, propertyName, name, initializer), node) + : node; + } + + // + // Expression + // + + function createBaseExpression(kind: T["kind"]) { + const node = createBaseNode(kind); + // the following properties are commonly set by the checker/binder + return node; + } + + // @api + function createArrayLiteralExpression(elements?: readonly Expression[], multiLine?: boolean) { + const node = createBaseExpression(SyntaxKind.ArrayLiteralExpression); + node.elements = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(createNodeArray(elements)); + node.multiLine = multiLine; + node.transformFlags |= propagateChildrenFlags(node.elements); + return node; + } + + // @api + function updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]) { + return node.elements !== elements + ? update(createArrayLiteralExpression(elements, node.multiLine), node) + : node; + } + + // @api + function createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean) { + const node = createBaseExpression(SyntaxKind.ObjectLiteralExpression); + node.properties = createNodeArray(properties); + node.multiLine = multiLine; + node.transformFlags |= propagateChildrenFlags(node.properties); + return node; + } + + // @api + function updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]) { + return node.properties !== properties + ? update(createObjectLiteralExpression(properties, node.multiLine), node) + : node; + } + + // @api + function createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier) { + const node = createBaseExpression(SyntaxKind.PropertyAccessExpression); + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.name = asName(name); + node.transformFlags = + propagateChildFlags(node.expression) | + propagateChildFlags(node.name); + if (isSuperKeyword(expression)) { + // super method calls require a lexical 'this' + // super method calls require 'super' hoisting in ES2017 and ES2018 async functions and async generators + node.transformFlags |= + TransformFlags.ContainsES2017 | + TransformFlags.ContainsES2018; + } + return node; + } + + // @api + function updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) { + if (isPropertyAccessChain(node)) { + return updatePropertyAccessChain(node, expression, node.questionDotToken, cast(name, isIdentifier)); + } + return node.expression !== expression + || node.name !== name + ? update(createPropertyAccessExpression(expression, name), node) + : node; + } + + // @api + function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier) { + const node = createBaseExpression(SyntaxKind.PropertyAccessExpression); + node.flags |= NodeFlags.OptionalChain; + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.questionDotToken = questionDotToken; + node.name = asName(name); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.questionDotToken) | + propagateChildFlags(node.name) | + TransformFlags.ContainsES2020; + return node; + } + + // @api + function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier) { + Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a PropertyAccessExpression using updatePropertyAccessChain. Use updatePropertyAccess instead."); + // Because we are updating an existing PropertyAccessChain we want to inherit its emitFlags + // instead of using the default from createPropertyAccess + return node.expression !== expression + || node.questionDotToken !== questionDotToken + || node.name !== name + ? update(createPropertyAccessChain(expression, questionDotToken, name), node) + : node; + } + + // @api + function createElementAccessExpression(expression: Expression, index: number | Expression) { + const node = createBaseExpression(SyntaxKind.ElementAccessExpression); + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.argumentExpression = asExpression(index); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.argumentExpression); + if (isSuperKeyword(expression)) { + // super method calls require a lexical 'this' + // super method calls require 'super' hoisting in ES2017 and ES2018 async functions and async generators + node.transformFlags |= + TransformFlags.ContainsES2017 | + TransformFlags.ContainsES2018; + } + return node; + } + + // @api + function updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) { + if (isElementAccessChain(node)) { + return updateElementAccessChain(node, expression, node.questionDotToken, argumentExpression); + } + return node.expression !== expression + || node.argumentExpression !== argumentExpression + ? update(createElementAccessExpression(expression, argumentExpression), node) + : node; + } + + // @api + function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression) { + const node = createBaseExpression(SyntaxKind.ElementAccessExpression); + node.flags |= NodeFlags.OptionalChain; + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.questionDotToken = questionDotToken; + node.argumentExpression = asExpression(index); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.questionDotToken) | + propagateChildFlags(node.argumentExpression) | + TransformFlags.ContainsES2020; + return node; + } + + // @api + function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression) { + Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a ElementAccessExpression using updateElementAccessChain. Use updateElementAccess instead."); + // Because we are updating an existing ElementAccessChain we want to inherit its emitFlags + // instead of using the default from createElementAccess + return node.expression !== expression + || node.questionDotToken !== questionDotToken + || node.argumentExpression !== argumentExpression + ? update(createElementAccessChain(expression, questionDotToken, argumentExpression), node) + : node; + } + + // @api + function createCallExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { + const node = createBaseExpression(SyntaxKind.CallExpression); + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.typeArguments = asNodeArray(typeArguments); + node.arguments = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(createNodeArray(argumentsArray)); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildrenFlags(node.typeArguments) | + propagateChildrenFlags(node.arguments); + if (node.typeArguments) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + if (isImportKeyword(node.expression)) { + node.transformFlags |= TransformFlags.ContainsDynamicImport; + } + else if (isSuperProperty(node.expression)) { + node.transformFlags |= TransformFlags.ContainsLexicalThis; + } + return node; + } + + // @api + function updateCallExpression(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) { + if (isCallChain(node)) { + return updateCallChain(node, expression, node.questionDotToken, typeArguments, argumentsArray); + } + return node.expression !== expression + || node.typeArguments !== typeArguments + || node.arguments !== argumentsArray + ? update(createCallExpression(expression, typeArguments, argumentsArray), node) + : node; + } + + // @api + function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { + const node = createBaseExpression(SyntaxKind.CallExpression); + node.flags |= NodeFlags.OptionalChain; + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.questionDotToken = questionDotToken; + node.typeArguments = asNodeArray(typeArguments); + node.arguments = parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(createNodeArray(argumentsArray)); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.questionDotToken) | + propagateChildrenFlags(node.typeArguments) | + propagateChildrenFlags(node.arguments) | + TransformFlags.ContainsES2020; + if (node.typeArguments) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + if (isSuperProperty(node.expression)) { + node.transformFlags |= TransformFlags.ContainsLexicalThis; + } + return node; + } + + // @api + function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) { + Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a CallExpression using updateCallChain. Use updateCall instead."); + return node.expression !== expression + || node.questionDotToken !== questionDotToken + || node.typeArguments !== typeArguments + || node.arguments !== argumentsArray + ? update(createCallChain(expression, questionDotToken, typeArguments, argumentsArray), node) + : node; + } + + // @api + function createNewExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { + const node = createBaseExpression(SyntaxKind.NewExpression); + node.expression = parenthesizerRules().parenthesizeExpressionOfNew(expression); + node.typeArguments = asNodeArray(typeArguments); + node.arguments = argumentsArray ? parenthesizerRules().parenthesizeExpressionsOfCommaDelimitedList(argumentsArray) : undefined; + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildrenFlags(node.typeArguments) | + propagateChildrenFlags(node.arguments) | + TransformFlags.ContainsES2020; + if (node.typeArguments) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + return node; + } + + // @api + function updateNewExpression(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { + return node.expression !== expression + || node.typeArguments !== typeArguments + || node.arguments !== argumentsArray + ? update(createNewExpression(expression, typeArguments, argumentsArray), node) + : node; + } + + // @api + function createTaggedTemplateExpression(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral) { + const node = createBaseExpression(SyntaxKind.TaggedTemplateExpression); + node.tag = parenthesizerRules().parenthesizeLeftSideOfAccess(tag); + node.typeArguments = asNodeArray(typeArguments); + node.template = template; + node.transformFlags |= + propagateChildFlags(node.tag) | + propagateChildrenFlags(node.typeArguments) | + propagateChildFlags(node.template) | + TransformFlags.ContainsES2015; + if (node.typeArguments) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + if (hasInvalidEscape(node.template)) { + node.transformFlags |= TransformFlags.ContainsES2018; + } + return node; + } + + // @api + function updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral) { + return node.tag !== tag + || node.typeArguments !== typeArguments + || node.template !== template + ? update(createTaggedTemplateExpression(tag, typeArguments, template), node) + : node; + } + + // @api + function createTypeAssertion(type: TypeNode, expression: Expression) { + const node = createBaseExpression(SyntaxKind.TypeAssertionExpression); + node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.type = type; + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.type) | + TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression) { + return node.type !== type + || node.expression !== expression + ? update(createTypeAssertion(type, expression), node) + : node; + } + + // @api + function createParenthesizedExpression(expression: Expression) { + const node = createBaseExpression(SyntaxKind.ParenthesizedExpression); + node.expression = expression; + node.transformFlags = propagateChildFlags(node.expression); + return node; + } + + // @api + function updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression) { + return node.expression !== expression + ? update(createParenthesizedExpression(expression), node) + : node; + } + + // @api + function createFunctionExpression( + modifiers: readonly Modifier[] | undefined, + asteriskToken: AsteriskToken | undefined, + name: string | Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[] | undefined, + type: TypeNode | undefined, + body: Block + ) { + const node = createBaseFunctionLikeDeclaration( + SyntaxKind.FunctionExpression, + /*decorators*/ undefined, + modifiers, + name, + typeParameters, + parameters, + type, + body + ); + node.asteriskToken = asteriskToken; + node.transformFlags |= propagateChildFlags(node.asteriskToken); + if (node.typeParameters) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { + if (node.asteriskToken) { + node.transformFlags |= TransformFlags.ContainsES2018; + } + else { + node.transformFlags |= TransformFlags.ContainsES2017; + } + } + else if (node.asteriskToken) { + node.transformFlags |= TransformFlags.ContainsGenerator; + } + return node; + } + + // @api + function updateFunctionExpression( + node: FunctionExpression, + modifiers: readonly Modifier[] | undefined, + asteriskToken: AsteriskToken | undefined, + name: Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + body: Block + ) { + return node.name !== name + || node.modifiers !== modifiers + || node.asteriskToken !== asteriskToken + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateBaseFunctionLikeDeclaration(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) + : node; + } + + // @api + function createArrowFunction( + modifiers: readonly Modifier[] | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + equalsGreaterThanToken: EqualsGreaterThanToken | undefined, + body: ConciseBody + ) { + const node = createBaseFunctionLikeDeclaration( + SyntaxKind.ArrowFunction, + /*decorators*/ undefined, + modifiers, + /*name*/ undefined, + typeParameters, + parameters, + type, + parenthesizerRules().parenthesizeConciseBodyOfArrowFunction(body) + ); + node.equalsGreaterThanToken = equalsGreaterThanToken ?? createToken(SyntaxKind.EqualsGreaterThanToken); + node.transformFlags |= + propagateChildFlags(node.equalsGreaterThanToken) | + TransformFlags.ContainsES2015; + if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { + node.transformFlags |= TransformFlags.ContainsES2017; + } + return node; + } + + // @api + function updateArrowFunction( + node: ArrowFunction, + modifiers: readonly Modifier[] | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + equalsGreaterThanToken: EqualsGreaterThanToken, + body: ConciseBody + ): ArrowFunction { + return node.modifiers !== modifiers + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.equalsGreaterThanToken !== equalsGreaterThanToken + || node.body !== body + ? updateBaseFunctionLikeDeclaration(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) + : node; + } + + // @api + function createDeleteExpression(expression: Expression) { + const node = createBaseExpression(SyntaxKind.DeleteExpression); + node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.transformFlags |= propagateChildFlags(node.expression); + return node; + } + + // @api + function updateDeleteExpression(node: DeleteExpression, expression: Expression) { + return node.expression !== expression + ? update(createDeleteExpression(expression), node) + : node; + } + + // @api + function createTypeOfExpression(expression: Expression) { + const node = createBaseExpression(SyntaxKind.TypeOfExpression); + node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.transformFlags |= propagateChildFlags(node.expression); + return node; + } + + // @api + function updateTypeOfExpression(node: TypeOfExpression, expression: Expression) { + return node.expression !== expression + ? update(createTypeOfExpression(expression), node) + : node; + } + + // @api + function createVoidExpression(expression: Expression) { + const node = createBaseExpression(SyntaxKind.VoidExpression); + node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.transformFlags |= propagateChildFlags(node.expression); + return node; + } + + // @api + function updateVoidExpression(node: VoidExpression, expression: Expression) { + return node.expression !== expression + ? update(createVoidExpression(expression), node) + : node; + } + + // @api + function createAwaitExpression(expression: Expression) { + const node = createBaseExpression(SyntaxKind.AwaitExpression); + node.expression = parenthesizerRules().parenthesizeOperandOfPrefixUnary(expression); + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsES2017 | + TransformFlags.ContainsES2018 | + TransformFlags.ContainsAwait; + return node; + } + + // @api + function updateAwaitExpression(node: AwaitExpression, expression: Expression) { + return node.expression !== expression + ? update(createAwaitExpression(expression), node) + : node; + } + + // @api + function createPrefixUnaryExpression(operator: PrefixUnaryOperator, operand: Expression) { + const node = createBaseExpression(SyntaxKind.PrefixUnaryExpression); + node.operator = operator; + node.operand = parenthesizerRules().parenthesizeOperandOfPrefixUnary(operand); + node.transformFlags |= propagateChildFlags(node.operand); + return node; + } + + // @api + function updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression) { + return node.operand !== operand + ? update(createPrefixUnaryExpression(node.operator, operand), node) + : node; + } + + // @api + function createPostfixUnaryExpression(operand: Expression, operator: PostfixUnaryOperator) { + const node = createBaseExpression(SyntaxKind.PostfixUnaryExpression); + node.operator = operator; + node.operand = parenthesizerRules().parenthesizeOperandOfPostfixUnary(operand); + node.transformFlags = propagateChildFlags(node.operand); + return node; + } + + // @api + function updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression) { + return node.operand !== operand + ? update(createPostfixUnaryExpression(operand, node.operator), node) + : node; + } + + // @api + function createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression) { + const node = createBaseExpression(SyntaxKind.BinaryExpression); + const operatorToken = asToken(operator); + const operatorKind = operatorToken.kind; + node.left = parenthesizerRules().parenthesizeLeftSideOfBinary(operatorKind, left); + node.operatorToken = operatorToken; + node.right = parenthesizerRules().parenthesizeRightSideOfBinary(operatorKind, node.left, right); + node.transformFlags |= + propagateChildFlags(node.left) | + propagateChildFlags(node.operatorToken) | + propagateChildFlags(node.right); + if (operatorKind === SyntaxKind.QuestionQuestionToken) { + node.transformFlags |= TransformFlags.ContainsES2020; + } + else if (operatorKind === SyntaxKind.EqualsToken) { + if (isObjectLiteralExpression(node.left)) { + node.transformFlags |= + TransformFlags.ContainsES2015 | + TransformFlags.ContainsES2018 | + TransformFlags.ContainsDestructuringAssignment; + } + else if (isArrayLiteralExpression(node.left)) { + node.transformFlags |= + TransformFlags.ContainsES2015 | + TransformFlags.ContainsDestructuringAssignment; + } + } + else if (operatorKind === SyntaxKind.AsteriskAsteriskToken || operatorKind === SyntaxKind.AsteriskAsteriskEqualsToken) { + node.transformFlags |= TransformFlags.ContainsES2016; + } + else if (isLogicalOrCoalescingAssignmentOperator(operatorKind)) { + node.transformFlags |= TransformFlags.ContainsESNext; + } + return node; + } + + // @api + function updateBinaryExpression(node: BinaryExpression, left: Expression, operator: BinaryOperatorToken, right: Expression) { + return node.left !== left + || node.operatorToken !== operator + || node.right !== right + ? update(createBinaryExpression(left, operator, right), node) + : node; + } + + // @api + function createConditionalExpression(condition: Expression, questionToken: QuestionToken | undefined, whenTrue: Expression, colonToken: ColonToken | undefined, whenFalse: Expression) { + const node = createBaseExpression(SyntaxKind.ConditionalExpression); + node.condition = parenthesizerRules().parenthesizeConditionOfConditionalExpression(condition); + node.questionToken = questionToken ?? createToken(SyntaxKind.QuestionToken); + node.whenTrue = parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenTrue); + node.colonToken = colonToken ?? createToken(SyntaxKind.ColonToken); + node.whenFalse = parenthesizerRules().parenthesizeBranchOfConditionalExpression(whenFalse); + node.transformFlags |= + propagateChildFlags(node.condition) | + propagateChildFlags(node.questionToken) | + propagateChildFlags(node.whenTrue) | + propagateChildFlags(node.colonToken) | + propagateChildFlags(node.whenFalse); + return node; + } + + // @api + function updateConditionalExpression( + node: ConditionalExpression, + condition: Expression, + questionToken: Token, + whenTrue: Expression, + colonToken: Token, + whenFalse: Expression + ): ConditionalExpression { + return node.condition !== condition + || node.questionToken !== questionToken + || node.whenTrue !== whenTrue + || node.colonToken !== colonToken + || node.whenFalse !== whenFalse + ? update(createConditionalExpression(condition, questionToken, whenTrue, colonToken, whenFalse), node) + : node; + } + + // @api + function createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]) { + const node = createBaseExpression(SyntaxKind.TemplateExpression); + node.head = head; + node.templateSpans = createNodeArray(templateSpans); + node.transformFlags |= + propagateChildFlags(node.head) | + propagateChildrenFlags(node.templateSpans) | + TransformFlags.ContainsES2015; + return node; + } + + // @api + function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]) { + return node.head !== head + || node.templateSpans !== templateSpans + ? update(createTemplateExpression(head, templateSpans), node) + : node; + } + + function createTemplateLiteralLikeNodeChecked(kind: TemplateLiteralToken["kind"], text: string | undefined, rawText: string | undefined, templateFlags = TokenFlags.None) { + Debug.assert(!(templateFlags & ~TokenFlags.TemplateLiteralLikeFlags), "Unsupported template flags."); + // NOTE: without the assignment to `undefined`, we don't narrow the initial type of `cooked`. + // eslint-disable-next-line no-undef-init + let cooked: string | object | undefined = undefined; + if (rawText !== undefined && rawText !== text) { + cooked = getCookedText(kind, rawText); + if (typeof cooked === "object") { + return Debug.fail("Invalid raw text"); + } + } + if (text === undefined) { + if (cooked === undefined) { + return Debug.fail("Arguments 'text' and 'rawText' may not both be undefined."); + } + text = cooked; + } + else if (cooked !== undefined) { + Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'."); + } + return createTemplateLiteralLikeNode(kind, text, rawText, templateFlags); + } + + // @api + function createTemplateLiteralLikeNode(kind: TemplateLiteralToken["kind"], text: string, rawText: string | undefined, templateFlags: TokenFlags | undefined) { + const node = createBaseToken(kind); + node.text = text; + node.rawText = rawText; + node.templateFlags = templateFlags! & TokenFlags.TemplateLiteralLikeFlags; + node.transformFlags |= TransformFlags.ContainsES2015; + if (node.templateFlags) { + node.transformFlags |= TransformFlags.ContainsES2018; + } + return node; + } + + // @api + function createTemplateHead(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { + return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateHead, text, rawText, templateFlags); + } + + // @api + function createTemplateMiddle(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { + return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateMiddle, text, rawText, templateFlags); + } + + // @api + function createTemplateTail(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { + return createTemplateLiteralLikeNodeChecked(SyntaxKind.TemplateTail, text, rawText, templateFlags); + } + + // @api + function createNoSubstitutionTemplateLiteral(text: string | undefined, rawText?: string, templateFlags?: TokenFlags) { + return createTemplateLiteralLikeNodeChecked(SyntaxKind.NoSubstitutionTemplateLiteral, text, rawText, templateFlags); + } + + // @api + function createYieldExpression(asteriskToken: AsteriskToken | undefined, expression: Expression | undefined): YieldExpression { + Debug.assert(!asteriskToken || !!expression, "A `YieldExpression` with an asteriskToken must have an expression."); + const node = createBaseExpression(SyntaxKind.YieldExpression); + node.expression = expression && parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); + node.asteriskToken = asteriskToken; + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.asteriskToken) | + TransformFlags.ContainsES2015 | + TransformFlags.ContainsES2018 | + TransformFlags.ContainsYield; + return node; + } + + // @api + function updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression) { + return node.expression !== expression + || node.asteriskToken !== asteriskToken + ? update(createYieldExpression(asteriskToken, expression), node) + : node; + } + + // @api + function createSpreadElement(expression: Expression) { + const node = createBaseExpression(SyntaxKind.SpreadElement); + node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsES2015 | + TransformFlags.ContainsRestOrSpread; + return node; + } + + // @api + function updateSpreadElement(node: SpreadElement, expression: Expression) { + return node.expression !== expression + ? update(createSpreadElement(expression), node) + : node; + } + + // @api + function createClassExpression( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly ClassElement[] + ) { + const node = createBaseClassLikeDeclaration( + SyntaxKind.ClassExpression, + decorators, + modifiers, + name, + typeParameters, + heritageClauses, + members + ); + node.transformFlags |= TransformFlags.ContainsES2015; + return node; + } + + // @api + function updateClassExpression( + node: ClassExpression, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly ClassElement[] + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.typeParameters !== typeParameters + || node.heritageClauses !== heritageClauses + || node.members !== members + ? update(createClassExpression(decorators, modifiers, name, typeParameters, heritageClauses, members), node) + : node; + } + + // @api + function createOmittedExpression() { + return createBaseExpression(SyntaxKind.OmittedExpression); + } + + // @api + function createExpressionWithTypeArguments(expression: Expression, typeArguments: readonly TypeNode[] | undefined) { + const node = createBaseNode(SyntaxKind.ExpressionWithTypeArguments); + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildrenFlags(node.typeArguments) | + TransformFlags.ContainsES2015; + return node; + } + + // @api + function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: readonly TypeNode[] | undefined) { + return node.expression !== expression + || node.typeArguments !== typeArguments + ? update(createExpressionWithTypeArguments(expression, typeArguments), node) + : node; + } + + // @api + function createAsExpression(expression: Expression, type: TypeNode) { + const node = createBaseExpression(SyntaxKind.AsExpression); + node.expression = expression; + node.type = type; + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.type) | + TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode) { + return node.expression !== expression + || node.type !== type + ? update(createAsExpression(expression, type), node) + : node; + } + + // @api + function createNonNullExpression(expression: Expression) { + const node = createBaseExpression(SyntaxKind.NonNullExpression); + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateNonNullExpression(node: NonNullExpression, expression: Expression) { + if (isNonNullChain(node)) { + return updateNonNullChain(node, expression); + } + return node.expression !== expression + ? update(createNonNullExpression(expression), node) + : node; + } + + // @api + function createNonNullChain(expression: Expression) { + const node = createBaseExpression(SyntaxKind.NonNullExpression); + node.flags |= NodeFlags.OptionalChain; + node.expression = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateNonNullChain(node: NonNullChain, expression: Expression) { + Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a NonNullExpression using updateNonNullChain. Use updateNonNullExpression instead."); + return node.expression !== expression + ? update(createNonNullChain(expression), node) + : node; + } + + // @api + function createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier) { + const node = createBaseExpression(SyntaxKind.MetaProperty); + node.keywordToken = keywordToken; + node.name = name; + node.transformFlags |= propagateChildFlags(node.name); + switch (keywordToken) { + case SyntaxKind.NewKeyword: + node.transformFlags |= TransformFlags.ContainsES2015; + break; + case SyntaxKind.ImportKeyword: + node.transformFlags |= TransformFlags.ContainsESNext; + break; + default: + return Debug.assertNever(keywordToken); + } + return node; + } + + // @api + function updateMetaProperty(node: MetaProperty, name: Identifier) { + return node.name !== name + ? update(createMetaProperty(node.keywordToken, name), node) + : node; + } + + // + // Misc + // + + // @api + function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail) { + const node = createBaseNode(SyntaxKind.TemplateSpan); + node.expression = expression; + node.literal = literal; + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.literal) | + TransformFlags.ContainsES2015; + return node; + } + + // @api + function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) { + return node.expression !== expression + || node.literal !== literal + ? update(createTemplateSpan(expression, literal), node) + : node; + } + + // @api + function createSemicolonClassElement() { + const node = createBaseNode(SyntaxKind.SemicolonClassElement); + node.transformFlags |= TransformFlags.ContainsES2015; + return node; + } + + // + // Element + // + + // @api + function createBlock(statements: readonly Statement[], multiLine?: boolean): Block { + const node = createBaseNode(SyntaxKind.Block); + node.statements = createNodeArray(statements); + node.multiLine = multiLine; + node.transformFlags |= propagateChildrenFlags(node.statements); + return node; + } + + // @api + function updateBlock(node: Block, statements: readonly Statement[]) { + return node.statements !== statements + ? update(createBlock(statements, node.multiLine), node) + : node; + } + + // @api + function createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]) { + const node = createBaseDeclaration(SyntaxKind.VariableStatement, /*decorators*/ undefined, modifiers); + node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; + node.transformFlags |= + propagateChildFlags(node.declarationList); + if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + node.transformFlags = TransformFlags.ContainsTypeScript; + } + return node; + } + + // @api + function updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList) { + return node.modifiers !== modifiers + || node.declarationList !== declarationList + ? update(createVariableStatement(modifiers, declarationList), node) + : node; + } + + // @api + function createEmptyStatement() { + return createBaseNode(SyntaxKind.EmptyStatement); + } + + // @api + function createExpressionStatement(expression: Expression): ExpressionStatement { + const node = createBaseNode(SyntaxKind.ExpressionStatement); + node.expression = parenthesizerRules().parenthesizeExpressionOfExpressionStatement(expression); + node.transformFlags |= propagateChildFlags(node.expression); + return node; + } + + // @api + function updateExpressionStatement(node: ExpressionStatement, expression: Expression) { + return node.expression !== expression + ? update(createExpressionStatement(expression), node) + : node; + } + + // @api + function createIfStatement(expression: Expression, thenStatement: Statement, elseStatement?: Statement) { + const node = createBaseNode(SyntaxKind.IfStatement); + node.expression = expression; + node.thenStatement = asEmbeddedStatement(thenStatement); + node.elseStatement = asEmbeddedStatement(elseStatement); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.thenStatement) | + propagateChildFlags(node.elseStatement); + return node; + } + + // @api + function updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined) { + return node.expression !== expression + || node.thenStatement !== thenStatement + || node.elseStatement !== elseStatement + ? update(createIfStatement(expression, thenStatement, elseStatement), node) + : node; + } + + // @api + function createDoStatement(statement: Statement, expression: Expression) { + const node = createBaseNode(SyntaxKind.DoStatement); + node.statement = asEmbeddedStatement(statement); + node.expression = expression; + node.transformFlags |= + propagateChildFlags(node.statement) | + propagateChildFlags(node.expression); + return node; + } + + // @api + function updateDoStatement(node: DoStatement, statement: Statement, expression: Expression) { + return node.statement !== statement + || node.expression !== expression + ? update(createDoStatement(statement, expression), node) + : node; + } + + // @api + function createWhileStatement(expression: Expression, statement: Statement) { + const node = createBaseNode(SyntaxKind.WhileStatement); + node.expression = expression; + node.statement = asEmbeddedStatement(statement); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.statement); + return node; + } + + // @api + function updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement) { + return node.expression !== expression + || node.statement !== statement + ? update(createWhileStatement(expression, statement), node) + : node; + } + + // @api + function createForStatement(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { + const node = createBaseNode(SyntaxKind.ForStatement); + node.initializer = initializer; + node.condition = condition; + node.incrementor = incrementor; + node.statement = asEmbeddedStatement(statement); + node.transformFlags |= + propagateChildFlags(node.initializer) | + propagateChildFlags(node.condition) | + propagateChildFlags(node.incrementor) | + propagateChildFlags(node.statement); + return node; + } + + // @api + function updateForStatement(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { + return node.initializer !== initializer + || node.condition !== condition + || node.incrementor !== incrementor + || node.statement !== statement + ? update(createForStatement(initializer, condition, incrementor, statement), node) + : node; + } + + // @api + function createForInStatement(initializer: ForInitializer, expression: Expression, statement: Statement) { + const node = createBaseNode(SyntaxKind.ForInStatement); + node.initializer = initializer; + node.expression = expression; + node.statement = asEmbeddedStatement(statement); + node.transformFlags |= + propagateChildFlags(node.initializer) | + propagateChildFlags(node.expression) | + propagateChildFlags(node.statement); + return node; + } + + // @api + function updateForInStatement(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { + return node.initializer !== initializer + || node.expression !== expression + || node.statement !== statement + ? update(createForInStatement(initializer, expression, statement), node) + : node; + } + + // @api + function createForOfStatement(awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { + const node = createBaseNode(SyntaxKind.ForOfStatement); + node.awaitModifier = awaitModifier; + node.initializer = initializer; + node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); + node.statement = asEmbeddedStatement(statement); + node.transformFlags |= + propagateChildFlags(node.awaitModifier) | + propagateChildFlags(node.initializer) | + propagateChildFlags(node.expression) | + propagateChildFlags(node.statement) | + TransformFlags.ContainsES2015; + if (awaitModifier) node.transformFlags |= TransformFlags.ContainsES2018; + return node; + } + + // @api + function updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { + return node.awaitModifier !== awaitModifier + || node.initializer !== initializer + || node.expression !== expression + || node.statement !== statement + ? update(createForOfStatement(awaitModifier, initializer, expression, statement), node) + : node; + } + + // @api + function createContinueStatement(label?: string | Identifier): ContinueStatement { + const node = createBaseNode(SyntaxKind.ContinueStatement); + node.label = asName(label); + node.transformFlags |= + propagateChildFlags(node.label) | + TransformFlags.ContainsHoistedDeclarationOrCompletion; + return node; + } + + // @api + function updateContinueStatement(node: ContinueStatement, label: Identifier | undefined) { + return node.label !== label + ? update(createContinueStatement(label), node) + : node; + } + + // @api + function createBreakStatement(label?: string | Identifier): BreakStatement { + const node = createBaseNode(SyntaxKind.BreakStatement); + node.label = asName(label); + node.transformFlags |= + propagateChildFlags(node.label) | + TransformFlags.ContainsHoistedDeclarationOrCompletion; + return node; + } + + // @api + function updateBreakStatement(node: BreakStatement, label: Identifier | undefined) { + return node.label !== label + ? update(createBreakStatement(label), node) + : node; + } + + // @api + function createReturnStatement(expression?: Expression): ReturnStatement { + const node = createBaseNode(SyntaxKind.ReturnStatement); + node.expression = expression; + // return in an ES2018 async generator must be awaited + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsES2018 | + TransformFlags.ContainsHoistedDeclarationOrCompletion; + return node; + } + + // @api + function updateReturnStatement(node: ReturnStatement, expression: Expression | undefined) { + return node.expression !== expression + ? update(createReturnStatement(expression), node) + : node; + } + + // @api + function createWithStatement(expression: Expression, statement: Statement) { + const node = createBaseNode(SyntaxKind.WithStatement); + node.expression = expression; + node.statement = asEmbeddedStatement(statement); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.statement); + return node; + } + + // @api + function updateWithStatement(node: WithStatement, expression: Expression, statement: Statement) { + return node.expression !== expression + || node.statement !== statement + ? update(createWithStatement(expression, statement), node) + : node; + } + + // @api + function createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement { + const node = createBaseNode(SyntaxKind.SwitchStatement); + node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); + node.caseBlock = caseBlock; + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.caseBlock); + return node; + } + + // @api + function updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) { + return node.expression !== expression + || node.caseBlock !== caseBlock + ? update(createSwitchStatement(expression, caseBlock), node) + : node; + } + + // @api + function createLabeledStatement(label: string | Identifier, statement: Statement) { + const node = createBaseNode(SyntaxKind.LabeledStatement); + node.label = asName(label); + node.statement = asEmbeddedStatement(statement); + node.transformFlags |= + propagateChildFlags(node.label) | + propagateChildFlags(node.statement); + return node; + } + + // @api + function updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement) { + return node.label !== label + || node.statement !== statement + ? update(createLabeledStatement(label, statement), node) + : node; + } + + // @api + function createThrowStatement(expression: Expression) { + const node = createBaseNode(SyntaxKind.ThrowStatement); + node.expression = expression; + node.transformFlags |= propagateChildFlags(node.expression); + return node; + } + + // @api + function updateThrowStatement(node: ThrowStatement, expression: Expression) { + return node.expression !== expression + ? update(createThrowStatement(expression), node) + : node; + } + + // @api + function createTryStatement(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { + const node = createBaseNode(SyntaxKind.TryStatement); + node.tryBlock = tryBlock; + node.catchClause = catchClause; + node.finallyBlock = finallyBlock; + node.transformFlags |= + propagateChildFlags(node.tryBlock) | + propagateChildFlags(node.catchClause) | + propagateChildFlags(node.finallyBlock); + return node; + } + + // @api + function updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { + return node.tryBlock !== tryBlock + || node.catchClause !== catchClause + || node.finallyBlock !== finallyBlock + ? update(createTryStatement(tryBlock, catchClause, finallyBlock), node) + : node; + } + + // @api + function createDebuggerStatement() { + return createBaseNode(SyntaxKind.DebuggerStatement); + } + + // @api + function createVariableDeclaration(name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { + const node = createBaseVariableLikeDeclaration( + SyntaxKind.VariableDeclaration, + /*decorators*/ undefined, + /*modifiers*/ undefined, + name, + type, + initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer) + ); + node.exclamationToken = exclamationToken; + node.transformFlags |= propagateChildFlags(node.exclamationToken); + if (exclamationToken) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + return node; + } + + // @api + function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { + return node.name !== name + || node.type !== type + || node.exclamationToken !== exclamationToken + || node.initializer !== initializer + ? update(createVariableDeclaration(name, exclamationToken, type, initializer), node) + : node; + } + + // @api + function createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags = NodeFlags.None) { + const node = createBaseNode(SyntaxKind.VariableDeclarationList); + node.flags |= flags & NodeFlags.BlockScoped; + node.declarations = createNodeArray(declarations); + node.transformFlags |= + propagateChildrenFlags(node.declarations) | + TransformFlags.ContainsHoistedDeclarationOrCompletion; + if (flags & NodeFlags.BlockScoped) { + node.transformFlags |= + TransformFlags.ContainsES2015 | + TransformFlags.ContainsBlockScopedBinding; + } + return node; + } + + // @api + function updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]) { + return node.declarations !== declarations + ? update(createVariableDeclarationList(declarations, node.flags), node) + : node; + } + + // @api + function createFunctionDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + asteriskToken: AsteriskToken | undefined, + name: string | Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + body: Block | undefined + ) { + const node = createBaseFunctionLikeDeclaration( + SyntaxKind.FunctionDeclaration, + decorators, + modifiers, + name, + typeParameters, + parameters, + type, + body + ); + node.asteriskToken = asteriskToken; + if (!node.body || modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + node.transformFlags = TransformFlags.ContainsTypeScript; + } + else { + node.transformFlags |= + propagateChildFlags(node.asteriskToken) | + TransformFlags.ContainsHoistedDeclarationOrCompletion; + if (modifiersToFlags(node.modifiers) & ModifierFlags.Async) { + if (node.asteriskToken) { + node.transformFlags |= TransformFlags.ContainsES2018; + } + else { + node.transformFlags |= TransformFlags.ContainsES2017; + } + } + else if (node.asteriskToken) { + node.transformFlags |= TransformFlags.ContainsGenerator; + } + } + return node; + } + + // @api + function updateFunctionDeclaration( + node: FunctionDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + asteriskToken: AsteriskToken | undefined, + name: Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined, + body: Block | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.asteriskToken !== asteriskToken + || node.name !== name + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.body !== body + ? updateBaseFunctionLikeDeclaration(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) + : node; + } + + // @api + function createClassDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly ClassElement[] + ) { + const node = createBaseClassLikeDeclaration( + SyntaxKind.ClassDeclaration, + decorators, + modifiers, + name, + typeParameters, + heritageClauses, + members + ); + if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + node.transformFlags = TransformFlags.ContainsTypeScript; + } + else { + node.transformFlags |= TransformFlags.ContainsES2015; + if (node.transformFlags & TransformFlags.ContainsTypeScriptClassSyntax) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + } + return node; + } + + // @api + function updateClassDeclaration( + node: ClassDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier | undefined, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly ClassElement[] + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.typeParameters !== typeParameters + || node.heritageClauses !== heritageClauses + || node.members !== members + ? update(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node) + : node; + } + + // @api + function createInterfaceDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | Identifier, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly TypeElement[] + ) { + const node = createBaseInterfaceOrClassLikeDeclaration( + SyntaxKind.InterfaceDeclaration, + decorators, + modifiers, + name, + typeParameters, + heritageClauses + ); + node.members = createNodeArray(members); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateInterfaceDeclaration( + node: InterfaceDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + heritageClauses: readonly HeritageClause[] | undefined, + members: readonly TypeElement[] + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.typeParameters !== typeParameters + || node.heritageClauses !== heritageClauses + || node.members !== members + ? update(createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node) + : node; + } + + // @api + function createTypeAliasDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | Identifier, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + type: TypeNode + ) { + const node = createBaseGenericNamedDeclaration( + SyntaxKind.TypeAliasDeclaration, + decorators, + modifiers, + name, + typeParameters + ); + node.type = type; + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateTypeAliasDeclaration( + node: TypeAliasDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier, + typeParameters: readonly TypeParameterDeclaration[] | undefined, + type: TypeNode + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.typeParameters !== typeParameters + || node.type !== type + ? update(createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type), node) + : node; + } + + // @api + function createEnumDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | Identifier, + members: readonly EnumMember[] + ) { + const node = createBaseNamedDeclaration( + SyntaxKind.EnumDeclaration, + decorators, + modifiers, + name + ); + node.members = createNodeArray(members); + node.transformFlags |= + propagateChildrenFlags(node.members) | + TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateEnumDeclaration( + node: EnumDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier, + members: readonly EnumMember[]) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.members !== members + ? update(createEnumDeclaration(decorators, modifiers, name, members), node) + : node; + } + + // @api + function createModuleDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: ModuleName, + body: ModuleBody | undefined, + flags = NodeFlags.None + ) { + const node = createBaseDeclaration( + SyntaxKind.ModuleDeclaration, + decorators, + modifiers + ); + node.flags |= flags & (NodeFlags.Namespace | NodeFlags.NestedNamespace | NodeFlags.GlobalAugmentation); + node.name = name; + node.body = body; + if (modifiersToFlags(node.modifiers) & ModifierFlags.Ambient) { + node.transformFlags = TransformFlags.ContainsTypeScript; + } + else { + node.transformFlags |= + propagateChildFlags(node.name) | + propagateChildFlags(node.body) | + TransformFlags.ContainsTypeScript; + } + return node; + } + + // @api + function updateModuleDeclaration( + node: ModuleDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: ModuleName, + body: ModuleBody | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.body !== body + ? update(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node) + : node; + } + + // @api + function createModuleBlock(statements: readonly Statement[]) { + const node = createBaseNode(SyntaxKind.ModuleBlock); + node.statements = createNodeArray(statements); + node.transformFlags |= propagateChildrenFlags(node.statements); + return node; + } + + // @api + function updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]) { + return node.statements !== statements + ? update(createModuleBlock(statements), node) + : node; + } + + // @api + function createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock { + const node = createBaseNode(SyntaxKind.CaseBlock); + node.clauses = createNodeArray(clauses); + node.transformFlags |= propagateChildrenFlags(node.clauses); + return node; + } + + // @api + function updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]) { + return node.clauses !== clauses + ? update(createCaseBlock(clauses), node) + : node; + } + + // @api + function createNamespaceExportDeclaration(name: string | Identifier) { + const node = createBaseNamedDeclaration( + SyntaxKind.NamespaceExportDeclaration, + /*decorators*/ undefined, + /*modifiers*/ undefined, + name + ); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier) { + return node.name !== name + ? update(createNamespaceExportDeclaration(name), node) + : node; + } + + // @api + function createImportEqualsDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: string | Identifier, + moduleReference: ModuleReference + ) { + const node = createBaseNamedDeclaration( + SyntaxKind.ImportEqualsDeclaration, + decorators, + modifiers, + name + ); + node.moduleReference = moduleReference; + node.transformFlags |= propagateChildFlags(node.moduleReference); + if (!isExternalModuleReference(node.moduleReference)) node.transformFlags |= TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateImportEqualsDeclaration( + node: ImportEqualsDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + name: Identifier, + moduleReference: ModuleReference + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.name !== name + || node.moduleReference !== moduleReference + ? update(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node) + : node; + } + + // @api + function createImportDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + importClause: ImportClause | undefined, + moduleSpecifier: Expression + ): ImportDeclaration { + const node = createBaseDeclaration( + SyntaxKind.ImportDeclaration, + decorators, + modifiers + ); + node.importClause = importClause; + node.moduleSpecifier = moduleSpecifier; + node.transformFlags |= + propagateChildFlags(node.importClause) | + propagateChildFlags(node.moduleSpecifier); + return node; + } + + // @api + function updateImportDeclaration( + node: ImportDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + importClause: ImportClause | undefined, + moduleSpecifier: Expression + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.importClause !== importClause + || node.moduleSpecifier !== moduleSpecifier + ? update(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node) + : node; + } + + // @api + function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { + const node = createBaseNode(SyntaxKind.ImportClause); + node.isTypeOnly = isTypeOnly; + node.name = name; + node.namedBindings = namedBindings; + node.transformFlags |= + propagateChildFlags(node.name) | + propagateChildFlags(node.namedBindings); + if (isTypeOnly) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + return node; + } + + // @api + function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { + return node.isTypeOnly !== isTypeOnly + || node.name !== name + || node.namedBindings !== namedBindings + ? update(createImportClause(isTypeOnly, name, namedBindings), node) + : node; + } + + // @api + function createNamespaceImport(name: Identifier): NamespaceImport { + const node = createBaseNode(SyntaxKind.NamespaceImport); + node.name = name; + node.transformFlags |= propagateChildFlags(node.name); + return node; + } + + // @api + function updateNamespaceImport(node: NamespaceImport, name: Identifier) { + return node.name !== name + ? update(createNamespaceImport(name), node) + : node; + } + + // @api + function createNamespaceExport(name: Identifier): NamespaceExport { + const node = createBaseNode(SyntaxKind.NamespaceExport); + node.name = name; + node.transformFlags |= + propagateChildFlags(node.name) | + TransformFlags.ContainsESNext; + return node; + } + + // @api + function updateNamespaceExport(node: NamespaceExport, name: Identifier) { + return node.name !== name + ? update(createNamespaceExport(name), node) + : node; + } + + // @api + function createNamedImports(elements: readonly ImportSpecifier[]): NamedImports { + const node = createBaseNode(SyntaxKind.NamedImports); + node.elements = createNodeArray(elements); + node.transformFlags |= propagateChildrenFlags(node.elements); + return node; + } + + // @api + function updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]) { + return node.elements !== elements + ? update(createNamedImports(elements), node) + : node; + } + + // @api + function createImportSpecifier(propertyName: Identifier | undefined, name: Identifier) { + const node = createBaseNode(SyntaxKind.ImportSpecifier); + node.propertyName = propertyName; + node.name = name; + node.transformFlags |= + propagateChildFlags(node.propertyName) | + propagateChildFlags(node.name); + return node; + } + + // @api + function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier) { + return node.propertyName !== propertyName + || node.name !== name + ? update(createImportSpecifier(propertyName, name), node) + : node; + } + + // @api + function createExportAssignment( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + isExportEquals: boolean | undefined, + expression: Expression + ) { + const node = createBaseDeclaration( + SyntaxKind.ExportAssignment, + decorators, + modifiers + ); + node.isExportEquals = isExportEquals; + node.expression = isExportEquals + ? parenthesizerRules().parenthesizeRightSideOfBinary(SyntaxKind.EqualsToken, /*leftSide*/ undefined, expression) + : parenthesizerRules().parenthesizeExpressionOfExportDefault(expression); + node.transformFlags |= propagateChildFlags(node.expression); + return node; + } + + // @api + function updateExportAssignment( + node: ExportAssignment, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + expression: Expression + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.expression !== expression + ? update(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node) + : node; + } + + // @api + function createExportDeclaration( + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + isTypeOnly: boolean, + exportClause: NamedExportBindings | undefined, + moduleSpecifier?: Expression + ) { + const node = createBaseDeclaration( + SyntaxKind.ExportDeclaration, + decorators, + modifiers + ); + node.isTypeOnly = isTypeOnly; + node.exportClause = exportClause; + node.moduleSpecifier = moduleSpecifier; + node.transformFlags |= + propagateChildFlags(node.exportClause) | + propagateChildFlags(node.moduleSpecifier); + return node; + } + + // @api + function updateExportDeclaration( + node: ExportDeclaration, + decorators: readonly Decorator[] | undefined, + modifiers: readonly Modifier[] | undefined, + isTypeOnly: boolean, + exportClause: NamedExportBindings | undefined, + moduleSpecifier: Expression | undefined + ) { + return node.decorators !== decorators + || node.modifiers !== modifiers + || node.isTypeOnly !== isTypeOnly + || node.exportClause !== exportClause + || node.moduleSpecifier !== moduleSpecifier + ? update(createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier), node) + : node; + } + + // @api + function createNamedExports(elements: readonly ExportSpecifier[]) { + const node = createBaseNode(SyntaxKind.NamedExports); + node.elements = createNodeArray(elements); + node.transformFlags |= propagateChildrenFlags(node.elements); + return node; + } + + // @api + function updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]) { + return node.elements !== elements + ? update(createNamedExports(elements), node) + : node; + } + + // @api + function createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier) { + const node = createBaseNode(SyntaxKind.ExportSpecifier); + node.propertyName = asName(propertyName); + node.name = asName(name); + node.transformFlags |= + propagateChildFlags(node.propertyName) | + propagateChildFlags(node.name); + return node; + } + + // @api + function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier) { + return node.propertyName !== propertyName + || node.name !== name + ? update(createExportSpecifier(propertyName, name), node) + : node; + } + + // @api + function createMissingDeclaration() { + const node = createBaseDeclaration( + SyntaxKind.MissingDeclaration, + /*decorators*/ undefined, + /*modifiers*/ undefined + ); + return node; + } + + // + // Module references + // + + // @api + function createExternalModuleReference(expression: Expression) { + const node = createBaseNode(SyntaxKind.ExternalModuleReference); + node.expression = expression; + node.transformFlags |= propagateChildFlags(node.expression); + return node; + } + + // @api + function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression) { + return node.expression !== expression + ? update(createExternalModuleReference(expression), node) + : node; + } + + // + // JSDoc + // + + // @api + // createJSDocAllType + // createJSDocUnknownType + function createJSDocPrimaryTypeWorker(kind: T["kind"]) { + return createBaseNode(kind); + } + + // @api + // createJSDocNonNullableType + // createJSDocNullableType + // createJSDocOptionalType + // createJSDocVariadicType + // createJSDocNamepathType + + function createJSDocUnaryTypeWorker(kind: T["kind"], type: T["type"]): T { + const node = createBaseNode(kind); + node.type = type; + return node; + } + + // @api + // updateJSDocNonNullableType + // updateJSDocNullableType + // updateJSDocOptionalType + // updateJSDocVariadicType + // updateJSDocNamepathType + function updateJSDocUnaryTypeWorker(kind: T["kind"], node: T, type: T["type"]): T { + return node.type !== type + ? update(createJSDocUnaryTypeWorker(kind, type), node) + : node; + } + + // @api + function createJSDocFunctionType(parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType { + const node = createBaseSignatureDeclaration( + SyntaxKind.JSDocFunctionType, + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + parameters, + type + ); + return node; + } + + // @api + function updateJSDocFunctionType(node: JSDocFunctionType, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType { + return node.parameters !== parameters + || node.type !== type + ? update(createJSDocFunctionType(parameters, type), node) + : node; + } + + // @api + function createJSDocTypeLiteral(propertyTags?: readonly JSDocPropertyLikeTag[], isArrayType = false): JSDocTypeLiteral { + const node = createBaseNode(SyntaxKind.JSDocTypeLiteral); + node.jsDocPropertyTags = asNodeArray(propertyTags); + node.isArrayType = isArrayType; + return node; + } + + // @api + function updateJSDocTypeLiteral(node: JSDocTypeLiteral, propertyTags: readonly JSDocPropertyLikeTag[] | undefined, isArrayType: boolean): JSDocTypeLiteral { + return node.jsDocPropertyTags !== propertyTags + || node.isArrayType !== isArrayType + ? update(createJSDocTypeLiteral(propertyTags, isArrayType), node) + : node; + } + + // @api + function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression { + const node = createBaseNode(SyntaxKind.JSDocTypeExpression); + node.type = type; + return node; + } + + // @api + function updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression { + return node.type !== type + ? update(createJSDocTypeExpression(type), node) + : node; + } + + // @api + function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature { + const node = createBaseNode(SyntaxKind.JSDocSignature); + node.typeParameters = asNodeArray(typeParameters); + node.parameters = createNodeArray(parameters); + node.type = type; + return node; + } + + // @api + function updateJSDocSignature(node: JSDocSignature, typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type: JSDocReturnTag | undefined): JSDocSignature { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? update(createJSDocSignature(typeParameters, parameters, type), node) + : node; + } + + function getDefaultTagName(node: JSDocTag) { + const defaultTagName = getDefaultTagNameForKind(node.kind); + return node.tagName.escapedText === escapeLeadingUnderscores(defaultTagName) + ? node.tagName + : createIdentifier(defaultTagName); + } + + // @api + function createBaseJSDocTag(kind: T["kind"], tagName: Identifier, comment: string | undefined) { + const node = createBaseNode(kind); + node.tagName = tagName; + node.comment = comment; + return node; + } + + // @api + function createJSDocTemplateTag(tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string): JSDocTemplateTag { + const node = createBaseJSDocTag(SyntaxKind.JSDocTemplateTag, tagName ?? createIdentifier("template"), comment); + node.constraint = constraint; + node.typeParameters = createNodeArray(typeParameters); + return node; + } + + // @api + function updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier = getDefaultTagName(node), constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | undefined): JSDocTemplateTag { + return node.tagName !== tagName + || node.constraint !== constraint + || node.typeParameters !== typeParameters + || node.comment !== comment + ? update(createJSDocTemplateTag(tagName, constraint, typeParameters, comment), node) + : node; + } + + // @api + function createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocTypedefTag { + const node = createBaseJSDocTag(SyntaxKind.JSDocTypedefTag, tagName ?? createIdentifier("typedef"), comment); + node.typeExpression = typeExpression; + node.fullName = fullName; + node.name = getJSDocTypeAliasName(fullName); + return node; + } + + // @api + function updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocTypeExpression | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocTypedefTag { + return node.tagName !== tagName + || node.typeExpression !== typeExpression + || node.fullName !== fullName + || node.comment !== comment + ? update(createJSDocTypedefTag(tagName, typeExpression, fullName, comment), node) + : node; + } + + // @api + function createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag { + const node = createBaseJSDocTag(SyntaxKind.JSDocParameterTag, tagName ?? createIdentifier("param"), comment); + node.typeExpression = typeExpression; + node.name = name; + node.isNameFirst = !!isNameFirst; + node.isBracketed = isBracketed; + return node; + } + + // @api + function updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier = getDefaultTagName(node), name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag { + return node.tagName !== tagName + || node.name !== name + || node.isBracketed !== isBracketed + || node.typeExpression !== typeExpression + || node.isNameFirst !== isNameFirst + || node.comment !== comment + ? update(createJSDocParameterTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment), node) + : node; + } + + // @api + function createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag { + const node = createBaseJSDocTag(SyntaxKind.JSDocPropertyTag, tagName ?? createIdentifier("prop"), comment); + node.typeExpression = typeExpression; + node.name = name; + node.isNameFirst = !!isNameFirst; + node.isBracketed = isBracketed; + return node; + } + + // @api + function updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier = getDefaultTagName(node), name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag { + return node.tagName !== tagName + || node.name !== name + || node.isBracketed !== isBracketed + || node.typeExpression !== typeExpression + || node.isNameFirst !== isNameFirst + || node.comment !== comment + ? update(createJSDocPropertyTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment), node) + : node; + } + + // @api + function createJSDocCallbackTag(tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocCallbackTag { + const node = createBaseJSDocTag(SyntaxKind.JSDocCallbackTag, tagName ?? createIdentifier("callback"), comment); + node.typeExpression = typeExpression; + node.fullName = fullName; + node.name = getJSDocTypeAliasName(fullName); + return node; + } + + // @api + function updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocSignature, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocCallbackTag { + return node.tagName !== tagName + || node.typeExpression !== typeExpression + || node.fullName !== fullName + || node.comment !== comment + ? update(createJSDocCallbackTag(tagName, typeExpression, fullName, comment), node) + : node; + } + + // @api + function createJSDocAugmentsTag(tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment?: string): JSDocAugmentsTag { + const node = createBaseJSDocTag(SyntaxKind.JSDocAugmentsTag, tagName ?? createIdentifier("augments"), comment); + node.class = className; + return node; + } + + // @api + function updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier = getDefaultTagName(node), className: JSDocAugmentsTag["class"], comment: string | undefined): JSDocAugmentsTag { + return node.tagName !== tagName + || node.class !== className + || node.comment !== comment + ? update(createJSDocAugmentsTag(tagName, className, comment), node) + : node; + } + + // @api + function createJSDocImplementsTag(tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag { + const node = createBaseJSDocTag(SyntaxKind.JSDocImplementsTag, tagName ?? createIdentifier("implements"), comment); + node.class = className; + return node; + } + + // @api + function updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier = getDefaultTagName(node), className: JSDocImplementsTag["class"], comment: string | undefined): JSDocImplementsTag { + return node.tagName !== tagName + || node.class !== className + || node.comment !== comment + ? update(createJSDocImplementsTag(tagName, className, comment), node) + : node; + } + + // @api + // createJSDocAuthorTag + // createJSDocClassTag + // createJSDocPublicTag + // createJSDocPrivateTag + // createJSDocProtectedTag + // createJSDocReadonlyTag + function createJSDocSimpleTagWorker(kind: T["kind"], tagName: Identifier | undefined, comment?: string) { + const node = createBaseJSDocTag(kind, tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), comment); + return node; + } + + // @api + // updateJSDocAuthorTag + // updateJSDocClassTag + // updateJSDocPublicTag + // updateJSDocPrivateTag + // updateJSDocProtectedTag + // updateJSDocReadonlyTag + function updateJSDocSimpleTagWorker(kind: T["kind"], node: T, tagName: Identifier = getDefaultTagName(node), comment: string | undefined) { + return node.tagName !== tagName + || node.comment !== comment + ? update(createJSDocSimpleTagWorker(kind, tagName, comment), node) : + node; + } + + // @api + // createJSDocTypeTag + // createJSDocReturnTag + // createJSDocThisTag + // createJSDocEnumTag + function createJSDocTypeLikeTagWorker(kind: T["kind"], tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string) { + const node = createBaseJSDocTag(kind, tagName ?? createIdentifier(getDefaultTagNameForKind(kind)), comment); + node.typeExpression = typeExpression; + return node; + } + + // @api + // updateJSDocTypeTag + // updateJSDocReturnTag + // updateJSDocThisTag + // updateJSDocEnumTag + function updateJSDocTypeLikeTagWorker(kind: T["kind"], node: T, tagName: Identifier = getDefaultTagName(node), typeExpression: JSDocTypeExpression | undefined, comment: string | undefined) { + return node.tagName !== tagName + || node.typeExpression !== typeExpression + || node.comment !== comment + ? update(createJSDocTypeLikeTagWorker(kind, tagName, typeExpression, comment), node) + : node; + } + + // @api + function createJSDocUnknownTag(tagName: Identifier, comment?: string): JSDocUnknownTag { + const node = createBaseJSDocTag(SyntaxKind.JSDocTag, tagName, comment); + return node; + } + + // @api + function updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | undefined): JSDocUnknownTag { + return node.tagName !== tagName + || node.comment !== comment + ? update(createJSDocUnknownTag(tagName, comment), node) + : node; + } + + // @api + function createJSDocComment(comment?: string | undefined, tags?: readonly JSDocTag[] | undefined) { + const node = createBaseNode(SyntaxKind.JSDocComment); + node.comment = comment; + node.tags = asNodeArray(tags); + return node; + } + + // @api + function updateJSDocComment(node: JSDoc, comment: string | undefined, tags: readonly JSDocTag[] | undefined) { + return node.comment !== comment + || node.tags !== tags + ? update(createJSDocComment(comment, tags), node) + : node; + } + + // + // JSX + // + + // @api + function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { + const node = createBaseNode(SyntaxKind.JsxElement); + node.openingElement = openingElement; + node.children = createNodeArray(children); + node.closingElement = closingElement; + node.transformFlags |= + propagateChildFlags(node.openingElement) | + propagateChildrenFlags(node.children) | + propagateChildFlags(node.closingElement) | + TransformFlags.ContainsJsx; + return node; + } + + // @api + function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { + return node.openingElement !== openingElement + || node.children !== children + || node.closingElement !== closingElement + ? update(createJsxElement(openingElement, children, closingElement), node) + : node; + } + + // @api + function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { + const node = createBaseNode(SyntaxKind.JsxSelfClosingElement); + node.tagName = tagName; + node.typeArguments = asNodeArray(typeArguments); + node.attributes = attributes; + node.transformFlags |= + propagateChildFlags(node.tagName) | + propagateChildrenFlags(node.typeArguments) | + propagateChildFlags(node.attributes) | + TransformFlags.ContainsJsx; + if (node.typeArguments) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + return node; + } + + // @api + function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { + return node.tagName !== tagName + || node.typeArguments !== typeArguments + || node.attributes !== attributes + ? update(createJsxSelfClosingElement(tagName, typeArguments, attributes), node) + : node; + } + + // @api + function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { + const node = createBaseNode(SyntaxKind.JsxOpeningElement); + node.tagName = tagName; + node.typeArguments = asNodeArray(typeArguments); + node.attributes = attributes; + node.transformFlags |= + propagateChildFlags(node.tagName) | + propagateChildrenFlags(node.typeArguments) | + propagateChildFlags(node.attributes) | + TransformFlags.ContainsJsx; + if (typeArguments) { + node.transformFlags |= TransformFlags.ContainsTypeScript; + } + return node; + } + + // @api + function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { + return node.tagName !== tagName + || node.typeArguments !== typeArguments + || node.attributes !== attributes + ? update(createJsxOpeningElement(tagName, typeArguments, attributes), node) + : node; + } + + // @api + function createJsxClosingElement(tagName: JsxTagNameExpression) { + const node = createBaseNode(SyntaxKind.JsxClosingElement); + node.tagName = tagName; + node.transformFlags |= + propagateChildFlags(node.tagName) | + TransformFlags.ContainsJsx; + return node; + } + + // @api + function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression) { + return node.tagName !== tagName + ? update(createJsxClosingElement(tagName), node) + : node; + } + + // @api + function createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { + const node = createBaseNode(SyntaxKind.JsxFragment); + node.openingFragment = openingFragment; + node.children = createNodeArray(children); + node.closingFragment = closingFragment; + node.transformFlags |= + propagateChildFlags(node.openingFragment) | + propagateChildrenFlags(node.children) | + propagateChildFlags(node.closingFragment) | + TransformFlags.ContainsJsx; + return node; + } + + // @api + function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { + return node.openingFragment !== openingFragment + || node.children !== children + || node.closingFragment !== closingFragment + ? update(createJsxFragment(openingFragment, children, closingFragment), node) + : node; + } + + // @api + function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean) { + const node = createBaseNode(SyntaxKind.JsxText); + node.text = text; + node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces; + node.transformFlags |= TransformFlags.ContainsJsx; + return node; + } + + // @api + function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean) { + return node.text !== text + || node.containsOnlyTriviaWhiteSpaces !== containsOnlyTriviaWhiteSpaces + ? update(createJsxText(text, containsOnlyTriviaWhiteSpaces), node) + : node; + } + + // @api + function createJsxOpeningFragment() { + const node = createBaseNode(SyntaxKind.JsxOpeningFragment); + node.transformFlags |= TransformFlags.ContainsJsx; + return node; + } + + // @api + function createJsxJsxClosingFragment() { + const node = createBaseNode(SyntaxKind.JsxClosingFragment); + node.transformFlags |= TransformFlags.ContainsJsx; + return node; + } + + // @api + function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression | undefined) { + const node = createBaseNode(SyntaxKind.JsxAttribute); + node.name = name; + node.initializer = initializer; + node.transformFlags |= + propagateChildFlags(node.name) | + propagateChildFlags(node.initializer) | + TransformFlags.ContainsJsx; + return node; + } + + // @api + function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression | undefined) { + return node.name !== name + || node.initializer !== initializer + ? update(createJsxAttribute(name, initializer), node) + : node; + } + + // @api + function createJsxAttributes(properties: readonly JsxAttributeLike[]) { + const node = createBaseNode(SyntaxKind.JsxAttributes); + node.properties = createNodeArray(properties); + node.transformFlags |= + propagateChildrenFlags(node.properties) | + TransformFlags.ContainsJsx; + return node; + } + + // @api + function updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]) { + return node.properties !== properties + ? update(createJsxAttributes(properties), node) + : node; + } + + // @api + function createJsxSpreadAttribute(expression: Expression) { + const node = createBaseNode(SyntaxKind.JsxSpreadAttribute); + node.expression = expression; + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsJsx; + return node; + } + + // @api + function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression) { + return node.expression !== expression + ? update(createJsxSpreadAttribute(expression), node) + : node; + } + + // @api + function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) { + const node = createBaseNode(SyntaxKind.JsxExpression); + node.dotDotDotToken = dotDotDotToken; + node.expression = expression; + node.transformFlags |= + propagateChildFlags(node.dotDotDotToken) | + propagateChildFlags(node.expression) | + TransformFlags.ContainsJsx; + return node; + } + + // @api + function updateJsxExpression(node: JsxExpression, expression: Expression | undefined) { + return node.expression !== expression + ? update(createJsxExpression(node.dotDotDotToken, expression), node) + : node; + } + + // + // Clauses + // + + // @api + function createCaseClause(expression: Expression, statements: readonly Statement[]) { + const node = createBaseNode(SyntaxKind.CaseClause); + node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); + node.statements = createNodeArray(statements); + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildrenFlags(node.statements); + return node; + } + + // @api + function updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]) { + return node.expression !== expression + || node.statements !== statements + ? update(createCaseClause(expression, statements), node) + : node; + } + + // @api + function createDefaultClause(statements: readonly Statement[]) { + const node = createBaseNode(SyntaxKind.DefaultClause); + node.statements = createNodeArray(statements); + node.transformFlags = propagateChildrenFlags(node.statements); + return node; + } + + // @api + function updateDefaultClause(node: DefaultClause, statements: readonly Statement[]) { + return node.statements !== statements + ? update(createDefaultClause(statements), node) + : node; + } + + // @api + function createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]) { + const node = createBaseNode(SyntaxKind.HeritageClause); + node.token = token; + node.types = createNodeArray(types); + node.transformFlags |= propagateChildrenFlags(node.types); + switch (token) { + case SyntaxKind.ExtendsKeyword: + node.transformFlags |= TransformFlags.ContainsES2015; + break; + case SyntaxKind.ImplementsKeyword: + node.transformFlags |= TransformFlags.ContainsTypeScript; + break; + default: + return Debug.assertNever(token); + } + return node; + } + + // @api + function updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]) { + return node.types !== types + ? update(createHeritageClause(node.token, types), node) + : node; + } + + // @api + function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block) { + const node = createBaseNode(SyntaxKind.CatchClause); + variableDeclaration = !isString(variableDeclaration) ? variableDeclaration : createVariableDeclaration( + variableDeclaration, + /*exclamationToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + ); + node.variableDeclaration = variableDeclaration; + node.block = block; + node.transformFlags |= + propagateChildFlags(node.variableDeclaration) | + propagateChildFlags(node.block); + if (!variableDeclaration) node.transformFlags |= TransformFlags.ContainsES2019; + return node; + } + + // @api + function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block) { + return node.variableDeclaration !== variableDeclaration + || node.block !== block + ? update(createCatchClause(variableDeclaration, block), node) + : node; + } + + // + // Property assignments + // + + // @api + function createPropertyAssignment(name: string | PropertyName, initializer: Expression) { + const node = createBaseNamedDeclaration( + SyntaxKind.PropertyAssignment, + /*decorators*/ undefined, + /*modifiers*/ undefined, + name + ); + node.initializer = parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer); + node.transformFlags |= + propagateChildFlags(node.name) | + propagateChildFlags(node.initializer); + return node; + } + + function finishUpdatePropertyAssignment(updated: Mutable, original: PropertyAssignment) { + // copy children used only for error reporting + if (original.decorators) updated.decorators = original.decorators; + if (original.modifiers) updated.modifiers = original.modifiers; + if (original.questionToken) updated.questionToken = original.questionToken; + if (original.exclamationToken) updated.exclamationToken = original.exclamationToken; + return update(updated, original); + } + + // @api + function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression) { + return node.name !== name + || node.initializer !== initializer + ? finishUpdatePropertyAssignment(createPropertyAssignment(name, initializer), node) + : node; + } + + // @api + function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression) { + const node = createBaseNamedDeclaration( + SyntaxKind.ShorthandPropertyAssignment, + /*decorators*/ undefined, + /*modifiers*/ undefined, + name + ); + node.objectAssignmentInitializer = objectAssignmentInitializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(objectAssignmentInitializer); + node.transformFlags |= + propagateChildFlags(node.objectAssignmentInitializer) | + TransformFlags.ContainsES2015; + return node; + } + + function finishUpdateShorthandPropertyAssignment(updated: Mutable, original: ShorthandPropertyAssignment) { + // copy children used only for error reporting + if (original.decorators) updated.decorators = original.decorators; + if (original.modifiers) updated.modifiers = original.modifiers; + if (original.equalsToken) updated.equalsToken = original.equalsToken; + if (original.questionToken) updated.questionToken = original.questionToken; + if (original.exclamationToken) updated.exclamationToken = original.exclamationToken; + return update(updated, original); + } + + // @api + function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) { + return node.name !== name + || node.objectAssignmentInitializer !== objectAssignmentInitializer + ? finishUpdateShorthandPropertyAssignment(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node) + : node; + } + + // @api + function createSpreadAssignment(expression: Expression) { + const node = createBaseNode(SyntaxKind.SpreadAssignment); + node.expression = parenthesizerRules().parenthesizeExpressionForDisallowedComma(expression); + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsES2018 | + TransformFlags.ContainsObjectRestOrSpread; + return node; + } + + // @api + function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) { + return node.expression !== expression + ? update(createSpreadAssignment(expression), node) + : node; + } + + // + // Enum + // + + // @api + function createEnumMember(name: string | PropertyName, initializer?: Expression) { + const node = createBaseNode(SyntaxKind.EnumMember); + node.name = asName(name); + node.initializer = initializer && parenthesizerRules().parenthesizeExpressionForDisallowedComma(initializer); + node.transformFlags |= + propagateChildFlags(node.name) | + propagateChildFlags(node.initializer) | + TransformFlags.ContainsTypeScript; + return node; + } + + // @api + function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined) { + return node.name !== name + || node.initializer !== initializer + ? update(createEnumMember(name, initializer), node) + : node; + } + + // + // Top-level nodes + // + + // @api + function createSourceFile( + statements: readonly Statement[], + endOfFileToken: EndOfFileToken, + flags: NodeFlags + ) { + const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as Mutable; + node.statements = createNodeArray(statements); + node.endOfFileToken = endOfFileToken; + node.flags |= flags; + node.fileName = ""; + node.text = ""; + node.languageVersion = 0; + node.languageVariant = 0; + node.scriptKind = 0; + node.isDeclarationFile = false; + node.hasNoDefaultLib = false; + node.transformFlags |= + propagateChildrenFlags(node.statements) | + propagateChildFlags(node.endOfFileToken); + return node; + } + + function cloneSourceFileWithChanges( + source: SourceFile, + statements: readonly Statement[], + isDeclarationFile: boolean, + referencedFiles: readonly FileReference[], + typeReferences: readonly FileReference[], + hasNoDefaultLib: boolean, + libReferences: readonly FileReference[] + ) { + const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as Mutable; + for (const p in source) { + if (p === "emitNode" || hasProperty(node, p) || !hasProperty(source, p)) continue; + (node as any)[p] = (source as any)[p]; + } + node.flags |= source.flags; + node.statements = createNodeArray(statements); + node.endOfFileToken = source.endOfFileToken; + node.isDeclarationFile = isDeclarationFile; + node.referencedFiles = referencedFiles; + node.typeReferenceDirectives = typeReferences; + node.hasNoDefaultLib = hasNoDefaultLib; + node.libReferenceDirectives = libReferences; + node.transformFlags = + propagateChildrenFlags(node.statements) | + propagateChildFlags(node.endOfFileToken); + return node; + } + + // @api + function updateSourceFile( + node: SourceFile, + statements: readonly Statement[], + isDeclarationFile = node.isDeclarationFile, + referencedFiles = node.referencedFiles, + typeReferenceDirectives = node.typeReferenceDirectives, + hasNoDefaultLib = node.hasNoDefaultLib, + libReferenceDirectives = node.libReferenceDirectives + ) { + return node.statements !== statements + || node.isDeclarationFile !== isDeclarationFile + || node.referencedFiles !== referencedFiles + || node.typeReferenceDirectives !== typeReferenceDirectives + || node.hasNoDefaultLib !== hasNoDefaultLib + || node.libReferenceDirectives !== libReferenceDirectives + ? update(cloneSourceFileWithChanges(node, statements, isDeclarationFile, referencedFiles, typeReferenceDirectives, hasNoDefaultLib, libReferenceDirectives), node) + : node; + } + + // @api + function createBundle(sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) { + const node = createBaseNode(SyntaxKind.Bundle); + node.prepends = prepends; + node.sourceFiles = sourceFiles; + return node; + } + + // @api + function updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) { + return node.sourceFiles !== sourceFiles + || node.prepends !== prepends + ? update(createBundle(sourceFiles, prepends), node) + : node; + } + + // @api + function createUnparsedSource(prologues: readonly UnparsedPrologue[], syntheticReferences: readonly UnparsedSyntheticReference[] | undefined, texts: readonly UnparsedSourceText[]) { + const node = createBaseNode(SyntaxKind.UnparsedSource); + node.prologues = prologues; + node.syntheticReferences = syntheticReferences; + node.texts = texts; + node.fileName = ""; + node.text = ""; + node.referencedFiles = emptyArray; + node.libReferenceDirectives = emptyArray; + node.getLineAndCharacterOfPosition = pos => getLineAndCharacterOfPosition(node, pos); + return node; + } + + function createBaseUnparsedNode(kind: T["kind"], data?: string) { + const node = createBaseNode(kind); + node.data = data; + return node; + } + + // @api + function createUnparsedPrologue(data?: string): UnparsedPrologue { + return createBaseUnparsedNode(SyntaxKind.UnparsedPrologue, data); + } + + // @api + function createUnparsedPrepend(data: string | undefined, texts: readonly UnparsedTextLike[]): UnparsedPrepend { + const node = createBaseUnparsedNode(SyntaxKind.UnparsedPrepend, data); + node.texts = texts; + return node; + } + + // @api + function createUnparsedTextLike(data: string | undefined, internal: boolean): UnparsedTextLike { + return createBaseUnparsedNode(internal ? SyntaxKind.UnparsedInternalText : SyntaxKind.UnparsedText, data); + } + + // @api + function createUnparsedSyntheticReference(section: BundleFileHasNoDefaultLib | BundleFileReference): UnparsedSyntheticReference { + const node = createBaseNode(SyntaxKind.UnparsedSyntheticReference); + node.data = section.data; + node.section = section; + return node; + } + + // @api + function createInputFiles(): InputFiles { + const node = createBaseNode(SyntaxKind.InputFiles); + node.javascriptText = ""; + node.declarationText = ""; + return node; + } + + // + // Synthetic Nodes (used by checker) + // + + // @api + function createSyntheticExpression(type: Type, isSpread = false, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { + const node = createBaseNode(SyntaxKind.SyntheticExpression); + node.type = type; + node.isSpread = isSpread; + node.tupleNameSource = tupleNameSource; + return node; + } + + // @api + function createSyntaxList(children: Node[]) { + const node = createBaseNode(SyntaxKind.SyntaxList); + node._children = children; + return node; + } + + // + // Transformation nodes + // + + /** + * Creates a synthetic statement to act as a placeholder for a not-emitted statement in + * order to preserve comments. + * + * @param original The original statement. + */ + // @api + function createNotEmittedStatement(original: Node) { + const node = createBaseNode(SyntaxKind.NotEmittedStatement); + node.original = original; + setTextRange(node, original); + return node; + } + + /** + * Creates a synthetic expression to act as a placeholder for a not-emitted expression in + * order to preserve comments or sourcemap positions. + * + * @param expression The inner expression to emit. + * @param original The original outer expression. + */ + // @api + function createPartiallyEmittedExpression(expression: Expression, original?: Node) { + const node = createBaseNode(SyntaxKind.PartiallyEmittedExpression); + node.expression = expression; + node.original = original; + node.transformFlags |= + propagateChildFlags(node.expression) | + TransformFlags.ContainsTypeScript; + setTextRange(node, original); + return node; + } + + // @api + function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression) { + return node.expression !== expression + ? update(createPartiallyEmittedExpression(expression, node.original), node) + : node; + } + + function flattenCommaElements(node: Expression): Expression | readonly Expression[] { + if (nodeIsSynthesized(node) && !isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) { + if (isCommaListExpression(node)) { + return node.elements; + } + if (isBinaryExpression(node) && isCommaToken(node.operatorToken)) { + return [node.left, node.right]; + } + } + return node; + } + + // @api + function createCommaListExpression(elements: readonly Expression[]) { + const node = createBaseNode(SyntaxKind.CommaListExpression); + node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements)); + node.transformFlags |= propagateChildrenFlags(node.elements); + return node; + } + + // @api + function updateCommaListExpression(node: CommaListExpression, elements: readonly Expression[]) { + return node.elements !== elements + ? update(createCommaListExpression(elements), node) + : node; + } + + /** + * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in + * order to properly emit exports. + */ + // @api + function createEndOfDeclarationMarker(original: Node) { + const node = createBaseNode(SyntaxKind.EndOfDeclarationMarker); + node.emitNode = {} as EmitNode; + node.original = original; + return node; + } + + /** + * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in + * order to properly emit exports. + */ + // @api + function createMergeDeclarationMarker(original: Node) { + const node = createBaseNode(SyntaxKind.MergeDeclarationMarker); + node.emitNode = {} as EmitNode; + node.original = original; + return node; + } + + // @api + function createSyntheticReferenceExpression(expression: Expression, thisArg: Expression) { + const node = createBaseNode(SyntaxKind.SyntheticReferenceExpression); + node.expression = expression; + node.thisArg = thisArg; + node.transformFlags |= + propagateChildFlags(node.expression) | + propagateChildFlags(node.thisArg); + return node; + } + + // @api + function updateSyntheticReferenceExpression(node: SyntheticReferenceExpression, expression: Expression, thisArg: Expression) { + return node.expression !== expression + || node.thisArg !== thisArg + ? update(createSyntheticReferenceExpression(expression, thisArg), node) + : node; + } + + // @api + function cloneNode(node: T): T; + function cloneNode(node: T) { + // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of + // the original node. We also need to exclude specific properties and only include own- + // properties (to skip members already defined on the shared prototype). + if (node === undefined) { + return node; + } + + const clone = + isSourceFile(node) ? baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as T : + isIdentifier(node) ? baseFactory.createBaseIdentifierNode(SyntaxKind.Identifier) as T : + isPrivateIdentifier(node) ? baseFactory.createBasePrivateIdentifierNode(SyntaxKind.PrivateIdentifier) as T : + !isNodeKind(node.kind) ? baseFactory.createBaseTokenNode(node.kind) as T : + baseFactory.createBaseNode(node.kind) as T; + + (clone as Mutable).flags |= (node.flags & ~NodeFlags.Synthesized); + (clone as Mutable).transformFlags = node.transformFlags; + setOriginalNode(clone, node); + + for (const key in node) { + if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) { + continue; + } + + clone[key] = node[key]; + } + + return clone; + } + + // compound nodes + function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; + function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { + return createCallExpression( + createFunctionExpression( + /*modifiers*/ undefined, + /*asteriskToken*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ param ? [param] : [], + /*type*/ undefined, + createBlock(statements, /*multiLine*/ true) + ), + /*typeArguments*/ undefined, + /*argumentsArray*/ paramValue ? [paramValue] : [] + ); + } + + function createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; + function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { + return createCallExpression( + createArrowFunction( + /*modifiers*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ param ? [param] : [], + /*type*/ undefined, + /*equalsGreaterThanToken*/ undefined, + createBlock(statements, /*multiLine*/ true) + ), + /*typeArguments*/ undefined, + /*argumentsArray*/ paramValue ? [paramValue] : [] + ); + } + + function createVoidZero() { + return createVoidExpression(createNumericLiteral("0")); + } + + function createExportDefault(expression: Expression) { + return createExportAssignment( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*isExportEquals*/ false, + expression); + } + + function createExternalModuleExport(exportName: Identifier) { + return createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*isTypeOnly*/ false, + createNamedExports([ + createExportSpecifier(/*propertyName*/ undefined, exportName) + ]) + ); + } + + // + // Utilities + // + + function createTypeCheck(value: Expression, tag: TypeOfTag) { + return tag === "undefined" + ? factory.createStrictEquality(value, createVoidZero()) + : factory.createStrictEquality(createTypeOfExpression(value), createStringLiteral(tag)); + } + + function createMethodCall(object: Expression, methodName: string | Identifier, argumentsList: readonly Expression[]) { + return createCallExpression( + createPropertyAccessExpression(object, methodName), + /*typeArguments*/ undefined, + argumentsList + ); + } + + function createFunctionBindCall(target: Expression, thisArg: Expression, argumentsList: readonly Expression[]) { + return createMethodCall(target, "bind", [thisArg, ...argumentsList]); + } + + function createFunctionCallCall(target: Expression, thisArg: Expression, argumentsList: readonly Expression[]) { + return createMethodCall(target, "call", [thisArg, ...argumentsList]); + } + + function createFunctionApplyCall(target: Expression, thisArg: Expression, argumentsExpression: Expression) { + return createMethodCall(target, "apply", [thisArg, argumentsExpression]); + } + + function createGlobalMethodCall(globalObjectName: string, methodName: string, argumentsList: readonly Expression[]) { + return createMethodCall(createIdentifier(globalObjectName), methodName, argumentsList); + } + + function createArraySliceCall(array: Expression, start?: number | Expression) { + return createMethodCall(array, "slice", start === undefined ? [] : [asExpression(start)]); + } + + function createArrayConcatCall(array: Expression, argumentsList: readonly Expression[]) { + return createMethodCall(array, "concat", argumentsList); + } + + function createObjectDefinePropertyCall(target: Expression, propertyName: string | Expression, attributes: Expression) { + return createGlobalMethodCall("Object", "defineProperty", [target, asExpression(propertyName), attributes]); + } + + function tryAddPropertyAssignment(properties: Push, propertyName: string, expression: Expression | undefined) { + if (expression) { + properties.push(createPropertyAssignment(propertyName, expression)); + return true; + } + return false; + } + + function createPropertyDescriptor(attributes: PropertyDescriptorAttributes, singleLine?: boolean) { + const properties: PropertyAssignment[] = []; + tryAddPropertyAssignment(properties, "enumerable", asExpression(attributes.enumerable)); + tryAddPropertyAssignment(properties, "configurable", asExpression(attributes.configurable)); + + let isData = tryAddPropertyAssignment(properties, "writable", asExpression(attributes.writable)); + isData = tryAddPropertyAssignment(properties, "value", attributes.value) || isData; + + let isAccessor = tryAddPropertyAssignment(properties, "get", attributes.get); + isAccessor = tryAddPropertyAssignment(properties, "set", attributes.set) || isAccessor; + + Debug.assert(!(isData && isAccessor), "A PropertyDescriptor may not be both an accessor descriptor and a data descriptor."); + return createObjectLiteralExpression(properties, !singleLine); + } + + function updateOuterExpression(outerExpression: OuterExpression, expression: Expression) { + switch (outerExpression.kind) { + case SyntaxKind.ParenthesizedExpression: return updateParenthesizedExpression(outerExpression, expression); + case SyntaxKind.TypeAssertionExpression: return updateTypeAssertion(outerExpression, outerExpression.type, expression); + case SyntaxKind.AsExpression: return updateAsExpression(outerExpression, expression, outerExpression.type); + case SyntaxKind.NonNullExpression: return updateNonNullExpression(outerExpression, expression); + case SyntaxKind.PartiallyEmittedExpression: return updatePartiallyEmittedExpression(outerExpression, expression); + } + } + + /** + * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions. + * + * A parenthesized expression can be ignored when all of the following are true: + * + * - It's `pos` and `end` are not -1 + * - It does not have a custom source map range + * - It does not have a custom comment range + * - It does not have synthetic leading or trailing comments + * + * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around + * the expression to maintain precedence, a new parenthesized expression should be created automatically when + * the containing expression is created/updated. + */ + function isIgnorableParen(node: Expression) { + return isParenthesizedExpression(node) + && nodeIsSynthesized(node) + && nodeIsSynthesized(getSourceMapRange(node)) + && nodeIsSynthesized(getCommentRange(node)) + && !some(getSyntheticLeadingComments(node)) + && !some(getSyntheticTrailingComments(node)); + } + + function restoreOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression { + if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { + return updateOuterExpression( + outerExpression, + restoreOuterExpressions(outerExpression.expression, innerExpression) + ); + } + return innerExpression; + } + + function restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement | undefined, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement { + if (!outermostLabeledStatement) { + return node; + } + const updated = updateLabeledStatement( + outermostLabeledStatement, + outermostLabeledStatement.label, + isLabeledStatement(outermostLabeledStatement.statement) + ? restoreEnclosingLabel(node, outermostLabeledStatement.statement) + : node + ); + if (afterRestoreLabelCallback) { + afterRestoreLabelCallback(outermostLabeledStatement); + } + return updated; + } + + function shouldBeCapturedInTempVariable(node: Expression, cacheIdentifiers: boolean): boolean { + const target = skipParentheses(node); + switch (target.kind) { + case SyntaxKind.Identifier: + return cacheIdentifiers; + case SyntaxKind.ThisKeyword: + case SyntaxKind.NumericLiteral: + case SyntaxKind.BigIntLiteral: + case SyntaxKind.StringLiteral: + return false; + case SyntaxKind.ArrayLiteralExpression: + const elements = (target).elements; + if (elements.length === 0) { + return false; + } + return true; + case SyntaxKind.ObjectLiteralExpression: + return (target).properties.length > 0; + default: + return true; + } + } + + function createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers = false): CallBinding { + const callee = skipOuterExpressions(expression, OuterExpressionKinds.All); + let thisArg: Expression; + let target: LeftHandSideExpression; + if (isSuperProperty(callee)) { + thisArg = createThis(); + target = callee; + } + else if (isSuperKeyword(callee)) { + thisArg = createThis(); + target = languageVersion !== undefined && languageVersion < ScriptTarget.ES2015 + ? setTextRange(createIdentifier("_super"), callee) + : callee; + } + else if (getEmitFlags(callee) & EmitFlags.HelperName) { + thisArg = createVoidZero(); + target = parenthesizerRules().parenthesizeLeftSideOfAccess(callee); + } + else if (isPropertyAccessExpression(callee)) { + if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) { + // for `a.b()` target is `(_a = a).b` and thisArg is `_a` + thisArg = createTempVariable(recordTempVariable); + target = createPropertyAccessExpression( + setTextRange( + factory.createAssignment( + thisArg, + callee.expression + ), + callee.expression + ), + callee.name + ); + setTextRange(target, callee); + } + else { + thisArg = callee.expression; + target = callee; + } + } + else if (isElementAccessExpression(callee)) { + if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) { + // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a` + thisArg = createTempVariable(recordTempVariable); + target = createElementAccessExpression( + setTextRange( + factory.createAssignment( + thisArg, + callee.expression + ), + callee.expression + ), + callee.argumentExpression + ); + setTextRange(target, callee); + } + else { + thisArg = callee.expression; + target = callee; + } + } + else { + // for `a()` target is `a` and thisArg is `void 0` + thisArg = createVoidZero(); + target = parenthesizerRules().parenthesizeLeftSideOfAccess(expression); + } + + return { target, thisArg }; + } + + function inlineExpressions(expressions: readonly Expression[]) { + // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call + // stack size exceeded" errors. + return expressions.length > 10 + ? createCommaListExpression(expressions) + : reduceLeft(expressions, factory.createComma)!; + } + + function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags: EmitFlags = 0) { + const nodeName = getNameOfDeclaration(node); + if (nodeName && isIdentifier(nodeName) && !isGeneratedIdentifier(nodeName)) { + // TODO(rbuckton): Does this need to be parented? + const name = setParent(setTextRange(cloneNode(nodeName), nodeName), nodeName.parent); + emitFlags |= getEmitFlags(nodeName); + if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; + if (!allowComments) emitFlags |= EmitFlags.NoComments; + if (emitFlags) setEmitFlags(name, emitFlags); + return name; + } + return getGeneratedNameForNode(node); + } + + /** + * Gets the internal name of a declaration. This is primarily used for declarations that can be + * referred to by name in the body of an ES5 class function body. An internal name will *never* + * be prefixed with an module or namespace export modifier like "exports." when emitted as an + * expression. An internal name will also *never* be renamed due to a collision with a block + * scoped variable. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + function getInternalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { + return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName | EmitFlags.InternalName); + } + + /** + * Gets the local name of a declaration. This is primarily used for declarations that can be + * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A + * local name will *never* be prefixed with an module or namespace export modifier like + * "exports." when emitted as an expression. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + function getLocalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { + return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName); + } + + /** + * Gets the export name of a declaration. This is primarily used for declarations that can be + * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An + * export name will *always* be prefixed with an module or namespace export modifier like + * `"exports."` when emitted as an expression if the name points to an exported symbol. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + function getExportName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier { + return getName(node, allowComments, allowSourceMaps, EmitFlags.ExportName); + } + + /** + * Gets the name of a declaration for use in declarations. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + function getDeclarationName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) { + return getName(node, allowComments, allowSourceMaps); + } + + /** + * Gets a namespace-qualified name for use in expressions. + * + * @param ns The namespace identifier. + * @param name The name. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression { + const qualifiedName = createPropertyAccessExpression(ns, nodeIsSynthesized(name) ? name : cloneNode(name)); + setTextRange(qualifiedName, name); + let emitFlags: EmitFlags = 0; + if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap; + if (!allowComments) emitFlags |= EmitFlags.NoComments; + if (emitFlags) setEmitFlags(qualifiedName, emitFlags); + return qualifiedName; + } + + /** + * Gets the exported name of a declaration for use in expressions. + * + * An exported name will *always* be prefixed with an module or namespace export modifier like + * "exports." if the name points to an exported symbol. + * + * @param ns The namespace identifier. + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + function getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression { + if (ns && hasSyntacticModifier(node, ModifierFlags.Export)) { + return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps); + } + return getExportName(node, allowComments, allowSourceMaps); + } + + /** + * Copies any necessary standard and custom prologue-directives into target array. + * @param source origin statements array + * @param target result statements array + * @param ensureUseStrict boolean determining whether the function need to add prologue-directives + * @param visitor Optional callback used to visit any custom prologue directives. + */ + function copyPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number { + const offset = copyStandardPrologue(source, target, ensureUseStrict); + return copyCustomPrologue(source, target, offset, visitor); + } + + function isUseStrictPrologue(node: ExpressionStatement): boolean { + return isStringLiteral(node.expression) && node.expression.text === "use strict"; + } + + function createUseStrictPrologue() { + return startOnNewLine(createExpressionStatement(createStringLiteral("use strict"))) as PrologueDirective; + } + + /** + * Copies only the standard (string-expression) prologue-directives into the target statement-array. + * @param source origin statements array + * @param target result statements array + * @param ensureUseStrict boolean determining whether the function need to add prologue-directives + */ + function copyStandardPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean): number { + Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array"); + let foundUseStrict = false; + let statementOffset = 0; + const numStatements = source.length; + while (statementOffset < numStatements) { + const statement = source[statementOffset]; + if (isPrologueDirective(statement)) { + if (isUseStrictPrologue(statement)) { + foundUseStrict = true; + } + target.push(statement); + } + else { + break; + } + statementOffset++; + } + if (ensureUseStrict && !foundUseStrict) { + target.push(createUseStrictPrologue()); + } + return statementOffset; + } + + /** + * Copies only the custom prologue-directives into target statement-array. + * @param source origin statements array + * @param target result statements array + * @param statementOffset The offset at which to begin the copy. + * @param visitor Optional callback used to visit any custom prologue directives. + */ + function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number; + function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number | undefined; + function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter: (node: Node) => boolean = returnTrue): number | undefined { + const numStatements = source.length; + while (statementOffset !== undefined && statementOffset < numStatements) { + const statement = source[statementOffset]; + if (getEmitFlags(statement) & EmitFlags.CustomPrologue && filter(statement)) { + append(target, visitor ? visitNode(statement, visitor, isStatement) : statement); + } + else { + break; + } + statementOffset++; + } + return statementOffset; + } + + /** + * Ensures "use strict" directive is added + * + * @param statements An array of statements + */ + function ensureUseStrict(statements: NodeArray): NodeArray { + const foundUseStrict = findUseStrictPrologue(statements); + + if (!foundUseStrict) { + return setTextRange(createNodeArray([createUseStrictPrologue(), ...statements]), statements); + } + + return statements; + } + + /** + * Lifts a NodeArray containing only Statement nodes to a block. + * + * @param nodes The NodeArray. + */ + function liftToBlock(nodes: readonly Node[]): Statement { + Debug.assert(every(nodes, isStatementOrBlock), "Cannot lift nodes to a Block."); + return singleOrUndefined(nodes) || createBlock(nodes); + } + + function findSpanEnd(array: readonly T[], test: (value: T) => boolean, start: number) { + let i = start; + while (i < array.length && test(array[i])) { + i++; + } + return i; + } + + function mergeLexicalEnvironment(statements: NodeArray, declarations: readonly Statement[] | undefined): NodeArray; + function mergeLexicalEnvironment(statements: Statement[], declarations: readonly Statement[] | undefined): Statement[]; + function mergeLexicalEnvironment(statements: Statement[] | NodeArray, declarations: readonly Statement[] | undefined) { + if (!some(declarations)) { + return statements; + } + + // When we merge new lexical statements into an existing statement list, we merge them in the following manner: + // + // Given: + // + // | Left | Right | + // |------------------------------------|-------------------------------------| + // | [standard prologues (left)] | [standard prologues (right)] | + // | [hoisted functions (left)] | [hoisted functions (right)] | + // | [hoisted variables (left)] | [hoisted variables (right)] | + // | [lexical init statements (left)] | [lexical init statements (right)] | + // | [other statements (left)] | | + // + // The resulting statement list will be: + // + // | Result | + // |-------------------------------------| + // | [standard prologues (right)] | + // | [standard prologues (left)] | + // | [hoisted functions (right)] | + // | [hoisted functions (left)] | + // | [hoisted variables (right)] | + // | [hoisted variables (left)] | + // | [lexical init statements (right)] | + // | [lexical init statements (left)] | + // | [other statements (left)] | + // + // NOTE: It is expected that new lexical init statements must be evaluated before existing lexical init statements, + // as the prior transformation may depend on the evaluation of the lexical init statements to be in the correct state. + + // find standard prologues on left in the following order: standard directives, hoisted functions, hoisted variables, other custom + const leftStandardPrologueEnd = findSpanEnd(statements, isPrologueDirective, 0); + const leftHoistedFunctionsEnd = findSpanEnd(statements, isHoistedFunction, leftStandardPrologueEnd); + const leftHoistedVariablesEnd = findSpanEnd(statements, isHoistedVariableStatement, leftHoistedFunctionsEnd); + + // find standard prologues on right in the following order: standard directives, hoisted functions, hoisted variables, other custom + const rightStandardPrologueEnd = findSpanEnd(declarations, isPrologueDirective, 0); + const rightHoistedFunctionsEnd = findSpanEnd(declarations, isHoistedFunction, rightStandardPrologueEnd); + const rightHoistedVariablesEnd = findSpanEnd(declarations, isHoistedVariableStatement, rightHoistedFunctionsEnd); + const rightCustomPrologueEnd = findSpanEnd(declarations, isCustomPrologue, rightHoistedVariablesEnd); + Debug.assert(rightCustomPrologueEnd === declarations.length, "Expected declarations to be valid standard or custom prologues"); + + // splice prologues from the right into the left. We do this in reverse order + // so that we don't need to recompute the index on the left when we insert items. + const left = isNodeArray(statements) ? statements.slice() : statements; + + // splice other custom prologues from right into left + if (rightCustomPrologueEnd > rightHoistedVariablesEnd) { + left.splice(leftHoistedVariablesEnd, 0, ...declarations.slice(rightHoistedVariablesEnd, rightCustomPrologueEnd)); + } + + // splice hoisted variables from right into left + if (rightHoistedVariablesEnd > rightHoistedFunctionsEnd) { + left.splice(leftHoistedFunctionsEnd, 0, ...declarations.slice(rightHoistedFunctionsEnd, rightHoistedVariablesEnd)); + } + + // splice hoisted functions from right into left + if (rightHoistedFunctionsEnd > rightStandardPrologueEnd) { + left.splice(leftStandardPrologueEnd, 0, ...declarations.slice(rightStandardPrologueEnd, rightHoistedFunctionsEnd)); + } + + // splice standard prologues from right into left (that are not already in left) + if (rightStandardPrologueEnd > 0) { + if (leftStandardPrologueEnd === 0) { + left.splice(0, 0, ...declarations.slice(0, rightStandardPrologueEnd)); + } + else { + const leftPrologues = createMap(); + for (let i = 0; i < leftStandardPrologueEnd; i++) { + const leftPrologue = statements[i] as PrologueDirective; + leftPrologues.set(leftPrologue.expression.text, true); + } + for (let i = rightStandardPrologueEnd - 1; i >= 0; i--) { + const rightPrologue = declarations[i] as PrologueDirective; + if (!leftPrologues.has(rightPrologue.expression.text)) { + left.unshift(rightPrologue); + } + } + } + } + + if (isNodeArray(statements)) { + return setTextRange(createNodeArray(left, statements.hasTrailingComma), statements); + } + + return statements; + } + + function updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags): T; + function updateModifiers(node: HasModifiers, modifiers: readonly Modifier[] | ModifierFlags) { + if (typeof modifiers === "number") { + modifiers = createModifiersFromModifierFlags(modifiers); + } + return isParameter(node) ? updateParameterDeclaration(node, node.decorators, modifiers, node.dotDotDotToken, node.name, node.questionToken, node.type, node.initializer) : + isPropertySignature(node) ? updatePropertySignature(node, modifiers, node.name, node.questionToken, node.type) : + isPropertyDeclaration(node) ? updatePropertyDeclaration(node, node.decorators, modifiers, node.name, node.questionToken ?? node.exclamationToken, node.type, node.initializer) : + isMethodSignature(node) ? updateMethodSignature(node, modifiers, node.name, node.questionToken, node.typeParameters, node.parameters, node.type) : + isMethodDeclaration(node) ? updateMethodDeclaration(node, node.decorators, modifiers, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body) : + isConstructorDeclaration(node) ? updateConstructorDeclaration(node, node.decorators, modifiers, node.parameters, node.body) : + isGetAccessorDeclaration(node) ? updateGetAccessorDeclaration(node, node.decorators, modifiers, node.name, node.parameters, node.type, node.body) : + isSetAccessorDeclaration(node) ? updateSetAccessorDeclaration(node, node.decorators, modifiers, node.name, node.parameters, node.body) : + isIndexSignatureDeclaration(node) ? updateIndexSignature(node, node.decorators, modifiers, node.parameters, node.type) : + isFunctionExpression(node) ? updateFunctionExpression(node, modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) : + isArrowFunction(node) ? updateArrowFunction(node, modifiers, node.typeParameters, node.parameters, node.type, node.equalsGreaterThanToken, node.body) : + isClassExpression(node) ? updateClassExpression(node, node.decorators, modifiers, node.name, node.typeParameters, node.heritageClauses, node.members) : + isVariableStatement(node) ? updateVariableStatement(node, modifiers, node.declarationList) : + isFunctionDeclaration(node) ? updateFunctionDeclaration(node, node.decorators, modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body) : + isClassDeclaration(node) ? updateClassDeclaration(node, node.decorators, modifiers, node.name, node.typeParameters, node.heritageClauses, node.members) : + isInterfaceDeclaration(node) ? updateInterfaceDeclaration(node, node.decorators, modifiers, node.name, node.typeParameters, node.heritageClauses, node.members) : + isTypeAliasDeclaration(node) ? updateTypeAliasDeclaration(node, node.decorators, modifiers, node.name, node.typeParameters, node.type) : + isEnumDeclaration(node) ? updateEnumDeclaration(node, node.decorators, modifiers, node.name, node.members) : + isModuleDeclaration(node) ? updateModuleDeclaration(node, node.decorators, modifiers, node.name, node.body) : + isImportEqualsDeclaration(node) ? updateImportEqualsDeclaration(node, node.decorators, modifiers, node.name, node.moduleReference) : + isImportDeclaration(node) ? updateImportDeclaration(node, node.decorators, modifiers, node.importClause, node.moduleSpecifier) : + isExportAssignment(node) ? updateExportAssignment(node, node.decorators, modifiers, node.expression) : + isExportDeclaration(node) ? updateExportDeclaration(node, node.decorators, modifiers, node.isTypeOnly, node.exportClause, node.moduleSpecifier) : + Debug.assertNever(node); + } + + function asNodeArray(array: readonly T[]): NodeArray; + function asNodeArray(array: readonly T[] | undefined): NodeArray | undefined; + function asNodeArray(array: readonly T[] | undefined): NodeArray | undefined { + return array ? createNodeArray(array) : undefined; + } + + function asName(name: string | T): T | Identifier { + return typeof name === "string" ? createIdentifier(name) : + name; + } + + function asExpression(value: string | number | boolean | T): T | StringLiteral | NumericLiteral | BooleanLiteral { + return typeof value === "string" ? createStringLiteral(value) : + typeof value === "number" ? createNumericLiteral(value) : + typeof value === "boolean" ? value ? createTrue() : createFalse() : + value; + } + + function asToken(value: TKind | Token): Token { + return typeof value === "number" ? createToken(value) : value; + } + + function asEmbeddedStatement(statement: T): T | EmptyStatement; + function asEmbeddedStatement(statement: T | undefined): T | EmptyStatement | undefined; + function asEmbeddedStatement(statement: T | undefined): T | EmptyStatement | undefined { + return statement && isNotEmittedStatement(statement) ? setTextRange(setOriginalNode(createEmptyStatement(), statement), statement) : statement; + } + } + + function updateWithoutOriginal(updated: T, original: T): T { + if (updated !== original) { + setTextRange(updated, original); + } + return updated; + } + + function updateWithOriginal(updated: T, original: T): T { + if (updated !== original) { + setOriginalNode(updated, original); + setTextRange(updated, original); + } + return updated; + } + + function getDefaultTagNameForKind(kind: JSDocTag["kind"]): string { + switch (kind) { + case SyntaxKind.JSDocTypeTag: return "type"; + case SyntaxKind.JSDocReturnTag: return "returns"; + case SyntaxKind.JSDocThisTag: return "this"; + case SyntaxKind.JSDocEnumTag: return "enum"; + case SyntaxKind.JSDocAuthorTag: return "author"; + case SyntaxKind.JSDocClassTag: return "class"; + case SyntaxKind.JSDocPublicTag: return "public"; + case SyntaxKind.JSDocPrivateTag: return "private"; + case SyntaxKind.JSDocProtectedTag: return "protected"; + case SyntaxKind.JSDocReadonlyTag: return "readonly"; + case SyntaxKind.JSDocTemplateTag: return "template"; + case SyntaxKind.JSDocTypedefTag: return "typedef"; + case SyntaxKind.JSDocParameterTag: return "param"; + case SyntaxKind.JSDocPropertyTag: return "prop"; + case SyntaxKind.JSDocCallbackTag: return "callback"; + case SyntaxKind.JSDocAugmentsTag: return "augments"; + case SyntaxKind.JSDocImplementsTag: return "implements"; + default: + return Debug.fail(`Unsupported kind: ${Debug.formatSyntaxKind(kind)}`); + } + } + + let rawTextScanner: Scanner | undefined; + const invalidValueSentinel: object = { }; + + function getCookedText(kind: TemplateLiteralToken["kind"], rawText: string) { + if (!rawTextScanner) { + rawTextScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard); + } + switch (kind) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + rawTextScanner.setText("`" + rawText + "`"); + break; + case SyntaxKind.TemplateHead: + // tslint:disable-next-line no-invalid-template-strings + rawTextScanner.setText("`" + rawText + "${"); + break; + case SyntaxKind.TemplateMiddle: + // tslint:disable-next-line no-invalid-template-strings + rawTextScanner.setText("}" + rawText + "${"); + break; + case SyntaxKind.TemplateTail: + rawTextScanner.setText("}" + rawText + "`"); + break; + } + + let token = rawTextScanner.scan(); + if (token === SyntaxKind.CloseBracketToken) { + token = rawTextScanner.reScanTemplateToken(/*isTaggedTemplate*/ false); + } + + if (rawTextScanner.isUnterminated()) { + rawTextScanner.setText(undefined); + return invalidValueSentinel; + } + + let tokenValue: string | undefined; + switch (token) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateHead: + case SyntaxKind.TemplateMiddle: + case SyntaxKind.TemplateTail: + tokenValue = rawTextScanner.getTokenValue(); + break; + } + + if (tokenValue === undefined || rawTextScanner.scan() !== SyntaxKind.EndOfFileToken) { + rawTextScanner.setText(undefined); + return invalidValueSentinel; + } + + rawTextScanner.setText(undefined); + return tokenValue; + } + + function propagatePropertyNameFlags(node: PropertyName, transformFlags: TransformFlags) { + return transformFlags | (node.transformFlags & TransformFlags.PropertyNamePropagatingFlags); + } + + function propagateChildFlags(child: Node | undefined): TransformFlags { + if (!child) return TransformFlags.None; + const childFlags = child.transformFlags & ~getTransformFlagsSubtreeExclusions(child.kind); + return isNamedDeclaration(child) && isPropertyName(child.name) ? propagatePropertyNameFlags(child.name, childFlags) : childFlags; + } + + function propagateChildrenFlags(children: NodeArray | undefined): TransformFlags { + return children ? children.transformFlags : TransformFlags.None; + } + + function aggregateChildrenFlags(children: MutableNodeArray) { + let subtreeFlags = TransformFlags.None; + for (const child of children) { + subtreeFlags |= propagateChildFlags(child); + } + children.transformFlags = subtreeFlags; + } + + /** + * Gets the transform flags to exclude when unioning the transform flags of a subtree. + */ + /* @internal */ + export function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) { + if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) { + return TransformFlags.TypeExcludes; + } + + switch (kind) { + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + case SyntaxKind.ArrayLiteralExpression: + return TransformFlags.ArrayLiteralOrCallOrNewExcludes; + case SyntaxKind.ModuleDeclaration: + return TransformFlags.ModuleExcludes; + case SyntaxKind.Parameter: + return TransformFlags.ParameterExcludes; + case SyntaxKind.ArrowFunction: + return TransformFlags.ArrowFunctionExcludes; + case SyntaxKind.FunctionExpression: + case SyntaxKind.FunctionDeclaration: + return TransformFlags.FunctionExcludes; + case SyntaxKind.VariableDeclarationList: + return TransformFlags.VariableDeclarationListExcludes; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + return TransformFlags.ClassExcludes; + case SyntaxKind.Constructor: + return TransformFlags.ConstructorExcludes; + case SyntaxKind.PropertyDeclaration: + return TransformFlags.PropertyExcludes; + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return TransformFlags.MethodOrAccessorExcludes; + case SyntaxKind.AnyKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.BigIntKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.ObjectKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.VoidKeyword: + case SyntaxKind.TypeParameter: + case SyntaxKind.PropertySignature: + case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.IndexSignature: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.TypeAliasDeclaration: + return TransformFlags.TypeExcludes; + case SyntaxKind.ObjectLiteralExpression: + return TransformFlags.ObjectLiteralExcludes; + case SyntaxKind.CatchClause: + return TransformFlags.CatchClauseExcludes; + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: + return TransformFlags.BindingPatternExcludes; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + case SyntaxKind.PartiallyEmittedExpression: + case SyntaxKind.ParenthesizedExpression: + case SyntaxKind.SuperKeyword: + return TransformFlags.OuterExpressionExcludes; + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + return TransformFlags.PropertyAccessExcludes; + default: + return TransformFlags.NodeExcludes; + } + } + + const baseFactory = createBaseNodeFactory(); + + function makeSynthetic(node: Node) { + (node as Mutable).flags |= NodeFlags.Synthesized; + return node; + } + + const syntheticFactory: BaseNodeFactory = { + createBaseSourceFileNode: kind => makeSynthetic(baseFactory.createBaseSourceFileNode(kind)), + createBaseIdentifierNode: kind => makeSynthetic(baseFactory.createBaseIdentifierNode(kind)), + createBasePrivateIdentifierNode: kind => makeSynthetic(baseFactory.createBasePrivateIdentifierNode(kind)), + createBaseTokenNode: kind => makeSynthetic(baseFactory.createBaseTokenNode(kind)), + createBaseNode: kind => makeSynthetic(baseFactory.createBaseNode(kind)), + }; + + export const factory = createNodeFactory(NodeFactoryFlags.NoIndentationOnFreshPropertyAccess, syntheticFactory); + + export function createUnparsedSourceFile(text: string): UnparsedSource; + export function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; + export function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; + export function createUnparsedSourceFile(textOrInputFiles: string | InputFiles, mapPathOrType?: string, mapTextOrStripInternal?: string | boolean): UnparsedSource { + let stripInternal: boolean | undefined; + let bundleFileInfo: BundleFileInfo | undefined; + let fileName: string; + let text: string | undefined; + let length: number | (() => number); + let sourceMapPath: string | undefined; + let sourceMapText: string | undefined; + let getText: (() => string) | undefined; + let getSourceMapText: (() => string | undefined) | undefined; + let oldFileOfCurrentEmit: boolean | undefined; + + if (!isString(textOrInputFiles)) { + Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts"); + fileName = (mapPathOrType === "js" ? textOrInputFiles.javascriptPath : textOrInputFiles.declarationPath) || ""; + sourceMapPath = mapPathOrType === "js" ? textOrInputFiles.javascriptMapPath : textOrInputFiles.declarationMapPath; + getText = () => mapPathOrType === "js" ? textOrInputFiles.javascriptText : textOrInputFiles.declarationText; + getSourceMapText = () => mapPathOrType === "js" ? textOrInputFiles.javascriptMapText : textOrInputFiles.declarationMapText; + length = () => getText!().length; + if (textOrInputFiles.buildInfo && textOrInputFiles.buildInfo.bundle) { + Debug.assert(mapTextOrStripInternal === undefined || typeof mapTextOrStripInternal === "boolean"); + stripInternal = mapTextOrStripInternal; + bundleFileInfo = mapPathOrType === "js" ? textOrInputFiles.buildInfo.bundle.js : textOrInputFiles.buildInfo.bundle.dts; + oldFileOfCurrentEmit = textOrInputFiles.oldFileOfCurrentEmit; + } + } + else { + fileName = ""; + text = textOrInputFiles; + length = textOrInputFiles.length; + sourceMapPath = mapPathOrType; + sourceMapText = mapTextOrStripInternal as string; + } + const node = oldFileOfCurrentEmit ? + parseOldFileOfCurrentEmit(Debug.assertDefined(bundleFileInfo)) : + parseUnparsedSourceFile(bundleFileInfo, stripInternal, length); + node.fileName = fileName; + node.sourceMapPath = sourceMapPath; + node.oldFileOfCurrentEmit = oldFileOfCurrentEmit; + if (getText && getSourceMapText) { + Object.defineProperty(node, "text", { get: getText }); + Object.defineProperty(node, "sourceMapText", { get: getSourceMapText }); + } + else { + Debug.assert(!oldFileOfCurrentEmit); + node.text = text ?? ""; + node.sourceMapText = sourceMapText; + } + + return node; + } + + function parseUnparsedSourceFile(bundleFileInfo: BundleFileInfo | undefined, stripInternal: boolean | undefined, length: number | (() => number)) { + let prologues: UnparsedPrologue[] | undefined; + let helpers: UnscopedEmitHelper[] | undefined; + let referencedFiles: FileReference[] | undefined; + let typeReferenceDirectives: string[] | undefined; + let libReferenceDirectives: FileReference[] | undefined; + let prependChildren: UnparsedTextLike[] | undefined; + let texts: UnparsedSourceText[] | undefined; + let hasNoDefaultLib: boolean | undefined; + + for (const section of bundleFileInfo ? bundleFileInfo.sections : emptyArray) { + switch (section.kind) { + case BundleFileSectionKind.Prologue: + prologues = append(prologues, setTextRange(factory.createUnparsedPrologue(section.data), section)); + break; + case BundleFileSectionKind.EmitHelpers: + helpers = append(helpers, getAllUnscopedEmitHelpers().get(section.data)!); + break; + case BundleFileSectionKind.NoDefaultLib: + hasNoDefaultLib = true; + break; + case BundleFileSectionKind.Reference: + referencedFiles = append(referencedFiles, { pos: -1, end: -1, fileName: section.data }); + break; + case BundleFileSectionKind.Type: + typeReferenceDirectives = append(typeReferenceDirectives, section.data); + break; + case BundleFileSectionKind.Lib: + libReferenceDirectives = append(libReferenceDirectives, { pos: -1, end: -1, fileName: section.data }); + break; + case BundleFileSectionKind.Prepend: + let prependTexts: UnparsedTextLike[] | undefined; + for (const text of section.texts) { + if (!stripInternal || text.kind !== BundleFileSectionKind.Internal) { + prependTexts = append(prependTexts, setTextRange(factory.createUnparsedTextLike(text.data, text.kind === BundleFileSectionKind.Internal), text)); + } + } + prependChildren = addRange(prependChildren, prependTexts); + texts = append(texts, factory.createUnparsedPrepend(section.data, prependTexts ?? emptyArray)); + break; + case BundleFileSectionKind.Internal: + if (stripInternal) { + if (!texts) texts = []; + break; + } + // falls through + + case BundleFileSectionKind.Text: + texts = append(texts, setTextRange(factory.createUnparsedTextLike(section.data, section.kind === BundleFileSectionKind.Internal), section)); + break; + default: + Debug.assertNever(section); + } + } + + if (!texts) { + const textNode = factory.createUnparsedTextLike(/*data*/ undefined, /*internal*/ false); + setTextRangePosWidth(textNode, 0, typeof length === "function" ? length() : length); + texts = [textNode]; + } + + const node = parseNodeFactory.createUnparsedSource(prologues ?? emptyArray, /*syntheticReferences*/ undefined, texts); + setEachParent(prologues, node); + setEachParent(texts, node); + setEachParent(prependChildren, node); + node.hasNoDefaultLib = hasNoDefaultLib; + node.helpers = helpers; + node.referencedFiles = referencedFiles || emptyArray; + node.typeReferenceDirectives = typeReferenceDirectives; + node.libReferenceDirectives = libReferenceDirectives || emptyArray; + return node; + } + + function parseOldFileOfCurrentEmit(bundleFileInfo: BundleFileInfo) { + let texts: UnparsedTextLike[] | undefined; + let syntheticReferences: UnparsedSyntheticReference[] | undefined; + for (const section of bundleFileInfo.sections) { + switch (section.kind) { + case BundleFileSectionKind.Internal: + case BundleFileSectionKind.Text: + texts = append(texts, setTextRange(factory.createUnparsedTextLike(section.data, section.kind === BundleFileSectionKind.Internal), section)); + break; + + case BundleFileSectionKind.NoDefaultLib: + case BundleFileSectionKind.Reference: + case BundleFileSectionKind.Type: + case BundleFileSectionKind.Lib: + syntheticReferences = append(syntheticReferences, setTextRange(factory.createUnparsedSyntheticReference(section), section)); + break; + + // Ignore + case BundleFileSectionKind.Prologue: + case BundleFileSectionKind.EmitHelpers: + case BundleFileSectionKind.Prepend: + break; + + default: + Debug.assertNever(section); + } + } + + const node = factory.createUnparsedSource(emptyArray, syntheticReferences, texts ?? emptyArray); + setEachParent(syntheticReferences, node); + setEachParent(texts, node); + node.helpers = map(bundleFileInfo.sources && bundleFileInfo.sources.helpers, name => getAllUnscopedEmitHelpers().get(name)!); + return node; + } + + // TODO(rbuckton): Move part of this to factory + export function createInputFiles( + javascriptText: string, + declarationText: string + ): InputFiles; + export function createInputFiles( + readFileText: (path: string) => string | undefined, + javascriptPath: string, + javascriptMapPath: string | undefined, + declarationPath: string, + declarationMapPath: string | undefined, + buildInfoPath: string | undefined + ): InputFiles; + export function createInputFiles( + javascriptText: string, + declarationText: string, + javascriptMapPath: string | undefined, + javascriptMapText: string | undefined, + declarationMapPath: string | undefined, + declarationMapText: string | undefined + ): InputFiles; + /*@internal*/ + export function createInputFiles( + javascriptText: string, + declarationText: string, + javascriptMapPath: string | undefined, + javascriptMapText: string | undefined, + declarationMapPath: string | undefined, + declarationMapText: string | undefined, + javascriptPath: string | undefined, + declarationPath: string | undefined, + buildInfoPath?: string | undefined, + buildInfo?: BuildInfo, + oldFileOfCurrentEmit?: boolean + ): InputFiles; + export function createInputFiles( + javascriptTextOrReadFileText: string | ((path: string) => string | undefined), + declarationTextOrJavascriptPath: string, + javascriptMapPath?: string, + javascriptMapTextOrDeclarationPath?: string, + declarationMapPath?: string, + declarationMapTextOrBuildInfoPath?: string, + javascriptPath?: string | undefined, + declarationPath?: string | undefined, + buildInfoPath?: string | undefined, + buildInfo?: BuildInfo, + oldFileOfCurrentEmit?: boolean + ): InputFiles { + const node = parseNodeFactory.createInputFiles(); + if (!isString(javascriptTextOrReadFileText)) { + const cache = createMap(); + const textGetter = (path: string | undefined) => { + if (path === undefined) return undefined; + let value = cache.get(path); + if (value === undefined) { + value = javascriptTextOrReadFileText(path); + cache.set(path, value !== undefined ? value : false); + } + return value !== false ? value as string : undefined; + }; + const definedTextGetter = (path: string) => { + const result = textGetter(path); + return result !== undefined ? result : `/* Input file ${path} was missing */\r\n`; + }; + let buildInfo: BuildInfo | false; + const getAndCacheBuildInfo = (getText: () => string | undefined) => { + if (buildInfo === undefined) { + const result = getText(); + buildInfo = result !== undefined ? getBuildInfo(result) : false; + } + return buildInfo || undefined; + }; + node.javascriptPath = declarationTextOrJavascriptPath; + node.javascriptMapPath = javascriptMapPath; + node.declarationPath = Debug.assertDefined(javascriptMapTextOrDeclarationPath); + node.declarationMapPath = declarationMapPath; + node.buildInfoPath = declarationMapTextOrBuildInfoPath; + Object.defineProperties(node, { + javascriptText: { get() { return definedTextGetter(declarationTextOrJavascriptPath); } }, + javascriptMapText: { get() { return textGetter(javascriptMapPath); } }, // TODO:: if there is inline sourceMap in jsFile, use that + declarationText: { get() { return definedTextGetter(Debug.assertDefined(javascriptMapTextOrDeclarationPath)); } }, + declarationMapText: { get() { return textGetter(declarationMapPath); } }, // TODO:: if there is inline sourceMap in dtsFile, use that + buildInfo: { get() { return getAndCacheBuildInfo(() => textGetter(declarationMapTextOrBuildInfoPath)); } } + }); + } + else { + node.javascriptText = javascriptTextOrReadFileText; + node.javascriptMapPath = javascriptMapPath; + node.javascriptMapText = javascriptMapTextOrDeclarationPath; + node.declarationText = declarationTextOrJavascriptPath; + node.declarationMapPath = declarationMapPath; + node.declarationMapText = declarationMapTextOrBuildInfoPath; + node.javascriptPath = javascriptPath; + node.declarationPath = declarationPath; + node.buildInfoPath = buildInfoPath; + node.buildInfo = buildInfo; + node.oldFileOfCurrentEmit = oldFileOfCurrentEmit; + } + return node; + } + + // tslint:disable-next-line variable-name + let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; + + /** + * Create an external source map source file reference + */ + export function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource { + return new (SourceMapSource || (SourceMapSource = objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia); + } + + // Utilities + + export function setOriginalNode(node: T, original: Node | undefined): T { + node.original = original; + if (original) { + const emitNode = original.emitNode; + if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); + } + return node; + } + + function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode | undefined) { + const { + flags, + leadingComments, + trailingComments, + commentRange, + sourceMapRange, + tokenSourceMapRanges, + constantValue, + helpers, + startsOnNewLine, + } = sourceEmitNode; + if (!destEmitNode) destEmitNode = {} as EmitNode; + // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later. + if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments); + if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments); + if (flags) destEmitNode.flags = flags; + if (commentRange) destEmitNode.commentRange = commentRange; + if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange; + if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges!); + if (constantValue !== undefined) destEmitNode.constantValue = constantValue; + if (helpers) { + for (const helper of helpers) { + destEmitNode.helpers = appendIfUnique(destEmitNode.helpers, helper); + } + } + if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine; + return destEmitNode; + } + + function mergeTokenSourceMapRanges(sourceRanges: (TextRange | undefined)[], destRanges: (TextRange | undefined)[]) { + if (!destRanges) destRanges = []; + for (const key in sourceRanges) { + destRanges[key] = sourceRanges[key]; + } + return destRanges; + } +} diff --git a/src/compiler/factory/nodeTests.ts b/src/compiler/factory/nodeTests.ts new file mode 100644 index 0000000000000..dd07841c186b6 --- /dev/null +++ b/src/compiler/factory/nodeTests.ts @@ -0,0 +1,818 @@ +namespace ts { + // Literals + + export function isNumericLiteral(node: Node): node is NumericLiteral { + return node.kind === SyntaxKind.NumericLiteral; + } + + export function isBigIntLiteral(node: Node): node is BigIntLiteral { + return node.kind === SyntaxKind.BigIntLiteral; + } + + export function isStringLiteral(node: Node): node is StringLiteral { + return node.kind === SyntaxKind.StringLiteral; + } + + export function isJsxText(node: Node): node is JsxText { + return node.kind === SyntaxKind.JsxText; + } + + export function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral { + return node.kind === SyntaxKind.RegularExpressionLiteral; + } + + export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral { + return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral; + } + + // Pseudo-literals + + export function isTemplateHead(node: Node): node is TemplateHead { + return node.kind === SyntaxKind.TemplateHead; + } + + export function isTemplateMiddle(node: Node): node is TemplateMiddle { + return node.kind === SyntaxKind.TemplateMiddle; + } + + export function isTemplateTail(node: Node): node is TemplateTail { + return node.kind === SyntaxKind.TemplateTail; + } + + // Identifiers + + export function isIdentifier(node: Node): node is Identifier { + return node.kind === SyntaxKind.Identifier; + } + + // Names + + export function isQualifiedName(node: Node): node is QualifiedName { + return node.kind === SyntaxKind.QualifiedName; + } + + export function isComputedPropertyName(node: Node): node is ComputedPropertyName { + return node.kind === SyntaxKind.ComputedPropertyName; + } + + export function isPrivateIdentifier(node: Node): node is PrivateIdentifier { + return node.kind === SyntaxKind.PrivateIdentifier; + } + + // Tokens + + /*@internal*/ + export function isSuperKeyword(node: Node): node is Token { + return node.kind === SyntaxKind.SuperKeyword; + } + + /*@internal*/ + export function isImportKeyword(node: Node): node is Token { + return node.kind === SyntaxKind.ImportKeyword; + } + + /*@internal*/ + export function isCommaToken(node: Node): node is Token { + return node.kind === SyntaxKind.CommaToken; + } + + /*@internal*/ + export function isQuestionToken(node: Node): node is Token { + return node.kind === SyntaxKind.QuestionToken; + } + + /*@internal*/ + export function isExclamationToken(node: Node): node is Token { + return node.kind === SyntaxKind.ExclamationToken; + } + + // Signature elements + + export function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration { + return node.kind === SyntaxKind.TypeParameter; + } + + // TODO(rbuckton): Rename to 'isParameterDeclaration' + export function isParameter(node: Node): node is ParameterDeclaration { + return node.kind === SyntaxKind.Parameter; + } + + export function isDecorator(node: Node): node is Decorator { + return node.kind === SyntaxKind.Decorator; + } + + // TypeMember + + export function isPropertySignature(node: Node): node is PropertySignature { + return node.kind === SyntaxKind.PropertySignature; + } + + export function isPropertyDeclaration(node: Node): node is PropertyDeclaration { + return node.kind === SyntaxKind.PropertyDeclaration; + } + + export function isMethodSignature(node: Node): node is MethodSignature { + return node.kind === SyntaxKind.MethodSignature; + } + + export function isMethodDeclaration(node: Node): node is MethodDeclaration { + return node.kind === SyntaxKind.MethodDeclaration; + } + + export function isConstructorDeclaration(node: Node): node is ConstructorDeclaration { + return node.kind === SyntaxKind.Constructor; + } + + export function isGetAccessorDeclaration(node: Node): node is GetAccessorDeclaration { + return node.kind === SyntaxKind.GetAccessor; + } + + export function isSetAccessorDeclaration(node: Node): node is SetAccessorDeclaration { + return node.kind === SyntaxKind.SetAccessor; + } + + export function isCallSignatureDeclaration(node: Node): node is CallSignatureDeclaration { + return node.kind === SyntaxKind.CallSignature; + } + + export function isConstructSignatureDeclaration(node: Node): node is ConstructSignatureDeclaration { + return node.kind === SyntaxKind.ConstructSignature; + } + + export function isIndexSignatureDeclaration(node: Node): node is IndexSignatureDeclaration { + return node.kind === SyntaxKind.IndexSignature; + } + + // Type + + export function isTypePredicateNode(node: Node): node is TypePredicateNode { + return node.kind === SyntaxKind.TypePredicate; + } + + export function isTypeReferenceNode(node: Node): node is TypeReferenceNode { + return node.kind === SyntaxKind.TypeReference; + } + + export function isFunctionTypeNode(node: Node): node is FunctionTypeNode { + return node.kind === SyntaxKind.FunctionType; + } + + export function isConstructorTypeNode(node: Node): node is ConstructorTypeNode { + return node.kind === SyntaxKind.ConstructorType; + } + + export function isTypeQueryNode(node: Node): node is TypeQueryNode { + return node.kind === SyntaxKind.TypeQuery; + } + + export function isTypeLiteralNode(node: Node): node is TypeLiteralNode { + return node.kind === SyntaxKind.TypeLiteral; + } + + export function isArrayTypeNode(node: Node): node is ArrayTypeNode { + return node.kind === SyntaxKind.ArrayType; + } + + export function isTupleTypeNode(node: Node): node is TupleTypeNode { + return node.kind === SyntaxKind.TupleType; + } + + export function isOptionalTypeNode(node: Node): node is OptionalTypeNode { + return node.kind === SyntaxKind.OptionalType; + } + + export function isRestTypeNode(node: Node): node is RestTypeNode { + return node.kind === SyntaxKind.RestType; + } + + export function isUnionTypeNode(node: Node): node is UnionTypeNode { + return node.kind === SyntaxKind.UnionType; + } + + export function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode { + return node.kind === SyntaxKind.IntersectionType; + } + + export function isConditionalTypeNode(node: Node): node is ConditionalTypeNode { + return node.kind === SyntaxKind.ConditionalType; + } + + export function isInferTypeNode(node: Node): node is InferTypeNode { + return node.kind === SyntaxKind.InferType; + } + + export function isParenthesizedTypeNode(node: Node): node is ParenthesizedTypeNode { + return node.kind === SyntaxKind.ParenthesizedType; + } + + export function isThisTypeNode(node: Node): node is ThisTypeNode { + return node.kind === SyntaxKind.ThisType; + } + + export function isTypeOperatorNode(node: Node): node is TypeOperatorNode { + return node.kind === SyntaxKind.TypeOperator; + } + + export function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode { + return node.kind === SyntaxKind.IndexedAccessType; + } + + export function isMappedTypeNode(node: Node): node is MappedTypeNode { + return node.kind === SyntaxKind.MappedType; + } + + export function isLiteralTypeNode(node: Node): node is LiteralTypeNode { + return node.kind === SyntaxKind.LiteralType; + } + + export function isImportTypeNode(node: Node): node is ImportTypeNode { + return node.kind === SyntaxKind.ImportType; + } + + // Binding patterns + + export function isObjectBindingPattern(node: Node): node is ObjectBindingPattern { + return node.kind === SyntaxKind.ObjectBindingPattern; + } + + export function isArrayBindingPattern(node: Node): node is ArrayBindingPattern { + return node.kind === SyntaxKind.ArrayBindingPattern; + } + + export function isBindingElement(node: Node): node is BindingElement { + return node.kind === SyntaxKind.BindingElement; + } + + // Expression + + export function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression { + return node.kind === SyntaxKind.ArrayLiteralExpression; + } + + export function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression { + return node.kind === SyntaxKind.ObjectLiteralExpression; + } + + export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression { + return node.kind === SyntaxKind.PropertyAccessExpression; + } + + export function isElementAccessExpression(node: Node): node is ElementAccessExpression { + return node.kind === SyntaxKind.ElementAccessExpression; + } + + export function isCallExpression(node: Node): node is CallExpression { + return node.kind === SyntaxKind.CallExpression; + } + + export function isNewExpression(node: Node): node is NewExpression { + return node.kind === SyntaxKind.NewExpression; + } + + export function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression { + return node.kind === SyntaxKind.TaggedTemplateExpression; + } + + export function isTypeAssertionExpression(node: Node): node is TypeAssertion { + return node.kind === SyntaxKind.TypeAssertionExpression; + } + + export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression { + return node.kind === SyntaxKind.ParenthesizedExpression; + } + + export function isFunctionExpression(node: Node): node is FunctionExpression { + return node.kind === SyntaxKind.FunctionExpression; + } + + export function isArrowFunction(node: Node): node is ArrowFunction { + return node.kind === SyntaxKind.ArrowFunction; + } + + export function isDeleteExpression(node: Node): node is DeleteExpression { + return node.kind === SyntaxKind.DeleteExpression; + } + + export function isTypeOfExpression(node: Node): node is TypeOfExpression { + return node.kind === SyntaxKind.TypeOfExpression; + } + + export function isVoidExpression(node: Node): node is VoidExpression { + return node.kind === SyntaxKind.VoidExpression; + } + + export function isAwaitExpression(node: Node): node is AwaitExpression { + return node.kind === SyntaxKind.AwaitExpression; + } + + export function isPrefixUnaryExpression(node: Node): node is PrefixUnaryExpression { + return node.kind === SyntaxKind.PrefixUnaryExpression; + } + + export function isPostfixUnaryExpression(node: Node): node is PostfixUnaryExpression { + return node.kind === SyntaxKind.PostfixUnaryExpression; + } + + export function isBinaryExpression(node: Node): node is BinaryExpression { + return node.kind === SyntaxKind.BinaryExpression; + } + + export function isConditionalExpression(node: Node): node is ConditionalExpression { + return node.kind === SyntaxKind.ConditionalExpression; + } + + export function isTemplateExpression(node: Node): node is TemplateExpression { + return node.kind === SyntaxKind.TemplateExpression; + } + + export function isYieldExpression(node: Node): node is YieldExpression { + return node.kind === SyntaxKind.YieldExpression; + } + + export function isSpreadElement(node: Node): node is SpreadElement { + return node.kind === SyntaxKind.SpreadElement; + } + + export function isClassExpression(node: Node): node is ClassExpression { + return node.kind === SyntaxKind.ClassExpression; + } + + export function isOmittedExpression(node: Node): node is OmittedExpression { + return node.kind === SyntaxKind.OmittedExpression; + } + + export function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments { + return node.kind === SyntaxKind.ExpressionWithTypeArguments; + } + + export function isAsExpression(node: Node): node is AsExpression { + return node.kind === SyntaxKind.AsExpression; + } + + export function isNonNullExpression(node: Node): node is NonNullExpression { + return node.kind === SyntaxKind.NonNullExpression; + } + + export function isMetaProperty(node: Node): node is MetaProperty { + return node.kind === SyntaxKind.MetaProperty; + } + + export function isSyntheticExpression(node: Node): node is SyntheticExpression { + return node.kind === SyntaxKind.SyntheticExpression; + } + + export function isPartiallyEmittedExpression(node: Node): node is PartiallyEmittedExpression { + return node.kind === SyntaxKind.PartiallyEmittedExpression; + } + + export function isCommaListExpression(node: Node): node is CommaListExpression { + return node.kind === SyntaxKind.CommaListExpression; + } + + // Misc + + export function isTemplateSpan(node: Node): node is TemplateSpan { + return node.kind === SyntaxKind.TemplateSpan; + } + + export function isSemicolonClassElement(node: Node): node is SemicolonClassElement { + return node.kind === SyntaxKind.SemicolonClassElement; + } + + // Elements + + export function isBlock(node: Node): node is Block { + return node.kind === SyntaxKind.Block; + } + + export function isVariableStatement(node: Node): node is VariableStatement { + return node.kind === SyntaxKind.VariableStatement; + } + + export function isEmptyStatement(node: Node): node is EmptyStatement { + return node.kind === SyntaxKind.EmptyStatement; + } + + export function isExpressionStatement(node: Node): node is ExpressionStatement { + return node.kind === SyntaxKind.ExpressionStatement; + } + + export function isIfStatement(node: Node): node is IfStatement { + return node.kind === SyntaxKind.IfStatement; + } + + export function isDoStatement(node: Node): node is DoStatement { + return node.kind === SyntaxKind.DoStatement; + } + + export function isWhileStatement(node: Node): node is WhileStatement { + return node.kind === SyntaxKind.WhileStatement; + } + + export function isForStatement(node: Node): node is ForStatement { + return node.kind === SyntaxKind.ForStatement; + } + + export function isForInStatement(node: Node): node is ForInStatement { + return node.kind === SyntaxKind.ForInStatement; + } + + export function isForOfStatement(node: Node): node is ForOfStatement { + return node.kind === SyntaxKind.ForOfStatement; + } + + export function isContinueStatement(node: Node): node is ContinueStatement { + return node.kind === SyntaxKind.ContinueStatement; + } + + export function isBreakStatement(node: Node): node is BreakStatement { + return node.kind === SyntaxKind.BreakStatement; + } + + export function isReturnStatement(node: Node): node is ReturnStatement { + return node.kind === SyntaxKind.ReturnStatement; + } + + export function isWithStatement(node: Node): node is WithStatement { + return node.kind === SyntaxKind.WithStatement; + } + + export function isSwitchStatement(node: Node): node is SwitchStatement { + return node.kind === SyntaxKind.SwitchStatement; + } + + export function isLabeledStatement(node: Node): node is LabeledStatement { + return node.kind === SyntaxKind.LabeledStatement; + } + + export function isThrowStatement(node: Node): node is ThrowStatement { + return node.kind === SyntaxKind.ThrowStatement; + } + + export function isTryStatement(node: Node): node is TryStatement { + return node.kind === SyntaxKind.TryStatement; + } + + export function isDebuggerStatement(node: Node): node is DebuggerStatement { + return node.kind === SyntaxKind.DebuggerStatement; + } + + export function isVariableDeclaration(node: Node): node is VariableDeclaration { + return node.kind === SyntaxKind.VariableDeclaration; + } + + export function isVariableDeclarationList(node: Node): node is VariableDeclarationList { + return node.kind === SyntaxKind.VariableDeclarationList; + } + + export function isFunctionDeclaration(node: Node): node is FunctionDeclaration { + return node.kind === SyntaxKind.FunctionDeclaration; + } + + export function isClassDeclaration(node: Node): node is ClassDeclaration { + return node.kind === SyntaxKind.ClassDeclaration; + } + + export function isInterfaceDeclaration(node: Node): node is InterfaceDeclaration { + return node.kind === SyntaxKind.InterfaceDeclaration; + } + + export function isTypeAliasDeclaration(node: Node): node is TypeAliasDeclaration { + return node.kind === SyntaxKind.TypeAliasDeclaration; + } + + export function isEnumDeclaration(node: Node): node is EnumDeclaration { + return node.kind === SyntaxKind.EnumDeclaration; + } + + export function isModuleDeclaration(node: Node): node is ModuleDeclaration { + return node.kind === SyntaxKind.ModuleDeclaration; + } + + export function isModuleBlock(node: Node): node is ModuleBlock { + return node.kind === SyntaxKind.ModuleBlock; + } + + export function isCaseBlock(node: Node): node is CaseBlock { + return node.kind === SyntaxKind.CaseBlock; + } + + export function isNamespaceExportDeclaration(node: Node): node is NamespaceExportDeclaration { + return node.kind === SyntaxKind.NamespaceExportDeclaration; + } + + export function isImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration { + return node.kind === SyntaxKind.ImportEqualsDeclaration; + } + + export function isImportDeclaration(node: Node): node is ImportDeclaration { + return node.kind === SyntaxKind.ImportDeclaration; + } + + export function isImportClause(node: Node): node is ImportClause { + return node.kind === SyntaxKind.ImportClause; + } + + export function isNamespaceImport(node: Node): node is NamespaceImport { + return node.kind === SyntaxKind.NamespaceImport; + } + + export function isNamespaceExport(node: Node): node is NamespaceExport { + return node.kind === SyntaxKind.NamespaceExport; + } + + export function isNamedImports(node: Node): node is NamedImports { + return node.kind === SyntaxKind.NamedImports; + } + + export function isImportSpecifier(node: Node): node is ImportSpecifier { + return node.kind === SyntaxKind.ImportSpecifier; + } + + export function isExportAssignment(node: Node): node is ExportAssignment { + return node.kind === SyntaxKind.ExportAssignment; + } + + export function isExportDeclaration(node: Node): node is ExportDeclaration { + return node.kind === SyntaxKind.ExportDeclaration; + } + + export function isNamedExports(node: Node): node is NamedExports { + return node.kind === SyntaxKind.NamedExports; + } + + export function isExportSpecifier(node: Node): node is ExportSpecifier { + return node.kind === SyntaxKind.ExportSpecifier; + } + + export function isMissingDeclaration(node: Node): node is MissingDeclaration { + return node.kind === SyntaxKind.MissingDeclaration; + } + + export function isNotEmittedStatement(node: Node): node is NotEmittedStatement { + return node.kind === SyntaxKind.NotEmittedStatement; + } + + /* @internal */ + export function isSyntheticReference(node: Node): node is SyntheticReferenceExpression { + return node.kind === SyntaxKind.SyntheticReferenceExpression; + } + + /* @internal */ + export function isMergeDeclarationMarker(node: Node): node is MergeDeclarationMarker { + return node.kind === SyntaxKind.MergeDeclarationMarker; + } + + /* @internal */ + export function isEndOfDeclarationMarker(node: Node): node is EndOfDeclarationMarker { + return node.kind === SyntaxKind.EndOfDeclarationMarker; + } + + // Module References + + export function isExternalModuleReference(node: Node): node is ExternalModuleReference { + return node.kind === SyntaxKind.ExternalModuleReference; + } + + // JSX + + export function isJsxElement(node: Node): node is JsxElement { + return node.kind === SyntaxKind.JsxElement; + } + + export function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement { + return node.kind === SyntaxKind.JsxSelfClosingElement; + } + + export function isJsxOpeningElement(node: Node): node is JsxOpeningElement { + return node.kind === SyntaxKind.JsxOpeningElement; + } + + export function isJsxClosingElement(node: Node): node is JsxClosingElement { + return node.kind === SyntaxKind.JsxClosingElement; + } + + export function isJsxFragment(node: Node): node is JsxFragment { + return node.kind === SyntaxKind.JsxFragment; + } + + export function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment { + return node.kind === SyntaxKind.JsxOpeningFragment; + } + + export function isJsxClosingFragment(node: Node): node is JsxClosingFragment { + return node.kind === SyntaxKind.JsxClosingFragment; + } + + export function isJsxAttribute(node: Node): node is JsxAttribute { + return node.kind === SyntaxKind.JsxAttribute; + } + + export function isJsxAttributes(node: Node): node is JsxAttributes { + return node.kind === SyntaxKind.JsxAttributes; + } + + export function isJsxSpreadAttribute(node: Node): node is JsxSpreadAttribute { + return node.kind === SyntaxKind.JsxSpreadAttribute; + } + + export function isJsxExpression(node: Node): node is JsxExpression { + return node.kind === SyntaxKind.JsxExpression; + } + + // Clauses + + export function isCaseClause(node: Node): node is CaseClause { + return node.kind === SyntaxKind.CaseClause; + } + + export function isDefaultClause(node: Node): node is DefaultClause { + return node.kind === SyntaxKind.DefaultClause; + } + + export function isHeritageClause(node: Node): node is HeritageClause { + return node.kind === SyntaxKind.HeritageClause; + } + + export function isCatchClause(node: Node): node is CatchClause { + return node.kind === SyntaxKind.CatchClause; + } + + // Property assignments + + export function isPropertyAssignment(node: Node): node is PropertyAssignment { + return node.kind === SyntaxKind.PropertyAssignment; + } + + export function isShorthandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment { + return node.kind === SyntaxKind.ShorthandPropertyAssignment; + } + + export function isSpreadAssignment(node: Node): node is SpreadAssignment { + return node.kind === SyntaxKind.SpreadAssignment; + } + + // Enum + + export function isEnumMember(node: Node): node is EnumMember { + return node.kind === SyntaxKind.EnumMember; + } + + // Unparsed + + // TODO(rbuckton): isUnparsedPrologue + + export function isUnparsedPrepend(node: Node): node is UnparsedPrepend { + return node.kind === SyntaxKind.UnparsedPrepend; + } + + // TODO(rbuckton): isUnparsedText + // TODO(rbuckton): isUnparsedInternalText + // TODO(rbuckton): isUnparsedSyntheticReference + + // Top-level nodes + export function isSourceFile(node: Node): node is SourceFile { + return node.kind === SyntaxKind.SourceFile; + } + + export function isBundle(node: Node): node is Bundle { + return node.kind === SyntaxKind.Bundle; + } + + export function isUnparsedSource(node: Node): node is UnparsedSource { + return node.kind === SyntaxKind.UnparsedSource; + } + + // TODO(rbuckton): isInputFiles + + // JSDoc Elements + + export function isJSDocTypeExpression(node: Node): node is JSDocTypeExpression { + return node.kind === SyntaxKind.JSDocTypeExpression; + } + + export function isJSDocAllType(node: Node): node is JSDocAllType { + return node.kind === SyntaxKind.JSDocAllType; + } + + export function isJSDocUnknownType(node: Node): node is JSDocUnknownType { + return node.kind === SyntaxKind.JSDocUnknownType; + } + + export function isJSDocNullableType(node: Node): node is JSDocNullableType { + return node.kind === SyntaxKind.JSDocNullableType; + } + + export function isJSDocNonNullableType(node: Node): node is JSDocNonNullableType { + return node.kind === SyntaxKind.JSDocNonNullableType; + } + + export function isJSDocOptionalType(node: Node): node is JSDocOptionalType { + return node.kind === SyntaxKind.JSDocOptionalType; + } + + export function isJSDocFunctionType(node: Node): node is JSDocFunctionType { + return node.kind === SyntaxKind.JSDocFunctionType; + } + + export function isJSDocVariadicType(node: Node): node is JSDocVariadicType { + return node.kind === SyntaxKind.JSDocVariadicType; + } + + export function isJSDocNamepathType(node: Node): node is JSDocNamepathType { + return node.kind === SyntaxKind.JSDocNamepathType; + } + + export function isJSDoc(node: Node): node is JSDoc { + return node.kind === SyntaxKind.JSDocComment; + } + + export function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral { + return node.kind === SyntaxKind.JSDocTypeLiteral; + } + + export function isJSDocSignature(node: Node): node is JSDocSignature { + return node.kind === SyntaxKind.JSDocSignature; + } + + // JSDoc Tags + + export function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag { + return node.kind === SyntaxKind.JSDocAugmentsTag; + } + + export function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag { + return node.kind === SyntaxKind.JSDocAuthorTag; + } + + export function isJSDocClassTag(node: Node): node is JSDocClassTag { + return node.kind === SyntaxKind.JSDocClassTag; + } + + export function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag { + return node.kind === SyntaxKind.JSDocCallbackTag; + } + + export function isJSDocPublicTag(node: Node): node is JSDocPublicTag { + return node.kind === SyntaxKind.JSDocPublicTag; + } + + export function isJSDocPrivateTag(node: Node): node is JSDocPrivateTag { + return node.kind === SyntaxKind.JSDocPrivateTag; + } + + export function isJSDocProtectedTag(node: Node): node is JSDocProtectedTag { + return node.kind === SyntaxKind.JSDocProtectedTag; + } + + export function isJSDocReadonlyTag(node: Node): node is JSDocReadonlyTag { + return node.kind === SyntaxKind.JSDocReadonlyTag; + } + + export function isJSDocEnumTag(node: Node): node is JSDocEnumTag { + return node.kind === SyntaxKind.JSDocEnumTag; + } + + export function isJSDocParameterTag(node: Node): node is JSDocParameterTag { + return node.kind === SyntaxKind.JSDocParameterTag; + } + + export function isJSDocReturnTag(node: Node): node is JSDocReturnTag { + return node.kind === SyntaxKind.JSDocReturnTag; + } + + export function isJSDocThisTag(node: Node): node is JSDocThisTag { + return node.kind === SyntaxKind.JSDocThisTag; + } + + export function isJSDocTypeTag(node: Node): node is JSDocTypeTag { + return node.kind === SyntaxKind.JSDocTypeTag; + } + + export function isJSDocTemplateTag(node: Node): node is JSDocTemplateTag { + return node.kind === SyntaxKind.JSDocTemplateTag; + } + + export function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag { + return node.kind === SyntaxKind.JSDocTypedefTag; + } + + export function isJSDocUnknownTag(node: Node): node is JSDocUnknownTag { + return node.kind === SyntaxKind.JSDocTag; + } + + export function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag { + return node.kind === SyntaxKind.JSDocPropertyTag; + } + + export function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag { + return node.kind === SyntaxKind.JSDocImplementsTag; + } + + // Synthesized list + + /* @internal */ + export function isSyntaxList(n: Node): n is SyntaxList { + return n.kind === SyntaxKind.SyntaxList; + } +} diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts new file mode 100644 index 0000000000000..069df2d60c9ae --- /dev/null +++ b/src/compiler/factory/parenthesizerRules.ts @@ -0,0 +1,426 @@ +/* @internal */ +namespace ts { + export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRules { + interface BinaryPlusExpression extends BinaryExpression { + cachedLiteralKind: SyntaxKind; + } + + return { + parenthesizeLeftSideOfBinary, + parenthesizeRightSideOfBinary, + parenthesizeExpressionOfComputedPropertyName, + parenthesizeConditionOfConditionalExpression, + parenthesizeBranchOfConditionalExpression, + parenthesizeExpressionOfExportDefault, + parenthesizeExpressionOfNew, + parenthesizeLeftSideOfAccess, + parenthesizeOperandOfPostfixUnary, + parenthesizeOperandOfPrefixUnary, + parenthesizeExpressionsOfCommaDelimitedList, + parenthesizeExpressionForDisallowedComma, + parenthesizeExpressionOfExpressionStatement, + parenthesizeConciseBodyOfArrowFunction, + parenthesizeMemberOfConditionalType, + parenthesizeMemberOfElementType, + parenthesizeElementTypeOfArrayType, + parenthesizeConstituentTypesOfUnionOrIntersectionType, + parenthesizeTypeArguments, + }; + + /** + * Determines whether the operand to a BinaryExpression needs to be parenthesized. + * + * @param binaryOperator The operator for the BinaryExpression. + * @param operand The operand for the BinaryExpression. + * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the + * BinaryExpression. + */ + function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand: Expression | undefined) { + // If the operand has lower precedence, then it needs to be parenthesized to preserve the + // intent of the expression. For example, if the operand is `a + b` and the operator is + // `*`, then we need to parenthesize the operand to preserve the intended order of + // operations: `(a + b) * x`. + // + // If the operand has higher precedence, then it does not need to be parenthesized. For + // example, if the operand is `a * b` and the operator is `+`, then we do not need to + // parenthesize to preserve the intended order of operations: `a * b + x`. + // + // If the operand has the same precedence, then we need to check the associativity of + // the operator based on whether this is the left or right operand of the expression. + // + // For example, if `a / d` is on the right of operator `*`, we need to parenthesize + // to preserve the intended order of operations: `x * (a / d)` + // + // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve + // the intended order of operations: `(a ** b) ** c` + const binaryOperatorPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, binaryOperator); + const binaryOperatorAssociativity = getOperatorAssociativity(SyntaxKind.BinaryExpression, binaryOperator); + const emittedOperand = skipPartiallyEmittedExpressions(operand); + if (!isLeftSideOfBinary && operand.kind === SyntaxKind.ArrowFunction && binaryOperatorPrecedence > OperatorPrecedence.Assignment) { + // We need to parenthesize arrow functions on the right side to avoid it being + // parsed as parenthesized expression: `a && (() => {})` + return true; + } + const operandPrecedence = getExpressionPrecedence(emittedOperand); + switch (compareValues(operandPrecedence, binaryOperatorPrecedence)) { + case Comparison.LessThan: + // If the operand is the right side of a right-associative binary operation + // and is a yield expression, then we do not need parentheses. + if (!isLeftSideOfBinary + && binaryOperatorAssociativity === Associativity.Right + && operand.kind === SyntaxKind.YieldExpression) { + return false; + } + + return true; + + case Comparison.GreaterThan: + return false; + + case Comparison.EqualTo: + if (isLeftSideOfBinary) { + // No need to parenthesize the left operand when the binary operator is + // left associative: + // (a*b)/x -> a*b/x + // (a**b)/x -> a**b/x + // + // Parentheses are needed for the left operand when the binary operator is + // right associative: + // (a/b)**x -> (a/b)**x + // (a**b)**x -> (a**b)**x + return binaryOperatorAssociativity === Associativity.Right; + } + else { + if (isBinaryExpression(emittedOperand) + && emittedOperand.operatorToken.kind === binaryOperator) { + // No need to parenthesize the right operand when the binary operator and + // operand are the same and one of the following: + // x*(a*b) => x*a*b + // x|(a|b) => x|a|b + // x&(a&b) => x&a&b + // x^(a^b) => x^a^b + if (operatorHasAssociativeProperty(binaryOperator)) { + return false; + } + + // No need to parenthesize the right operand when the binary operator + // is plus (+) if both the left and right operands consist solely of either + // literals of the same kind or binary plus (+) expressions for literals of + // the same kind (recursively). + // "a"+(1+2) => "a"+(1+2) + // "a"+("b"+"c") => "a"+"b"+"c" + if (binaryOperator === SyntaxKind.PlusToken) { + const leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : SyntaxKind.Unknown; + if (isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) { + return false; + } + } + } + + // No need to parenthesize the right operand when the operand is right + // associative: + // x/(a**b) -> x/a**b + // x**(a**b) -> x**a**b + // + // Parentheses are needed for the right operand when the operand is left + // associative: + // x/(a*b) -> x/(a*b) + // x**(a/b) -> x**(a/b) + const operandAssociativity = getExpressionAssociativity(emittedOperand); + return operandAssociativity === Associativity.Left; + } + } + } + + /** + * Determines whether a binary operator is mathematically associative. + * + * @param binaryOperator The binary operator. + */ + function operatorHasAssociativeProperty(binaryOperator: SyntaxKind) { + // The following operators are associative in JavaScript: + // (a*b)*c -> a*(b*c) -> a*b*c + // (a|b)|c -> a|(b|c) -> a|b|c + // (a&b)&c -> a&(b&c) -> a&b&c + // (a^b)^c -> a^(b^c) -> a^b^c + // + // While addition is associative in mathematics, JavaScript's `+` is not + // guaranteed to be associative as it is overloaded with string concatenation. + return binaryOperator === SyntaxKind.AsteriskToken + || binaryOperator === SyntaxKind.BarToken + || binaryOperator === SyntaxKind.AmpersandToken + || binaryOperator === SyntaxKind.CaretToken; + } + + /** + * This function determines whether an expression consists of a homogeneous set of + * literal expressions or binary plus expressions that all share the same literal kind. + * It is used to determine whether the right-hand operand of a binary plus expression can be + * emitted without parentheses. + */ + function getLiteralKindOfBinaryPlusOperand(node: Expression): SyntaxKind { + node = skipPartiallyEmittedExpressions(node); + + if (isLiteralKind(node.kind)) { + return node.kind; + } + + if (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.PlusToken) { + if ((node).cachedLiteralKind !== undefined) { + return (node).cachedLiteralKind; + } + + const leftKind = getLiteralKindOfBinaryPlusOperand((node).left); + const literalKind = isLiteralKind(leftKind) + && leftKind === getLiteralKindOfBinaryPlusOperand((node).right) + ? leftKind + : SyntaxKind.Unknown; + + (node).cachedLiteralKind = literalKind; + return literalKind; + } + + return SyntaxKind.Unknown; + } + + /** + * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended + * order of operations. + * + * @param binaryOperator The operator for the BinaryExpression. + * @param operand The operand for the BinaryExpression. + * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the + * BinaryExpression. + */ + function parenthesizeBinaryOperand(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand?: Expression) { + const skipped = skipPartiallyEmittedExpressions(operand); + + // If the resulting expression is already parenthesized, we do not need to do any further processing. + if (skipped.kind === SyntaxKind.ParenthesizedExpression) { + return operand; + } + + return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) + ? factory.createParenthesizedExpression(operand) + : operand; + } + + + function parenthesizeLeftSideOfBinary(binaryOperator: SyntaxKind, leftSide: Expression): Expression { + return parenthesizeBinaryOperand(binaryOperator, leftSide, /*isLeftSideOfBinary*/ true); + } + + function parenthesizeRightSideOfBinary(binaryOperator: SyntaxKind, leftSide: Expression, rightSide: Expression): Expression { + return parenthesizeBinaryOperand(binaryOperator, rightSide, /*isLeftSideOfBinary*/ false, leftSide); + } + + function parenthesizeExpressionOfComputedPropertyName(expression: Expression): Expression { + return isCommaSequence(expression) ? factory.createParenthesizedExpression(expression) : expression; + } + + function parenthesizeConditionOfConditionalExpression(condition: Expression): Expression { + const conditionalPrecedence = getOperatorPrecedence(SyntaxKind.ConditionalExpression, SyntaxKind.QuestionToken); + const emittedCondition = skipPartiallyEmittedExpressions(condition); + const conditionPrecedence = getExpressionPrecedence(emittedCondition); + if (compareValues(conditionPrecedence, conditionalPrecedence) !== Comparison.GreaterThan) { + return factory.createParenthesizedExpression(condition); + } + return condition; + } + + function parenthesizeBranchOfConditionalExpression(branch: Expression): Expression { + // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions + // so in case when comma expression is introduced as a part of previous transformations + // if should be wrapped in parens since comma operator has the lowest precedence + const emittedExpression = skipPartiallyEmittedExpressions(branch); + return isCommaSequence(emittedExpression) + ? factory.createParenthesizedExpression(branch) + : branch; + } + + /** + * [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but + * has a lookahead restriction for `function`, `async function`, and `class`. + * + * Basically, that means we need to parenthesize in the following cases: + * + * - BinaryExpression of CommaToken + * - CommaList (synthetic list of multiple comma expressions) + * - FunctionExpression + * - ClassExpression + */ + function parenthesizeExpressionOfExportDefault(expression: Expression): Expression { + const check = skipPartiallyEmittedExpressions(expression); + let needsParens = isCommaSequence(check); + if (!needsParens) { + switch (getLeftmostExpression(check, /*stopAtCallExpression*/ false).kind) { + case SyntaxKind.ClassExpression: + case SyntaxKind.FunctionExpression: + needsParens = true; + } + } + return needsParens ? factory.createParenthesizedExpression(expression) : expression; + } + + /** + * Wraps an expression in parentheses if it is needed in order to use the expression + * as the expression of a `NewExpression` node. + */ + function parenthesizeExpressionOfNew(expression: Expression): LeftHandSideExpression { + const leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true); + switch (leftmostExpr.kind) { + case SyntaxKind.CallExpression: + return factory.createParenthesizedExpression(expression); + + case SyntaxKind.NewExpression: + return !(leftmostExpr as NewExpression).arguments + ? factory.createParenthesizedExpression(expression) + : expression as LeftHandSideExpression; // TODO(rbuckton): Verify this assertion holds + } + + return parenthesizeLeftSideOfAccess(expression); + } + + /** + * Wraps an expression in parentheses if it is needed in order to use the expression for + * property or element access. + */ + function parenthesizeLeftSideOfAccess(expression: Expression): LeftHandSideExpression { + // isLeftHandSideExpression is almost the correct criterion for when it is not necessary + // to parenthesize the expression before a dot. The known exception is: + // + // NewExpression: + // new C.x -> not the same as (new C).x + // + const emittedExpression = skipPartiallyEmittedExpressions(expression); + if (isLeftHandSideExpression(emittedExpression) + && (emittedExpression.kind !== SyntaxKind.NewExpression || (emittedExpression).arguments)) { + // TODO(rbuckton): Verify whether this assertion holds. + return expression as LeftHandSideExpression; + } + + // TODO(rbuckton): Verifiy whether `setTextRange` is needed. + return setTextRange(factory.createParenthesizedExpression(expression), expression); + } + + function parenthesizeOperandOfPostfixUnary(operand: Expression): LeftHandSideExpression { + // TODO(rbuckton): Verifiy whether `setTextRange` is needed. + return isLeftHandSideExpression(operand) ? operand : setTextRange(factory.createParenthesizedExpression(operand), operand); + } + + function parenthesizeOperandOfPrefixUnary(operand: Expression): UnaryExpression { + // TODO(rbuckton): Verifiy whether `setTextRange` is needed. + return isUnaryExpression(operand) ? operand : setTextRange(factory.createParenthesizedExpression(operand), operand); + } + + function parenthesizeExpressionsOfCommaDelimitedList(elements: NodeArray): NodeArray { + const result = sameMap(elements, parenthesizeExpressionForDisallowedComma); + return setTextRange(factory.createNodeArray(result, elements.hasTrailingComma), elements); + } + + function parenthesizeExpressionForDisallowedComma(expression: Expression): Expression { + const emittedExpression = skipPartiallyEmittedExpressions(expression); + const expressionPrecedence = getExpressionPrecedence(emittedExpression); + const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken); + // TODO(rbuckton): Verifiy whether `setTextRange` is needed. + return expressionPrecedence > commaPrecedence ? expression : setTextRange(factory.createParenthesizedExpression(expression), expression); + } + + function parenthesizeExpressionOfExpressionStatement(expression: Expression): Expression { + const emittedExpression = skipPartiallyEmittedExpressions(expression); + if (isCallExpression(emittedExpression)) { + const callee = emittedExpression.expression; + const kind = skipPartiallyEmittedExpressions(callee).kind; + if (kind === SyntaxKind.FunctionExpression || kind === SyntaxKind.ArrowFunction) { + // TODO(rbuckton): Verifiy whether `setTextRange` is needed. + const updated = factory.updateCallExpression( + emittedExpression, + setTextRange(factory.createParenthesizedExpression(callee), callee), + emittedExpression.typeArguments, + emittedExpression.arguments + ); + return factory.restoreOuterExpressions(expression, updated, OuterExpressionKinds.PartiallyEmittedExpressions); + } + } + + const leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind; + if (leftmostExpressionKind === SyntaxKind.ObjectLiteralExpression || leftmostExpressionKind === SyntaxKind.FunctionExpression) { + // TODO(rbuckton): Verifiy whether `setTextRange` is needed. + return setTextRange(factory.createParenthesizedExpression(expression), expression); + } + + return expression; + } + + function parenthesizeConciseBodyOfArrowFunction(body: ConciseBody): ConciseBody { + if (!isBlock(body) && (isCommaSequence(body) || getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === SyntaxKind.ObjectLiteralExpression)) { + // TODO(rbuckton): Verifiy whether `setTextRange` is needed. + return setTextRange(factory.createParenthesizedExpression(body), body); + } + + return body; + } + + function parenthesizeMemberOfConditionalType(member: TypeNode): TypeNode { + return member.kind === SyntaxKind.ConditionalType ? factory.createParenthesizedType(member) : member; + } + + function parenthesizeMemberOfElementType(member: TypeNode): TypeNode { + switch (member.kind) { + case SyntaxKind.UnionType: + case SyntaxKind.IntersectionType: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + return factory.createParenthesizedType(member); + } + return parenthesizeMemberOfConditionalType(member); + } + + function parenthesizeElementTypeOfArrayType(member: TypeNode): TypeNode { + switch (member.kind) { + case SyntaxKind.TypeQuery: + case SyntaxKind.TypeOperator: + case SyntaxKind.InferType: + return factory.createParenthesizedType(member); + } + return parenthesizeMemberOfElementType(member); + } + + function parenthesizeConstituentTypesOfUnionOrIntersectionType(members: readonly TypeNode[]): NodeArray { + return factory.createNodeArray(sameMap(members, parenthesizeMemberOfElementType)); + + } + + function parenthesizeOrdinalTypeArgument(node: TypeNode, i: number) { + return i === 0 && isFunctionOrConstructorTypeNode(node) && node.typeParameters ? factory.createParenthesizedType(node) : node; + } + + function parenthesizeTypeArguments(typeArguments: NodeArray | undefined): NodeArray | undefined { + if (some(typeArguments)) { + return factory.createNodeArray(sameMap(typeArguments, parenthesizeOrdinalTypeArgument)); + } + } + } + + export const nullParenthesizerRules: ParenthesizerRules = { + parenthesizeLeftSideOfBinary: (_binaryOperator, leftSide) => leftSide, + parenthesizeRightSideOfBinary: (_binaryOperator, _leftSide, rightSide) => rightSide, + parenthesizeExpressionOfComputedPropertyName: identity, + parenthesizeConditionOfConditionalExpression: identity, + parenthesizeBranchOfConditionalExpression: identity, + parenthesizeExpressionOfExportDefault: identity, + parenthesizeExpressionOfNew: expression => cast(expression, isLeftHandSideExpression), + parenthesizeLeftSideOfAccess: expression => cast(expression, isLeftHandSideExpression), + parenthesizeOperandOfPostfixUnary: operand => cast(operand, isLeftHandSideExpression), + parenthesizeOperandOfPrefixUnary: operand => cast(operand, isUnaryExpression), + parenthesizeExpressionsOfCommaDelimitedList: nodes => cast(nodes, isNodeArray), + parenthesizeExpressionForDisallowedComma: identity, + parenthesizeExpressionOfExpressionStatement: identity, + parenthesizeConciseBodyOfArrowFunction: identity, + parenthesizeMemberOfConditionalType: identity, + parenthesizeMemberOfElementType: identity, + parenthesizeElementTypeOfArrayType: identity, + parenthesizeConstituentTypesOfUnionOrIntersectionType: nodes => cast(nodes, isNodeArray), + parenthesizeTypeArguments: nodes => nodes && cast(nodes, isNodeArray), + }; +} \ No newline at end of file diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts new file mode 100644 index 0000000000000..459b578936901 --- /dev/null +++ b/src/compiler/factory/utilities.ts @@ -0,0 +1,823 @@ +/* @internal */ +namespace ts { + + // Compound nodes + + export function createEmptyExports(factory: NodeFactory) { + return factory.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, factory.createNamedExports([]), /*moduleSpecifier*/ undefined); + } + + export function createMemberAccessForPropertyName(factory: NodeFactory, target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression { + if (isComputedPropertyName(memberName)) { + return setTextRange(factory.createElementAccessExpression(target, memberName.expression), location); + } + else { + const expression = setTextRange( + isIdentifierOrPrivateIdentifier(memberName) + ? factory.createPropertyAccessExpression(target, memberName) + : factory.createElementAccessExpression(target, memberName), + memberName + ); + getOrCreateEmitNode(expression).flags |= EmitFlags.NoNestedSourceMaps; + return expression; + } + } + + function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment) { + // To ensure the emit resolver can properly resolve the namespace, we need to + // treat this identifier as if it were a source tree node by clearing the `Synthesized` + // flag and setting a parent node. + const react = parseNodeFactory.createIdentifier(reactNamespace || "React"); + // Set the parent that is in parse tree + // this makes sure that parent chain is intact for checker to traverse complete scope tree + setParent(react, getParseTreeNode(parent)); + return react; + } + + function createJsxFactoryExpressionFromEntityName(factory: NodeFactory, jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { + if (isQualifiedName(jsxFactory)) { + const left = createJsxFactoryExpressionFromEntityName(factory, jsxFactory.left, parent); + const right = factory.createIdentifier(idText(jsxFactory.right)) as Mutable; + right.escapedText = jsxFactory.right.escapedText; + return factory.createPropertyAccessExpression(left, right); + } + else { + return createReactNamespace(idText(jsxFactory), parent); + } + } + + function createJsxFactoryExpression(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { + return jsxFactoryEntity ? + createJsxFactoryExpressionFromEntityName(factory, jsxFactoryEntity, parent) : + factory.createPropertyAccessExpression( + createReactNamespace(reactNamespace, parent), + "createElement" + ); + } + + export function createExpressionForJsxElement(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, tagName: Expression, props: Expression | undefined, children: readonly Expression[] | undefined, parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression { + const argumentsList = [tagName]; + if (props) { + argumentsList.push(props); + } + + if (children && children.length > 0) { + if (!props) { + argumentsList.push(factory.createNull()); + } + + if (children.length > 1) { + for (const child of children) { + startOnNewLine(child); + argumentsList.push(child); + } + } + else { + argumentsList.push(children[0]); + } + } + + return setTextRange( + factory.createCallExpression( + createJsxFactoryExpression(factory, jsxFactoryEntity, reactNamespace, parentElement), + /*typeArguments*/ undefined, + argumentsList + ), + location + ); + } + + export function createExpressionForJsxFragment(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, children: readonly Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression { + const tagName = factory.createPropertyAccessExpression( + createReactNamespace(reactNamespace, parentElement), + "Fragment" + ); + + const argumentsList = [tagName]; + argumentsList.push(factory.createNull()); + + if (children && children.length > 0) { + if (children.length > 1) { + for (const child of children) { + startOnNewLine(child); + argumentsList.push(child); + } + } + else { + argumentsList.push(children[0]); + } + } + + return setTextRange( + factory.createCallExpression( + createJsxFactoryExpression(factory, jsxFactoryEntity, reactNamespace, parentElement), + /*typeArguments*/ undefined, + argumentsList + ), + location + ); + } + + // Utilities + + export function createForOfBindingStatement(factory: NodeFactory, node: ForInitializer, boundValue: Expression): Statement { + if (isVariableDeclarationList(node)) { + const firstDeclaration = first(node.declarations); + const updatedDeclaration = factory.updateVariableDeclaration( + firstDeclaration, + firstDeclaration.name, + /*exclamationToken*/ undefined, + /*type*/ undefined, + boundValue + ); + return setTextRange( + factory.createVariableStatement( + /*modifiers*/ undefined, + factory.updateVariableDeclarationList(node, [updatedDeclaration]) + ), + /*location*/ node + ); + } + else { + const updatedExpression = setTextRange(factory.createAssignment(node, boundValue), /*location*/ node); + return setTextRange(factory.createExpressionStatement(updatedExpression), /*location*/ node); + } + } + + export function insertLeadingStatement(factory: NodeFactory, dest: Statement, source: Statement) { + if (isBlock(dest)) { + return factory.updateBlock(dest, setTextRange(factory.createNodeArray([source, ...dest.statements]), dest.statements)); + } + else { + return factory.createBlock(factory.createNodeArray([dest, source]), /*multiLine*/ true); + } + } + + export function createExpressionFromEntityName(factory: NodeFactory, node: EntityName | Expression): Expression { + if (isQualifiedName(node)) { + const left = createExpressionFromEntityName(factory, node.left); + // TODO(rbuckton): Does this need to be parented? + const right = setParent(setTextRange(factory.cloneNode(node.right), node.right), node.right.parent); + return setTextRange(factory.createPropertyAccessExpression(left, right), node); + } + else { + // TODO(rbuckton): Does this need to be parented? + return setParent(setTextRange(factory.cloneNode(node), node), node.parent); + } + } + + export function createExpressionForPropertyName(factory: NodeFactory, memberName: Exclude): Expression { + if (isIdentifier(memberName)) { + return factory.createStringLiteralFromNode(memberName); + } + else if (isComputedPropertyName(memberName)) { + // TODO(rbuckton): Does this need to be parented? + return setParent(setTextRange(factory.cloneNode(memberName.expression), memberName.expression), memberName.expression.parent); + } + else { + // TODO(rbuckton): Does this need to be parented? + return setParent(setTextRange(factory.cloneNode(memberName), memberName), memberName.parent); + } + } + + function createExpressionForAccessorDeclaration(factory: NodeFactory, properties: NodeArray, property: AccessorDeclaration & { readonly name: Exclude; }, receiver: Expression, multiLine: boolean) { + const { firstAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(properties, property); + if (property === firstAccessor) { + return setTextRange( + factory.createObjectDefinePropertyCall( + receiver, + createExpressionForPropertyName(factory, property.name), + factory.createPropertyDescriptor({ + enumerable: factory.createFalse(), + configurable: true, + get: getAccessor && setTextRange( + setOriginalNode( + factory.createFunctionExpression( + getAccessor.modifiers, + /*asteriskToken*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + getAccessor.parameters, + /*type*/ undefined, + getAccessor.body! // TODO: GH#18217 + ), + getAccessor + ), + getAccessor + ), + set: setAccessor && setTextRange( + setOriginalNode( + factory.createFunctionExpression( + setAccessor.modifiers, + /*asteriskToken*/ undefined, + /*name*/ undefined, + /*typeParameters*/ undefined, + setAccessor.parameters, + /*type*/ undefined, + setAccessor.body! // TODO: GH#18217 + ), + setAccessor + ), + setAccessor + ) + }, !multiLine) + ), + firstAccessor + ); + } + + return undefined; + } + + function createExpressionForPropertyAssignment(factory: NodeFactory, property: PropertyAssignment, receiver: Expression) { + return setOriginalNode( + setTextRange( + factory.createAssignment( + createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name), + property.initializer + ), + property + ), + property + ); + } + + function createExpressionForShorthandPropertyAssignment(factory: NodeFactory, property: ShorthandPropertyAssignment, receiver: Expression) { + return setOriginalNode( + setTextRange( + factory.createAssignment( + createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name), + factory.cloneNode(property.name) + ), + /*location*/ property + ), + /*original*/ property + ); + } + + function createExpressionForMethodDeclaration(factory: NodeFactory, method: MethodDeclaration, receiver: Expression) { + return setOriginalNode( + setTextRange( + factory.createAssignment( + createMemberAccessForPropertyName(factory, receiver, method.name, /*location*/ method.name), + setOriginalNode( + setTextRange( + factory.createFunctionExpression( + method.modifiers, + method.asteriskToken, + /*name*/ undefined, + /*typeParameters*/ undefined, + method.parameters, + /*type*/ undefined, + method.body! // TODO: GH#18217 + ), + /*location*/ method + ), + /*original*/ method + ) + ), + /*location*/ method + ), + /*original*/ method + ); + } + + export function createExpressionForObjectLiteralElementLike(factory: NodeFactory, node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression | undefined { + if (property.name && isPrivateIdentifier(property.name)) { + Debug.failBadSyntaxKind(property.name, "Private identifiers are not allowed in object literals."); + } + switch (property.kind) { + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return createExpressionForAccessorDeclaration(factory, node.properties, property as typeof property & { readonly name: Exclude }, receiver, !!node.multiLine); + case SyntaxKind.PropertyAssignment: + return createExpressionForPropertyAssignment(factory, property, receiver); + case SyntaxKind.ShorthandPropertyAssignment: + return createExpressionForShorthandPropertyAssignment(factory, property, receiver); + case SyntaxKind.MethodDeclaration: + return createExpressionForMethodDeclaration(factory, property, receiver); + } + } + + /** + * Gets whether an identifier should only be referred to by its internal name. + */ + export function isInternalName(node: Identifier) { + return (getEmitFlags(node) & EmitFlags.InternalName) !== 0; + } + + /** + * Gets whether an identifier should only be referred to by its local name. + */ + export function isLocalName(node: Identifier) { + return (getEmitFlags(node) & EmitFlags.LocalName) !== 0; + } + + /** + * Gets whether an identifier should only be referred to by its export representation if the + * name points to an exported symbol. + */ + export function isExportName(node: Identifier) { + return (getEmitFlags(node) & EmitFlags.ExportName) !== 0; + } + + function isUseStrictPrologue(node: ExpressionStatement): boolean { + return isStringLiteral(node.expression) && node.expression.text === "use strict"; + } + + export function findUseStrictPrologue(statements: readonly Statement[]): Statement | undefined { + for (const statement of statements) { + if (isPrologueDirective(statement)) { + if (isUseStrictPrologue(statement)) { + return statement; + } + } + else { + break; + } + } + return undefined; + } + + export function startsWithUseStrict(statements: readonly Statement[]) { + const firstStatement = firstOrUndefined(statements); + return firstStatement !== undefined + && isPrologueDirective(firstStatement) + && isUseStrictPrologue(firstStatement); + } + + export function isCommaSequence(node: Expression): node is BinaryExpression & {operatorToken: Token} | CommaListExpression { + return node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.CommaToken || + node.kind === SyntaxKind.CommaListExpression; + } + + export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression { + switch (node.kind) { + case SyntaxKind.ParenthesizedExpression: + return (kinds & OuterExpressionKinds.Parentheses) !== 0; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + return (kinds & OuterExpressionKinds.TypeAssertions) !== 0; + case SyntaxKind.NonNullExpression: + return (kinds & OuterExpressionKinds.NonNullAssertions) !== 0; + case SyntaxKind.PartiallyEmittedExpression: + return (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) !== 0; + } + return false; + } + + export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; + export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node; + export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) { + while (isOuterExpression(node, kinds)) { + node = node.expression; + } + return node; + } + + export function skipAssertions(node: Expression): Expression; + export function skipAssertions(node: Node): Node; + export function skipAssertions(node: Node): Node { + return skipOuterExpressions(node, OuterExpressionKinds.Assertions); + } + + export function startOnNewLine(node: T): T { + return setStartsOnNewLine(node, /*newLine*/ true); + } + + export function getExternalHelpersModuleName(node: SourceFile) { + const parseNode = getOriginalNode(node, isSourceFile); + const emitNode = parseNode && parseNode.emitNode; + return emitNode && emitNode.externalHelpersModuleName; + } + + export function hasRecordedExternalHelpers(sourceFile: SourceFile) { + const parseNode = getOriginalNode(sourceFile, isSourceFile); + const emitNode = parseNode && parseNode.emitNode; + return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers); + } + + export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: NodeFactory, helperFactory: EmitHelperFactory, sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) { + if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) { + let namedBindings: NamedImportBindings | undefined; + const moduleKind = getEmitModuleKind(compilerOptions); + if (moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) { + // use named imports + const helpers = getEmitHelpers(sourceFile); + if (helpers) { + const helperNames: string[] = []; + for (const helper of helpers) { + if (!helper.scoped) { + const importName = (helper as UnscopedEmitHelper).importName; + if (importName) { + pushIfUnique(helperNames, importName); + } + } + } + if (some(helperNames)) { + helperNames.sort(compareStringsCaseSensitive); + // Alias the imports if the names are used somewhere in the file. + // NOTE: We don't need to care about global import collisions as this is a module. + namedBindings = nodeFactory.createNamedImports( + map(helperNames, name => isFileLevelUniqueName(sourceFile, name) + ? nodeFactory.createImportSpecifier(/*propertyName*/ undefined, nodeFactory.createIdentifier(name)) + : nodeFactory.createImportSpecifier(nodeFactory.createIdentifier(name), helperFactory.getUnscopedHelperName(name)) + ) + ); + const parseNode = getOriginalNode(sourceFile, isSourceFile); + const emitNode = getOrCreateEmitNode(parseNode); + emitNode.externalHelpers = true; + } + } + } + else { + // use a namespace import + const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(nodeFactory, sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar || hasImportDefault); + if (externalHelpersModuleName) { + namedBindings = nodeFactory.createNamespaceImport(externalHelpersModuleName); + } + } + if (namedBindings) { + const externalHelpersImportDeclaration = nodeFactory.createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings), + nodeFactory.createStringLiteral(externalHelpersModuleNameText) + ); + addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper); + return externalHelpersImportDeclaration; + } + } + } + + export function getOrCreateExternalHelpersModuleNameIfNeeded(factory: NodeFactory, node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) { + if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) { + const externalHelpersModuleName = getExternalHelpersModuleName(node); + if (externalHelpersModuleName) { + return externalHelpersModuleName; + } + + const moduleKind = getEmitModuleKind(compilerOptions); + let create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault)) + && moduleKind !== ModuleKind.System + && moduleKind < ModuleKind.ES2015; + if (!create) { + const helpers = getEmitHelpers(node); + if (helpers) { + for (const helper of helpers) { + if (!helper.scoped) { + create = true; + break; + } + } + } + } + + if (create) { + const parseNode = getOriginalNode(node, isSourceFile); + const emitNode = getOrCreateEmitNode(parseNode); + return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = factory.createUniqueName(externalHelpersModuleNameText)); + } + } + } + + /** + * Get the name of that target module from an import or export declaration + */ + export function getLocalNameForExternalImport(factory: NodeFactory, node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier | undefined { + const namespaceDeclaration = getNamespaceDeclarationNode(node); + if (namespaceDeclaration && !isDefaultImport(node)) { + const name = namespaceDeclaration.name; + return isGeneratedIdentifier(name) ? name : factory.createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name)); + } + if (node.kind === SyntaxKind.ImportDeclaration && node.importClause) { + return factory.getGeneratedNameForNode(node); + } + if (node.kind === SyntaxKind.ExportDeclaration && node.moduleSpecifier) { + return factory.getGeneratedNameForNode(node); + } + return undefined; + } + + /** + * Get the name of a target module from an import/export declaration as should be written in the emitted output. + * The emitted output name can be different from the input if: + * 1. The module has a /// + * 2. --out or --outFile is used, making the name relative to the rootDir + * 3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System). + * Otherwise, a new StringLiteral node representing the module name will be returned. + */ + export function getExternalModuleNameLiteral(factory: NodeFactory, importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { + const moduleName = getExternalModuleName(importNode)!; // TODO: GH#18217 + if (moduleName.kind === SyntaxKind.StringLiteral) { + return tryGetModuleNameFromDeclaration(importNode, host, factory, resolver, compilerOptions) + || tryRenameExternalModule(factory, moduleName, sourceFile) + || factory.cloneNode(moduleName); + } + + return undefined; + } + + /** + * Some bundlers (SystemJS builder) sometimes want to rename dependencies. + * Here we check if alternative name was provided for a given moduleName and return it if possible. + */ + function tryRenameExternalModule(factory: NodeFactory, moduleName: LiteralExpression, sourceFile: SourceFile) { + const rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text); + return rename && factory.createStringLiteral(rename); + } + + /** + * Get the name of a module as should be written in the emitted output. + * The emitted output name can be different from the input if: + * 1. The module has a /// + * 2. --out or --outFile is used, making the name relative to the rootDir + * Otherwise, a new StringLiteral node representing the module name will be returned. + */ + export function tryGetModuleNameFromFile(factory: NodeFactory, file: SourceFile | undefined, host: EmitHost, options: CompilerOptions): StringLiteral | undefined { + if (!file) { + return undefined; + } + if (file.moduleName) { + return factory.createStringLiteral(file.moduleName); + } + if (!file.isDeclarationFile && outFile(options)) { + return factory.createStringLiteral(getExternalModuleNameFromPath(host, file.fileName)); + } + return undefined; + } + + function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration, host: EmitHost, factory: NodeFactory, resolver: EmitResolver, compilerOptions: CompilerOptions) { + return tryGetModuleNameFromFile(factory, resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions); + } + + /** + * Gets the initializer of an BindingOrAssignmentElement. + */ + export function getInitializerOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Expression | undefined { + if (isDeclarationBindingElement(bindingElement)) { + // `1` in `let { a = 1 } = ...` + // `1` in `let { a: b = 1 } = ...` + // `1` in `let { a: {b} = 1 } = ...` + // `1` in `let { a: [b] = 1 } = ...` + // `1` in `let [a = 1] = ...` + // `1` in `let [{a} = 1] = ...` + // `1` in `let [[a] = 1] = ...` + return bindingElement.initializer; + } + + if (isPropertyAssignment(bindingElement)) { + // `1` in `({ a: b = 1 } = ...)` + // `1` in `({ a: {b} = 1 } = ...)` + // `1` in `({ a: [b] = 1 } = ...)` + const initializer = bindingElement.initializer; + return isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true) + ? initializer.right + : undefined; + } + + if (isShorthandPropertyAssignment(bindingElement)) { + // `1` in `({ a = 1 } = ...)` + return bindingElement.objectAssignmentInitializer; + } + + if (isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { + // `1` in `[a = 1] = ...` + // `1` in `[{a} = 1] = ...` + // `1` in `[[a] = 1] = ...` + return bindingElement.right; + } + + if (isSpreadElement(bindingElement)) { + // Recovery consistent with existing emit. + return getInitializerOfBindingOrAssignmentElement(bindingElement.expression); + } + } + + /** + * Gets the name of an BindingOrAssignmentElement. + */ + export function getTargetOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementTarget | undefined { + if (isDeclarationBindingElement(bindingElement)) { + // `a` in `let { a } = ...` + // `a` in `let { a = 1 } = ...` + // `b` in `let { a: b } = ...` + // `b` in `let { a: b = 1 } = ...` + // `a` in `let { ...a } = ...` + // `{b}` in `let { a: {b} } = ...` + // `{b}` in `let { a: {b} = 1 } = ...` + // `[b]` in `let { a: [b] } = ...` + // `[b]` in `let { a: [b] = 1 } = ...` + // `a` in `let [a] = ...` + // `a` in `let [a = 1] = ...` + // `a` in `let [...a] = ...` + // `{a}` in `let [{a}] = ...` + // `{a}` in `let [{a} = 1] = ...` + // `[a]` in `let [[a]] = ...` + // `[a]` in `let [[a] = 1] = ...` + return bindingElement.name; + } + + if (isObjectLiteralElementLike(bindingElement)) { + switch (bindingElement.kind) { + case SyntaxKind.PropertyAssignment: + // `b` in `({ a: b } = ...)` + // `b` in `({ a: b = 1 } = ...)` + // `{b}` in `({ a: {b} } = ...)` + // `{b}` in `({ a: {b} = 1 } = ...)` + // `[b]` in `({ a: [b] } = ...)` + // `[b]` in `({ a: [b] = 1 } = ...)` + // `b.c` in `({ a: b.c } = ...)` + // `b.c` in `({ a: b.c = 1 } = ...)` + // `b[0]` in `({ a: b[0] } = ...)` + // `b[0]` in `({ a: b[0] = 1 } = ...)` + return getTargetOfBindingOrAssignmentElement(bindingElement.initializer); + + case SyntaxKind.ShorthandPropertyAssignment: + // `a` in `({ a } = ...)` + // `a` in `({ a = 1 } = ...)` + return bindingElement.name; + + case SyntaxKind.SpreadAssignment: + // `a` in `({ ...a } = ...)` + return getTargetOfBindingOrAssignmentElement(bindingElement.expression); + } + + // no target + return undefined; + } + + if (isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { + // `a` in `[a = 1] = ...` + // `{a}` in `[{a} = 1] = ...` + // `[a]` in `[[a] = 1] = ...` + // `a.b` in `[a.b = 1] = ...` + // `a[0]` in `[a[0] = 1] = ...` + return getTargetOfBindingOrAssignmentElement(bindingElement.left); + } + + if (isSpreadElement(bindingElement)) { + // `a` in `[...a] = ...` + return getTargetOfBindingOrAssignmentElement(bindingElement.expression); + } + + // `a` in `[a] = ...` + // `{a}` in `[{a}] = ...` + // `[a]` in `[[a]] = ...` + // `a.b` in `[a.b] = ...` + // `a[0]` in `[a[0]] = ...` + return bindingElement; + } + + /** + * Determines whether an BindingOrAssignmentElement is a rest element. + */ + export function getRestIndicatorOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementRestIndicator | undefined { + switch (bindingElement.kind) { + case SyntaxKind.Parameter: + case SyntaxKind.BindingElement: + // `...` in `let [...a] = ...` + return bindingElement.dotDotDotToken; + + case SyntaxKind.SpreadElement: + case SyntaxKind.SpreadAssignment: + // `...` in `[...a] = ...` + return bindingElement; + } + + return undefined; + } + + /** + * Gets the property name of a BindingOrAssignmentElement + */ + export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { + const propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement); + Debug.assert(!!propertyName || isSpreadAssignment(bindingElement), "Invalid property name for binding element."); + return propertyName; + } + + export function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Exclude | undefined { + switch (bindingElement.kind) { + case SyntaxKind.BindingElement: + // `a` in `let { a: b } = ...` + // `[a]` in `let { [a]: b } = ...` + // `"a"` in `let { "a": b } = ...` + // `1` in `let { 1: b } = ...` + if (bindingElement.propertyName) { + const propertyName = bindingElement.propertyName; + if (isPrivateIdentifier(propertyName)) { + return Debug.failBadSyntaxKind(propertyName); + } + return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) + ? propertyName.expression + : propertyName; + } + + break; + + case SyntaxKind.PropertyAssignment: + // `a` in `({ a: b } = ...)` + // `[a]` in `({ [a]: b } = ...)` + // `"a"` in `({ "a": b } = ...)` + // `1` in `({ 1: b } = ...)` + if (bindingElement.name) { + const propertyName = bindingElement.name; + if (isPrivateIdentifier(propertyName)) { + return Debug.failBadSyntaxKind(propertyName); + } + return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression) + ? propertyName.expression + : propertyName; + } + + break; + + case SyntaxKind.SpreadAssignment: + // `a` in `({ ...a } = ...)` + if (bindingElement.name && isPrivateIdentifier(bindingElement.name)) { + return Debug.failBadSyntaxKind(bindingElement.name); + } + return bindingElement.name; + } + + const target = getTargetOfBindingOrAssignmentElement(bindingElement); + if (target && isPropertyName(target)) { + return target; + } + } + + function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral { + const kind = node.kind; + return kind === SyntaxKind.StringLiteral + || kind === SyntaxKind.NumericLiteral; + } + + /** + * Gets the elements of a BindingOrAssignmentPattern + */ + export function getElementsOfBindingOrAssignmentPattern(name: BindingOrAssignmentPattern): readonly BindingOrAssignmentElement[] { + switch (name.kind) { + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: + case SyntaxKind.ArrayLiteralExpression: + // `a` in `{a}` + // `a` in `[a]` + return name.elements; + + case SyntaxKind.ObjectLiteralExpression: + // `a` in `{a}` + return name.properties; + } + } + + /* @internal */ + export function getJSDocTypeAliasName(fullName: JSDocNamespaceBody | undefined) { + if (fullName) { + let rightNode = fullName; + while (true) { + if (isIdentifier(rightNode) || !rightNode.body) { + return isIdentifier(rightNode) ? rightNode : rightNode.name; + } + rightNode = rightNode.body; + } + } + } + + export function canHaveModifiers(node: Node): node is HasModifiers { + const kind = node.kind; + return kind === SyntaxKind.Parameter + || kind === SyntaxKind.PropertySignature + || kind === SyntaxKind.PropertyDeclaration + || kind === SyntaxKind.MethodSignature + || kind === SyntaxKind.MethodDeclaration + || kind === SyntaxKind.Constructor + || kind === SyntaxKind.GetAccessor + || kind === SyntaxKind.SetAccessor + || kind === SyntaxKind.IndexSignature + || kind === SyntaxKind.FunctionExpression + || kind === SyntaxKind.ArrowFunction + || kind === SyntaxKind.ClassExpression + || kind === SyntaxKind.VariableStatement + || kind === SyntaxKind.FunctionDeclaration + || kind === SyntaxKind.ClassDeclaration + || kind === SyntaxKind.InterfaceDeclaration + || kind === SyntaxKind.TypeAliasDeclaration + || kind === SyntaxKind.EnumDeclaration + || kind === SyntaxKind.ModuleDeclaration + || kind === SyntaxKind.ImportEqualsDeclaration + || kind === SyntaxKind.ImportDeclaration + || kind === SyntaxKind.ExportAssignment + || kind === SyntaxKind.ExportDeclaration; + } + + /* @internal */ + export function isAsyncModifier(node: Modifier): node is AsyncKeyword { + return node.kind === SyntaxKind.AsyncKeyword; + } + + /* @internal */ + export function isStaticModifier(node: Modifier): node is StaticKeyword { + return node.kind === SyntaxKind.StaticKeyword; + } +} \ No newline at end of file diff --git a/src/compiler/factory/utilitiesPublic.ts b/src/compiler/factory/utilitiesPublic.ts new file mode 100644 index 0000000000000..9dd28667eb0e1 --- /dev/null +++ b/src/compiler/factory/utilitiesPublic.ts @@ -0,0 +1,5 @@ +namespace ts { + export function setTextRange(range: T, location: TextRange | undefined): T { + return location ? setTextRangePosEnd(range, location.pos, location.end) : range; + } +} \ No newline at end of file diff --git a/src/compiler/factoryPublic.ts b/src/compiler/factoryPublic.ts deleted file mode 100644 index 17e2db983bcfb..0000000000000 --- a/src/compiler/factoryPublic.ts +++ /dev/null @@ -1,3876 +0,0 @@ -namespace ts { - function createSynthesizedNode(kind: SyntaxKind): Node { - const node = createNode(kind, -1, -1); - node.flags |= NodeFlags.Synthesized; - return node; - } - - /* @internal */ - export function updateNode(updated: T, original: T): T { - if (updated !== original) { - setOriginalNode(updated, original); - setTextRange(updated, original); - aggregateTransformFlags(updated); - } - return updated; - } - - /* @internal */ export function createNodeArray(elements?: T[], hasTrailingComma?: boolean): MutableNodeArray; - export function createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray; - /** - * Make `elements` into a `NodeArray`. If `elements` is `undefined`, returns an empty `NodeArray`. - */ - export function createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray { - if (!elements || elements === emptyArray) { - elements = []; - } - else if (isNodeArray(elements)) { - return elements; - } - - const array = >elements; - array.pos = -1; - array.end = -1; - array.hasTrailingComma = hasTrailingComma; - return array; - } - - /** - * Creates a shallow, memberwise clone of a node with no source map location. - */ - /* @internal */ - export function getSynthesizedClone(node: T): T { - // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of - // the original node. We also need to exclude specific properties and only include own- - // properties (to skip members already defined on the shared prototype). - - if (node === undefined) { - return node; - } - - const clone = createSynthesizedNode(node.kind); - clone.flags |= node.flags; - setOriginalNode(clone, node); - - for (const key in node) { - if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) { - continue; - } - - (clone)[key] = (node)[key]; - } - - return clone; - } - - // Literals - - /* @internal */ export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote: boolean): StringLiteral; // eslint-disable-line @typescript-eslint/unified-signatures - /* @internal */ export function createLiteral(value: string | number, isSingleQuote: boolean): StringLiteral | NumericLiteral; - /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; - export function createLiteral(value: number | PseudoBigInt): NumericLiteral; - export function createLiteral(value: boolean): BooleanLiteral; - export function createLiteral(value: string | number | PseudoBigInt | boolean): PrimaryExpression; - export function createLiteral(value: string | number | PseudoBigInt | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression { - if (typeof value === "number") { - return createNumericLiteral(value + ""); - } - // eslint-disable-next-line no-in-operator - if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt - return createBigIntLiteral(pseudoBigIntToString(value) + "n"); - } - if (typeof value === "boolean") { - return value ? createTrue() : createFalse(); - } - if (isString(value)) { - const res = createStringLiteral(value); - if (isSingleQuote) res.singleQuote = true; - return res; - } - return createLiteralFromNode(value); - } - - export function createNumericLiteral(value: string, numericLiteralFlags: TokenFlags = TokenFlags.None): NumericLiteral { - const node = createSynthesizedNode(SyntaxKind.NumericLiteral); - node.text = value; - node.numericLiteralFlags = numericLiteralFlags; - return node; - } - - export function createBigIntLiteral(value: string): BigIntLiteral { - const node = createSynthesizedNode(SyntaxKind.BigIntLiteral); - node.text = value; - return node; - } - - export function createStringLiteral(text: string): StringLiteral { - const node = createSynthesizedNode(SyntaxKind.StringLiteral); - node.text = text; - return node; - } - - export function createRegularExpressionLiteral(text: string): RegularExpressionLiteral { - const node = createSynthesizedNode(SyntaxKind.RegularExpressionLiteral); - node.text = text; - return node; - } - - function createLiteralFromNode(sourceNode: Exclude): StringLiteral { - const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode)); - node.textSourceNode = sourceNode; - return node; - } - - - // Identifiers - - export function createIdentifier(text: string): Identifier; - /* @internal */ - export function createIdentifier(text: string, typeArguments: readonly (TypeNode | TypeParameterDeclaration)[] | undefined): Identifier; // eslint-disable-line @typescript-eslint/unified-signatures - export function createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[]): Identifier { - const node = createSynthesizedNode(SyntaxKind.Identifier); - node.escapedText = escapeLeadingUnderscores(text); - node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; - node.autoGenerateFlags = GeneratedIdentifierFlags.None; - node.autoGenerateId = 0; - if (typeArguments) { - node.typeArguments = createNodeArray(typeArguments as readonly TypeNode[]); - } - return node; - } - - export function updateIdentifier(node: Identifier): Identifier; - /* @internal */ - export function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; // eslint-disable-line @typescript-eslint/unified-signatures - export function updateIdentifier(node: Identifier, typeArguments?: NodeArray | undefined): Identifier { - return node.typeArguments !== typeArguments - ? updateNode(createIdentifier(idText(node), typeArguments), node) - : node; - } - - let nextAutoGenerateId = 0; - - /** Create a unique temporary variable. */ - export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; - /* @internal */ export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes: boolean): GeneratedIdentifier; - export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): GeneratedIdentifier { - const name = createIdentifier("") as GeneratedIdentifier; - name.autoGenerateFlags = GeneratedIdentifierFlags.Auto; - name.autoGenerateId = nextAutoGenerateId; - nextAutoGenerateId++; - if (recordTempVariable) { - recordTempVariable(name); - } - if (reservedInNestedScopes) { - name.autoGenerateFlags |= GeneratedIdentifierFlags.ReservedInNestedScopes; - } - return name; - } - - /** Create a unique temporary variable for use in a loop. */ - export function createLoopVariable(): Identifier { - const name = createIdentifier(""); - name.autoGenerateFlags = GeneratedIdentifierFlags.Loop; - name.autoGenerateId = nextAutoGenerateId; - nextAutoGenerateId++; - return name; - } - - /** Create a unique name based on the supplied text. */ - export function createUniqueName(text: string): Identifier { - const name = createIdentifier(text); - name.autoGenerateFlags = GeneratedIdentifierFlags.Unique; - name.autoGenerateId = nextAutoGenerateId; - nextAutoGenerateId++; - return name; - } - - /* @internal */ export function createOptimisticUniqueName(text: string): GeneratedIdentifier; - /** Create a unique name based on the supplied text. */ - export function createOptimisticUniqueName(text: string): Identifier; - export function createOptimisticUniqueName(text: string): GeneratedIdentifier { - const name = createIdentifier(text) as GeneratedIdentifier; - name.autoGenerateFlags = GeneratedIdentifierFlags.Unique | GeneratedIdentifierFlags.Optimistic; - name.autoGenerateId = nextAutoGenerateId; - nextAutoGenerateId++; - return name; - } - - /** Create a unique name based on the supplied text. This does not consider names injected by the transformer. */ - export function createFileLevelUniqueName(text: string): Identifier { - const name = createOptimisticUniqueName(text); - name.autoGenerateFlags |= GeneratedIdentifierFlags.FileLevel; - return name; - } - - /** Create a unique name generated for a node. */ - export function getGeneratedNameForNode(node: Node | undefined): Identifier; - /* @internal */ export function getGeneratedNameForNode(node: Node | undefined, flags: GeneratedIdentifierFlags): Identifier; // eslint-disable-line @typescript-eslint/unified-signatures - export function getGeneratedNameForNode(node: Node | undefined, flags?: GeneratedIdentifierFlags): Identifier { - const name = createIdentifier(node && isIdentifier(node) ? idText(node) : ""); - name.autoGenerateFlags = GeneratedIdentifierFlags.Node | flags!; - name.autoGenerateId = nextAutoGenerateId; - name.original = node; - nextAutoGenerateId++; - return name; - } - - // Private Identifiers - export function createPrivateIdentifier(text: string): PrivateIdentifier { - if (text[0] !== "#") { - Debug.fail("First character of private identifier must be #: " + text); - } - const node = createSynthesizedNode(SyntaxKind.PrivateIdentifier) as PrivateIdentifier; - node.escapedText = escapeLeadingUnderscores(text); - return node; - } - - // Punctuation - - export function createToken(token: TKind) { - return >createSynthesizedNode(token); - } - - // Reserved words - - export function createSuper() { - return createSynthesizedNode(SyntaxKind.SuperKeyword); - } - - export function createThis() { - return >createSynthesizedNode(SyntaxKind.ThisKeyword); - } - - export function createNull() { - return >createSynthesizedNode(SyntaxKind.NullKeyword); - } - - export function createTrue() { - return >createSynthesizedNode(SyntaxKind.TrueKeyword); - } - - export function createFalse() { - return >createSynthesizedNode(SyntaxKind.FalseKeyword); - } - - // Modifiers - - export function createModifier(kind: T): Token { - return createToken(kind); - } - - export function createModifiersFromModifierFlags(flags: ModifierFlags) { - const result: Modifier[] = []; - if (flags & ModifierFlags.Export) { result.push(createModifier(SyntaxKind.ExportKeyword)); } - if (flags & ModifierFlags.Ambient) { result.push(createModifier(SyntaxKind.DeclareKeyword)); } - if (flags & ModifierFlags.Default) { result.push(createModifier(SyntaxKind.DefaultKeyword)); } - if (flags & ModifierFlags.Const) { result.push(createModifier(SyntaxKind.ConstKeyword)); } - if (flags & ModifierFlags.Public) { result.push(createModifier(SyntaxKind.PublicKeyword)); } - if (flags & ModifierFlags.Private) { result.push(createModifier(SyntaxKind.PrivateKeyword)); } - if (flags & ModifierFlags.Protected) { result.push(createModifier(SyntaxKind.ProtectedKeyword)); } - if (flags & ModifierFlags.Abstract) { result.push(createModifier(SyntaxKind.AbstractKeyword)); } - if (flags & ModifierFlags.Static) { result.push(createModifier(SyntaxKind.StaticKeyword)); } - if (flags & ModifierFlags.Readonly) { result.push(createModifier(SyntaxKind.ReadonlyKeyword)); } - if (flags & ModifierFlags.Async) { result.push(createModifier(SyntaxKind.AsyncKeyword)); } - return result; - } - - // Names - - export function createQualifiedName(left: EntityName, right: string | Identifier) { - const node = createSynthesizedNode(SyntaxKind.QualifiedName); - node.left = left; - node.right = asName(right); - return node; - } - - export function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier) { - return node.left !== left - || node.right !== right - ? updateNode(createQualifiedName(left, right), node) - : node; - } - - function parenthesizeForComputedName(expression: Expression): Expression { - return isCommaSequence(expression) - ? createParen(expression) - : expression; - } - - export function createComputedPropertyName(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.ComputedPropertyName); - node.expression = parenthesizeForComputedName(expression); - return node; - } - - export function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression) { - return node.expression !== expression - ? updateNode(createComputedPropertyName(expression), node) - : node; - } - - // Signature elements - - export function createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; - node.name = asName(name); - node.constraint = constraint; - node.default = defaultType; - return node; - } - - export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) { - return node.name !== name - || node.constraint !== constraint - || node.default !== defaultType - ? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node) - : node; - } - - export function createParameter( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - dotDotDotToken: DotDotDotToken | undefined, - name: string | BindingName, - questionToken?: QuestionToken, - type?: TypeNode, - initializer?: Expression) { - const node = createSynthesizedNode(SyntaxKind.Parameter); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.dotDotDotToken = dotDotDotToken; - node.name = asName(name); - node.questionToken = questionToken; - node.type = type; - node.initializer = initializer ? parenthesizeExpressionForList(initializer) : undefined; - return node; - } - - export function updateParameter( - node: ParameterDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - dotDotDotToken: DotDotDotToken | undefined, - name: string | BindingName, - questionToken: QuestionToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.dotDotDotToken !== dotDotDotToken - || node.name !== name - || node.questionToken !== questionToken - || node.type !== type - || node.initializer !== initializer - ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) - : node; - } - - export function createDecorator(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.Decorator); - node.expression = parenthesizeForAccess(expression); - return node; - } - - export function updateDecorator(node: Decorator, expression: Expression) { - return node.expression !== expression - ? updateNode(createDecorator(expression), node) - : node; - } - - - // Type Elements - - export function createPropertySignature( - modifiers: readonly Modifier[] | undefined, - name: PropertyName | string, - questionToken: QuestionToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined): PropertySignature { - const node = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.questionToken = questionToken; - node.type = type; - node.initializer = initializer; - return node; - } - - export function updatePropertySignature( - node: PropertySignature, - modifiers: readonly Modifier[] | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined) { - return node.modifiers !== modifiers - || node.name !== name - || node.questionToken !== questionToken - || node.type !== type - || node.initializer !== initializer - ? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node) - : node; - } - - export function createProperty( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined) { - const node = createSynthesizedNode(SyntaxKind.PropertyDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.questionToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.QuestionToken ? questionOrExclamationToken : undefined; - node.exclamationToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.ExclamationToken ? questionOrExclamationToken : undefined; - node.type = type; - node.initializer = initializer; - return node; - } - - export function updateProperty( - node: PropertyDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, - type: TypeNode | undefined, - initializer: Expression | undefined) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.questionToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.QuestionToken ? questionOrExclamationToken : undefined) - || node.exclamationToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.ExclamationToken ? questionOrExclamationToken : undefined) - || node.type !== type - || node.initializer !== initializer - ? updateNode(createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer), node) - : node; - } - - export function createMethodSignature( - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - name: string | PropertyName, - questionToken: QuestionToken | undefined) { - const node = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature; - node.name = asName(name); - node.questionToken = questionToken; - return node; - } - - export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined) { - return node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - || node.name !== name - || node.questionToken !== questionToken - ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node) - : node; - } - - export function createMethod( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: string | PropertyName, - questionToken: QuestionToken | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined) { - const node = createSynthesizedNode(SyntaxKind.MethodDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.asteriskToken = asteriskToken; - node.name = asName(name); - node.questionToken = questionToken; - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - return node; - } - - function createMethodCall(object: Expression, methodName: string | Identifier, argumentsList: readonly Expression[]) { - return createCall( - createPropertyAccess(object, asName(methodName)), - /*typeArguments*/ undefined, - argumentsList - ); - } - - function createGlobalMethodCall(globalObjectName: string, methodName: string, argumentsList: readonly Expression[]) { - return createMethodCall(createIdentifier(globalObjectName), methodName, argumentsList); - } - - /* @internal */ - export function createObjectDefinePropertyCall(target: Expression, propertyName: string | Expression, attributes: Expression) { - return createGlobalMethodCall("Object", "defineProperty", [target, asExpression(propertyName), attributes]); - } - - function tryAddPropertyAssignment(properties: Push, propertyName: string, expression: Expression | undefined) { - if (expression) { - properties.push(createPropertyAssignment(propertyName, expression)); - return true; - } - return false; - } - - /* @internal */ - export function createPropertyDescriptor(attributes: PropertyDescriptorAttributes, singleLine?: boolean) { - const properties: PropertyAssignment[] = []; - tryAddPropertyAssignment(properties, "enumerable", asExpression(attributes.enumerable)); - tryAddPropertyAssignment(properties, "configurable", asExpression(attributes.configurable)); - - let isData = tryAddPropertyAssignment(properties, "writable", asExpression(attributes.writable)); - isData = tryAddPropertyAssignment(properties, "value", attributes.value) || isData; - - let isAccessor = tryAddPropertyAssignment(properties, "get", attributes.get); - isAccessor = tryAddPropertyAssignment(properties, "set", attributes.set) || isAccessor; - - Debug.assert(!(isData && isAccessor), "A PropertyDescriptor may not be both an accessor descriptor and a data descriptor."); - return createObjectLiteral(properties, !singleLine); - } - - export function updateMethod( - node: MethodDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.asteriskToken !== asteriskToken - || node.name !== name - || node.questionToken !== questionToken - || node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - || node.body !== body - ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) - : node; - } - - export function createConstructor(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined) { - const node = createSynthesizedNode(SyntaxKind.Constructor); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.typeParameters = undefined; - node.parameters = createNodeArray(parameters); - node.type = undefined; - node.body = body; - return node; - } - - export function updateConstructor( - node: ConstructorDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - parameters: readonly ParameterDeclaration[], - body: Block | undefined) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.parameters !== parameters - || node.body !== body - ? updateNode(createConstructor(decorators, modifiers, parameters, body), node) - : node; - } - - export function createGetAccessor( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined) { - const node = createSynthesizedNode(SyntaxKind.GetAccessor); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = undefined; - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - return node; - } - - export function updateGetAccessor( - node: GetAccessorDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: PropertyName, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.parameters !== parameters - || node.type !== type - || node.body !== body - ? updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body), node) - : node; - } - - export function createSetAccessor( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | PropertyName, - parameters: readonly ParameterDeclaration[], - body: Block | undefined) { - const node = createSynthesizedNode(SyntaxKind.SetAccessor); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = undefined; - node.parameters = createNodeArray(parameters); - node.body = body; - return node; - } - - export function updateSetAccessor( - node: SetAccessorDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: PropertyName, - parameters: readonly ParameterDeclaration[], - body: Block | undefined) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.parameters !== parameters - || node.body !== body - ? updateNode(createSetAccessor(decorators, modifiers, name, parameters, body), node) - : node; - } - - export function createCallSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) { - return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration; - } - - export function updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createConstructSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) { - return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration; - } - - export function updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createIndexSignature( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode): IndexSignatureDeclaration { - const node = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration; - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.parameters = createNodeArray(parameters); - node.type = type; - return node; - } - - export function updateIndexSignature( - node: IndexSignatureDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode) { - return node.parameters !== parameters - || node.type !== type - || node.decorators !== decorators - || node.modifiers !== modifiers - ? updateNode(createIndexSignature(decorators, modifiers, parameters, type), node) - : node; - } - - /* @internal */ - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, typeArguments?: readonly TypeNode[] | undefined) { - const node = createSynthesizedNode(kind) as SignatureDeclaration; - node.typeParameters = asNodeArray(typeParameters); - node.parameters = asNodeArray(parameters); - node.type = type; - node.typeArguments = asNodeArray(typeArguments); - return node; - } - - function updateSignatureDeclaration(node: T, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { - return node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node) - : node; - } - - // Types - - export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]) { - return createSynthesizedNode(kind); - } - - export function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode) { - return createTypePredicateNodeWithModifier(/*assertsModifier*/ undefined, parameterName, type); - } - - export function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { - const node = createSynthesizedNode(SyntaxKind.TypePredicate) as TypePredicateNode; - node.assertsModifier = assertsModifier; - node.parameterName = asName(parameterName); - node.type = type; - return node; - } - - export function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) { - return updateTypePredicateNodeWithModifier(node, node.assertsModifier, parameterName, type); - } - - export function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) { - return node.assertsModifier !== assertsModifier - || node.parameterName !== parameterName - || node.type !== type - ? updateNode(createTypePredicateNodeWithModifier(assertsModifier, parameterName, type), node) - : node; - } - - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined) { - const node = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; - node.typeName = asName(typeName); - node.typeArguments = typeArguments && parenthesizeTypeParameters(typeArguments); - return node; - } - - export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) { - return node.typeName !== typeName - || node.typeArguments !== typeArguments - ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) - : node; - } - - export function createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) { - return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode; - } - - export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) { - return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode; - } - - export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createTypeQueryNode(exprName: EntityName) { - const node = createSynthesizedNode(SyntaxKind.TypeQuery) as TypeQueryNode; - node.exprName = exprName; - return node; - } - - export function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) { - return node.exprName !== exprName - ? updateNode(createTypeQueryNode(exprName), node) - : node; - } - - export function createTypeLiteralNode(members: readonly TypeElement[] | undefined) { - const node = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode; - node.members = createNodeArray(members); - return node; - } - - export function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray) { - return node.members !== members - ? updateNode(createTypeLiteralNode(members), node) - : node; - } - - export function createArrayTypeNode(elementType: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode; - node.elementType = parenthesizeArrayTypeMember(elementType); - return node; - } - - export function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode { - return node.elementType !== elementType - ? updateNode(createArrayTypeNode(elementType), node) - : node; - } - - export function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]) { - const node = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode; - node.elements = createNodeArray(elements); - return node; - } - - export function updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]) { - return node.elements !== elements - ? updateNode(createTupleTypeNode(elements), node) - : node; - } - - export function createOptionalTypeNode(type: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.OptionalType) as OptionalTypeNode; - node.type = parenthesizeArrayTypeMember(type); - return node; - } - - export function updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode { - return node.type !== type - ? updateNode(createOptionalTypeNode(type), node) - : node; - } - - export function createRestTypeNode(type: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.RestType) as RestTypeNode; - node.type = type; - return node; - } - - export function updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode { - return node.type !== type - ? updateNode(createRestTypeNode(type), node) - : node; - } - - export function createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode { - return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, types); - } - - export function updateUnionTypeNode(node: UnionTypeNode, types: NodeArray) { - return updateUnionOrIntersectionTypeNode(node, types); - } - - export function createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode { - return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, types); - } - - export function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray) { - return updateUnionOrIntersectionTypeNode(node, types); - } - - export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: readonly TypeNode[]) { - const node = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode; - node.types = parenthesizeElementTypeMembers(types); - return node; - } - - function updateUnionOrIntersectionTypeNode(node: T, types: NodeArray): T { - return node.types !== types - ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node) - : node; - } - - export function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.ConditionalType) as ConditionalTypeNode; - node.checkType = parenthesizeConditionalTypeMember(checkType); - node.extendsType = parenthesizeConditionalTypeMember(extendsType); - node.trueType = trueType; - node.falseType = falseType; - return node; - } - - export function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { - return node.checkType !== checkType - || node.extendsType !== extendsType - || node.trueType !== trueType - || node.falseType !== falseType - ? updateNode(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node) - : node; - } - - export function createInferTypeNode(typeParameter: TypeParameterDeclaration) { - const node = createSynthesizedNode(SyntaxKind.InferType); - node.typeParameter = typeParameter; - return node; - } - - export function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration) { - return node.typeParameter !== typeParameter - ? updateNode(createInferTypeNode(typeParameter), node) - : node; - } - - export function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean) { - const node = createSynthesizedNode(SyntaxKind.ImportType); - node.argument = argument; - node.qualifier = qualifier; - node.typeArguments = parenthesizeTypeParameters(typeArguments); - node.isTypeOf = isTypeOf; - return node; - } - - export function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean) { - return node.argument !== argument - || node.qualifier !== qualifier - || node.typeArguments !== typeArguments - || node.isTypeOf !== isTypeOf - ? updateNode(createImportTypeNode(argument, qualifier, typeArguments, isTypeOf), node) - : node; - } - - export function createParenthesizedType(type: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.ParenthesizedType); - node.type = type; - return node; - } - - export function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode) { - return node.type !== type - ? updateNode(createParenthesizedType(type), node) - : node; - } - - export function createNamedTupleMember(dotDotDotToken: Token | undefined, name: Identifier, questionToken: Token | undefined, type: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.NamedTupleMember); - node.dotDotDotToken = dotDotDotToken; - node.name = name; - node.questionToken = questionToken; - node.type = type; - return node; - } - - export function updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: Token | undefined, name: Identifier, questionToken: Token | undefined, type: TypeNode) { - return node.dotDotDotToken !== dotDotDotToken - || node.name !== name - || node.questionToken !== questionToken - || node.type !== type - ? updateNode(createNamedTupleMember(dotDotDotToken, name, questionToken, type), node) - : node; - } - - export function createThisTypeNode() { - return createSynthesizedNode(SyntaxKind.ThisType); - } - - export function createTypeOperatorNode(type: TypeNode): TypeOperatorNode; - export function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; - export function createTypeOperatorNode(operatorOrType: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | TypeNode, type?: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode; - node.operator = typeof operatorOrType === "number" ? operatorOrType : SyntaxKind.KeyOfKeyword; - node.type = parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type! : operatorOrType); - return node; - } - - export function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) { - return node.type !== type ? updateNode(createTypeOperatorNode(node.operator, type), node) : node; - } - - export function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.IndexedAccessType) as IndexedAccessTypeNode; - node.objectType = parenthesizeElementTypeMember(objectType); - node.indexType = indexType; - return node; - } - - export function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) { - return node.objectType !== objectType - || node.indexType !== indexType - ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node) - : node; - } - - export function createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode { - const node = createSynthesizedNode(SyntaxKind.MappedType) as MappedTypeNode; - node.readonlyToken = readonlyToken; - node.typeParameter = typeParameter; - node.questionToken = questionToken; - node.type = type; - return node; - } - - export function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode { - return node.readonlyToken !== readonlyToken - || node.typeParameter !== typeParameter - || node.questionToken !== questionToken - || node.type !== type - ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node) - : node; - } - - export function createLiteralTypeNode(literal: LiteralTypeNode["literal"]) { - const node = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; - node.literal = literal; - return node; - } - - export function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]) { - return node.literal !== literal - ? updateNode(createLiteralTypeNode(literal), node) - : node; - } - - // Binding Patterns - - export function createObjectBindingPattern(elements: readonly BindingElement[]) { - const node = createSynthesizedNode(SyntaxKind.ObjectBindingPattern); - node.elements = createNodeArray(elements); - return node; - } - - export function updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]) { - return node.elements !== elements - ? updateNode(createObjectBindingPattern(elements), node) - : node; - } - - export function createArrayBindingPattern(elements: readonly ArrayBindingElement[]) { - const node = createSynthesizedNode(SyntaxKind.ArrayBindingPattern); - node.elements = createNodeArray(elements); - return node; - } - - export function updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]) { - return node.elements !== elements - ? updateNode(createArrayBindingPattern(elements), node) - : node; - } - - export function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression) { - const node = createSynthesizedNode(SyntaxKind.BindingElement); - node.dotDotDotToken = dotDotDotToken; - node.propertyName = asName(propertyName); - node.name = asName(name); - node.initializer = initializer; - return node; - } - - export function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined) { - return node.propertyName !== propertyName - || node.dotDotDotToken !== dotDotDotToken - || node.name !== name - || node.initializer !== initializer - ? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node) - : node; - } - - // Expression - - export function createArrayLiteral(elements?: readonly Expression[], multiLine?: boolean) { - const node = createSynthesizedNode(SyntaxKind.ArrayLiteralExpression); - node.elements = parenthesizeListElements(createNodeArray(elements)); - if (multiLine) node.multiLine = true; - return node; - } - - export function updateArrayLiteral(node: ArrayLiteralExpression, elements: readonly Expression[]) { - return node.elements !== elements - ? updateNode(createArrayLiteral(elements, node.multiLine), node) - : node; - } - - export function createObjectLiteral(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean) { - const node = createSynthesizedNode(SyntaxKind.ObjectLiteralExpression); - node.properties = createNodeArray(properties); - if (multiLine) node.multiLine = true; - return node; - } - - export function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]) { - return node.properties !== properties - ? updateNode(createObjectLiteral(properties, node.multiLine), node) - : node; - } - - export function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateIdentifier) { - const node = createSynthesizedNode(SyntaxKind.PropertyAccessExpression); - node.expression = parenthesizeForAccess(expression); - node.name = asName(name); - setEmitFlags(node, EmitFlags.NoIndentation); - return node; - } - - export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) { - if (isPropertyAccessChain(node)) { - return updatePropertyAccessChain(node, expression, node.questionDotToken, cast(name, isIdentifier)); - } - // Because we are updating existed propertyAccess we want to inherit its emitFlags - // instead of using the default from createPropertyAccess - return node.expression !== expression - || node.name !== name - ? updateNode(setEmitFlags(createPropertyAccess(expression, name), getEmitFlags(node)), node) - : node; - } - - export function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier) { - const node = createSynthesizedNode(SyntaxKind.PropertyAccessExpression); - node.flags |= NodeFlags.OptionalChain; - node.expression = parenthesizeForAccess(expression); - node.questionDotToken = questionDotToken; - node.name = asName(name); - setEmitFlags(node, EmitFlags.NoIndentation); - return node; - } - - export function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier) { - Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a PropertyAccessExpression using updatePropertyAccessChain. Use updatePropertyAccess instead."); - // Because we are updating an existing PropertyAccessChain we want to inherit its emitFlags - // instead of using the default from createPropertyAccess - return node.expression !== expression - || node.questionDotToken !== questionDotToken - || node.name !== name - ? updateNode(setEmitFlags(createPropertyAccessChain(expression, questionDotToken, name), getEmitFlags(node)), node) - : node; - } - - export function createElementAccess(expression: Expression, index: number | Expression) { - const node = createSynthesizedNode(SyntaxKind.ElementAccessExpression); - node.expression = parenthesizeForAccess(expression); - node.argumentExpression = asExpression(index); - return node; - } - - export function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) { - if (isOptionalChain(node)) { - return updateElementAccessChain(node, expression, node.questionDotToken, argumentExpression); - } - return node.expression !== expression - || node.argumentExpression !== argumentExpression - ? updateNode(createElementAccess(expression, argumentExpression), node) - : node; - } - - export function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression) { - const node = createSynthesizedNode(SyntaxKind.ElementAccessExpression); - node.flags |= NodeFlags.OptionalChain; - node.expression = parenthesizeForAccess(expression); - node.questionDotToken = questionDotToken; - node.argumentExpression = asExpression(index); - return node; - } - - export function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression) { - Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update an ElementAccessExpression using updateElementAccessChain. Use updateElementAccess instead."); - return node.expression !== expression - || node.questionDotToken !== questionDotToken - || node.argumentExpression !== argumentExpression - ? updateNode(createElementAccessChain(expression, questionDotToken, argumentExpression), node) - : node; - } - - export function createCall(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { - const node = createSynthesizedNode(SyntaxKind.CallExpression); - node.expression = parenthesizeForAccess(expression); - node.typeArguments = asNodeArray(typeArguments); - node.arguments = parenthesizeListElements(createNodeArray(argumentsArray)); - return node; - } - - export function updateCall(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) { - if (isOptionalChain(node)) { - return updateCallChain(node, expression, node.questionDotToken, typeArguments, argumentsArray); - } - return node.expression !== expression - || node.typeArguments !== typeArguments - || node.arguments !== argumentsArray - ? updateNode(createCall(expression, typeArguments, argumentsArray), node) - : node; - } - - export function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { - const node = createSynthesizedNode(SyntaxKind.CallExpression); - node.flags |= NodeFlags.OptionalChain; - node.expression = parenthesizeForAccess(expression); - node.questionDotToken = questionDotToken; - node.typeArguments = asNodeArray(typeArguments); - node.arguments = parenthesizeListElements(createNodeArray(argumentsArray)); - return node; - } - - export function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) { - Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a CallExpression using updateCallChain. Use updateCall instead."); - return node.expression !== expression - || node.questionDotToken !== questionDotToken - || node.typeArguments !== typeArguments - || node.arguments !== argumentsArray - ? updateNode(createCallChain(expression, questionDotToken, typeArguments, argumentsArray), node) - : node; - } - - export function createNew(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { - const node = createSynthesizedNode(SyntaxKind.NewExpression); - node.expression = parenthesizeForNew(expression); - node.typeArguments = asNodeArray(typeArguments); - node.arguments = argumentsArray ? parenthesizeListElements(createNodeArray(argumentsArray)) : undefined; - return node; - } - - export function updateNew(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) { - return node.expression !== expression - || node.typeArguments !== typeArguments - || node.arguments !== argumentsArray - ? updateNode(createNew(expression, typeArguments, argumentsArray), node) - : node; - } - - /** @deprecated */ export function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - export function createTaggedTemplate(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; - /** @internal */ - export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: readonly TypeNode[] | TemplateLiteral | undefined, template?: TemplateLiteral): TaggedTemplateExpression; - export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: readonly TypeNode[] | TemplateLiteral | undefined, template?: TemplateLiteral) { - const node = createSynthesizedNode(SyntaxKind.TaggedTemplateExpression); - node.tag = parenthesizeForAccess(tag); - if (template) { - node.typeArguments = asNodeArray(typeArgumentsOrTemplate as readonly TypeNode[]); - node.template = template; - } - else { - node.typeArguments = undefined; - node.template = typeArgumentsOrTemplate as TemplateLiteral; - } - return node; - } - - /** @deprecated */ export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArgumentsOrTemplate: readonly TypeNode[] | TemplateLiteral | undefined, template?: TemplateLiteral) { - return node.tag !== tag - || (template - ? node.typeArguments !== typeArgumentsOrTemplate || node.template !== template - : node.typeArguments !== undefined || node.template !== typeArgumentsOrTemplate) - ? updateNode(createTaggedTemplate(tag, typeArgumentsOrTemplate, template), node) - : node; - } - - export function createTypeAssertion(type: TypeNode, expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.TypeAssertionExpression); - node.type = type; - node.expression = parenthesizePrefixOperand(expression); - return node; - } - - export function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression) { - return node.type !== type - || node.expression !== expression - ? updateNode(createTypeAssertion(type, expression), node) - : node; - } - - export function createParen(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.ParenthesizedExpression); - node.expression = expression; - return node; - } - - export function updateParen(node: ParenthesizedExpression, expression: Expression) { - return node.expression !== expression - ? updateNode(createParen(expression), node) - : node; - } - - export function createFunctionExpression( - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[] | undefined, - type: TypeNode | undefined, - body: Block) { - const node = createSynthesizedNode(SyntaxKind.FunctionExpression); - node.modifiers = asNodeArray(modifiers); - node.asteriskToken = asteriskToken; - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - return node; - } - - export function updateFunctionExpression( - node: FunctionExpression, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block) { - return node.name !== name - || node.modifiers !== modifiers - || node.asteriskToken !== asteriskToken - || node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - || node.body !== body - ? updateNode(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) - : node; - } - - export function createArrowFunction( - modifiers: readonly Modifier[] | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - equalsGreaterThanToken: EqualsGreaterThanToken | undefined, - body: ConciseBody) { - const node = createSynthesizedNode(SyntaxKind.ArrowFunction); - node.modifiers = asNodeArray(modifiers); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; - node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(SyntaxKind.EqualsGreaterThanToken); - node.body = parenthesizeConciseBody(body); - return node; - } - export function updateArrowFunction( - node: ArrowFunction, - modifiers: readonly Modifier[] | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - equalsGreaterThanToken: Token, - body: ConciseBody - ): ArrowFunction { - return node.modifiers !== modifiers - || node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - || node.equalsGreaterThanToken !== equalsGreaterThanToken - || node.body !== body - ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) - : node; - } - - export function createDelete(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.DeleteExpression); - node.expression = parenthesizePrefixOperand(expression); - return node; - } - - export function updateDelete(node: DeleteExpression, expression: Expression) { - return node.expression !== expression - ? updateNode(createDelete(expression), node) - : node; - } - - export function createTypeOf(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.TypeOfExpression); - node.expression = parenthesizePrefixOperand(expression); - return node; - } - - export function updateTypeOf(node: TypeOfExpression, expression: Expression) { - return node.expression !== expression - ? updateNode(createTypeOf(expression), node) - : node; - } - - export function createVoid(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.VoidExpression); - node.expression = parenthesizePrefixOperand(expression); - return node; - } - - export function updateVoid(node: VoidExpression, expression: Expression) { - return node.expression !== expression - ? updateNode(createVoid(expression), node) - : node; - } - - export function createAwait(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.AwaitExpression); - node.expression = parenthesizePrefixOperand(expression); - return node; - } - - export function updateAwait(node: AwaitExpression, expression: Expression) { - return node.expression !== expression - ? updateNode(createAwait(expression), node) - : node; - } - - export function createPrefix(operator: PrefixUnaryOperator, operand: Expression) { - const node = createSynthesizedNode(SyntaxKind.PrefixUnaryExpression); - node.operator = operator; - node.operand = parenthesizePrefixOperand(operand); - return node; - } - - export function updatePrefix(node: PrefixUnaryExpression, operand: Expression) { - return node.operand !== operand - ? updateNode(createPrefix(node.operator, operand), node) - : node; - } - - export function createPostfix(operand: Expression, operator: PostfixUnaryOperator) { - const node = createSynthesizedNode(SyntaxKind.PostfixUnaryExpression); - node.operand = parenthesizePostfixOperand(operand); - node.operator = operator; - return node; - } - - export function updatePostfix(node: PostfixUnaryExpression, operand: Expression) { - return node.operand !== operand - ? updateNode(createPostfix(operand, node.operator), node) - : node; - } - - export function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression) { - const node = createSynthesizedNode(SyntaxKind.BinaryExpression); - const operatorToken = asToken(operator); - const operatorKind = operatorToken.kind; - node.left = parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined); - node.operatorToken = operatorToken; - node.right = parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left); - return node; - } - - export function updateBinary(node: BinaryExpression, left: Expression, right: Expression, operator: BinaryOperator | BinaryOperatorToken = node.operatorToken) { - return node.left !== left - || node.right !== right - || node.operatorToken !== operator - ? updateNode(createBinary(left, operator, right), node) - : node; - } - - /** @deprecated */ export function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; - export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; - export function createConditional(condition: Expression, questionTokenOrWhenTrue: QuestionToken | Expression, whenTrueOrWhenFalse: Expression, colonToken?: ColonToken, whenFalse?: Expression) { - const node = createSynthesizedNode(SyntaxKind.ConditionalExpression); - node.condition = parenthesizeForConditionalHead(condition); - node.questionToken = whenFalse ? questionTokenOrWhenTrue : createToken(SyntaxKind.QuestionToken); - node.whenTrue = parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : questionTokenOrWhenTrue); - node.colonToken = whenFalse ? colonToken! : createToken(SyntaxKind.ColonToken); - node.whenFalse = parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse); - return node; - } - export function updateConditional( - node: ConditionalExpression, - condition: Expression, - questionToken: Token, - whenTrue: Expression, - colonToken: Token, - whenFalse: Expression - ): ConditionalExpression { - return node.condition !== condition - || node.questionToken !== questionToken - || node.whenTrue !== whenTrue - || node.colonToken !== colonToken - || node.whenFalse !== whenFalse - ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) - : node; - } - - export function createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]) { - const node = createSynthesizedNode(SyntaxKind.TemplateExpression); - node.head = head; - node.templateSpans = createNodeArray(templateSpans); - return node; - } - - export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]) { - return node.head !== head - || node.templateSpans !== templateSpans - ? updateNode(createTemplateExpression(head, templateSpans), node) - : node; - } - - let rawTextScanner: Scanner | undefined; - const invalidValueSentinel: object = {}; - - function getCookedText(kind: TemplateLiteralToken["kind"], rawText: string) { - if (!rawTextScanner) { - rawTextScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard); - } - switch (kind) { - case SyntaxKind.NoSubstitutionTemplateLiteral: - rawTextScanner.setText("`" + rawText + "`"); - break; - case SyntaxKind.TemplateHead: - rawTextScanner.setText("`" + rawText + "${"); - break; - case SyntaxKind.TemplateMiddle: - rawTextScanner.setText("}" + rawText + "${"); - break; - case SyntaxKind.TemplateTail: - rawTextScanner.setText("}" + rawText + "`"); - break; - } - - let token = rawTextScanner.scan(); - if (token === SyntaxKind.CloseBracketToken) { - token = rawTextScanner.reScanTemplateToken(/* isTaggedTemplate */ false); - } - - if (rawTextScanner.isUnterminated()) { - rawTextScanner.setText(undefined); - return invalidValueSentinel; - } - - let tokenValue: string | undefined; - switch (token) { - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - case SyntaxKind.TemplateMiddle: - case SyntaxKind.TemplateTail: - tokenValue = rawTextScanner.getTokenValue(); - break; - } - - if (rawTextScanner.scan() !== SyntaxKind.EndOfFileToken) { - rawTextScanner.setText(undefined); - return invalidValueSentinel; - } - - rawTextScanner.setText(undefined); - return tokenValue; - } - - function createTemplateLiteralLikeNode(kind: TemplateLiteralToken["kind"], text: string, rawText: string | undefined) { - const node = createSynthesizedNode(kind); - node.text = text; - if (rawText === undefined || text === rawText) { - node.rawText = rawText; - } - else { - const cooked = getCookedText(kind, rawText); - if (typeof cooked === "object") { - return Debug.fail("Invalid raw text"); - } - - Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'."); - node.rawText = rawText; - } - return node; - } - - export function createTemplateHead(text: string, rawText?: string) { - const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateHead, text, rawText); - node.text = text; - return node; - } - - export function createTemplateMiddle(text: string, rawText?: string) { - const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateMiddle, text, rawText); - node.text = text; - return node; - } - - export function createTemplateTail(text: string, rawText?: string) { - const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateTail, text, rawText); - node.text = text; - return node; - } - - export function createNoSubstitutionTemplateLiteral(text: string, rawText?: string) { - const node = createTemplateLiteralLikeNode(SyntaxKind.NoSubstitutionTemplateLiteral, text, rawText); - return node; - } - - export function createYield(expression?: Expression): YieldExpression; - export function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; - export function createYield(asteriskTokenOrExpression?: AsteriskToken | undefined | Expression, expression?: Expression) { - const asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : undefined; - expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : expression; - const node = createSynthesizedNode(SyntaxKind.YieldExpression); - node.asteriskToken = asteriskToken; - node.expression = expression && parenthesizeExpressionForList(expression); - return node; - } - - export function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression) { - return node.expression !== expression - || node.asteriskToken !== asteriskToken - ? updateNode(createYield(asteriskToken, expression), node) - : node; - } - - export function createSpread(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.SpreadElement); - node.expression = parenthesizeExpressionForList(expression); - return node; - } - - export function updateSpread(node: SpreadElement, expression: Expression) { - return node.expression !== expression - ? updateNode(createSpread(expression), node) - : node; - } - - export function createClassExpression( - modifiers: readonly Modifier[] | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[]) { - const node = createSynthesizedNode(SyntaxKind.ClassExpression); - node.decorators = undefined; - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.heritageClauses = asNodeArray(heritageClauses); - node.members = createNodeArray(members); - return node; - } - - export function updateClassExpression( - node: ClassExpression, - modifiers: readonly Modifier[] | undefined, - name: Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[]) { - return node.modifiers !== modifiers - || node.name !== name - || node.typeParameters !== typeParameters - || node.heritageClauses !== heritageClauses - || node.members !== members - ? updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node) - : node; - } - - export function createOmittedExpression() { - return createSynthesizedNode(SyntaxKind.OmittedExpression); - } - - export function createExpressionWithTypeArguments(typeArguments: readonly TypeNode[] | undefined, expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.ExpressionWithTypeArguments); - node.expression = parenthesizeForAccess(expression); - node.typeArguments = asNodeArray(typeArguments); - return node; - } - - export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: readonly TypeNode[] | undefined, expression: Expression) { - return node.typeArguments !== typeArguments - || node.expression !== expression - ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node) - : node; - } - - export function createAsExpression(expression: Expression, type: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.AsExpression); - node.expression = expression; - node.type = type; - return node; - } - - export function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode) { - return node.expression !== expression - || node.type !== type - ? updateNode(createAsExpression(expression, type), node) - : node; - } - - export function createNonNullExpression(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.NonNullExpression); - node.expression = parenthesizeForAccess(expression); - return node; - } - - export function updateNonNullExpression(node: NonNullExpression, expression: Expression) { - if (isNonNullChain(node)) { - return updateNonNullChain(node, expression); - } - return node.expression !== expression - ? updateNode(createNonNullExpression(expression), node) - : node; - } - - export function createNonNullChain(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.NonNullExpression); - node.flags |= NodeFlags.OptionalChain; - node.expression = parenthesizeForAccess(expression); - return node; - } - - export function updateNonNullChain(node: NonNullChain, expression: Expression) { - Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a NonNullExpression using updateNonNullChain. Use updateNonNullExpression instead."); - return node.expression !== expression - ? updateNode(createNonNullChain(expression), node) - : node; - } - - export function createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier) { - const node = createSynthesizedNode(SyntaxKind.MetaProperty); - node.keywordToken = keywordToken; - node.name = name; - return node; - } - - export function updateMetaProperty(node: MetaProperty, name: Identifier) { - return node.name !== name - ? updateNode(createMetaProperty(node.keywordToken, name), node) - : node; - } - - // Misc - - export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail) { - const node = createSynthesizedNode(SyntaxKind.TemplateSpan); - node.expression = expression; - node.literal = literal; - return node; - } - - export function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) { - return node.expression !== expression - || node.literal !== literal - ? updateNode(createTemplateSpan(expression, literal), node) - : node; - } - - export function createSemicolonClassElement() { - return createSynthesizedNode(SyntaxKind.SemicolonClassElement); - } - - // Element - - export function createBlock(statements: readonly Statement[], multiLine?: boolean): Block { - const block = createSynthesizedNode(SyntaxKind.Block); - block.statements = createNodeArray(statements); - if (multiLine) block.multiLine = multiLine; - return block; - } - - export function updateBlock(node: Block, statements: readonly Statement[]) { - return node.statements !== statements - ? updateNode(createBlock(statements, node.multiLine), node) - : node; - } - - export function createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]) { - const node = createSynthesizedNode(SyntaxKind.VariableStatement); - node.decorators = undefined; - node.modifiers = asNodeArray(modifiers); - node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; - return node; - } - - export function updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList) { - return node.modifiers !== modifiers - || node.declarationList !== declarationList - ? updateNode(createVariableStatement(modifiers, declarationList), node) - : node; - } - - export function createEmptyStatement() { - return createSynthesizedNode(SyntaxKind.EmptyStatement); - } - - export function createExpressionStatement(expression: Expression): ExpressionStatement { - const node = createSynthesizedNode(SyntaxKind.ExpressionStatement); - node.expression = parenthesizeExpressionForExpressionStatement(expression); - return node; - } - - export function updateExpressionStatement(node: ExpressionStatement, expression: Expression) { - return node.expression !== expression - ? updateNode(createExpressionStatement(expression), node) - : node; - } - - /** @deprecated Use `createExpressionStatement` instead. */ - export const createStatement = createExpressionStatement; - /** @deprecated Use `updateExpressionStatement` instead. */ - export const updateStatement = updateExpressionStatement; - - export function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement) { - const node = createSynthesizedNode(SyntaxKind.IfStatement); - node.expression = expression; - node.thenStatement = asEmbeddedStatement(thenStatement); - node.elseStatement = asEmbeddedStatement(elseStatement); - return node; - } - - export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined) { - return node.expression !== expression - || node.thenStatement !== thenStatement - || node.elseStatement !== elseStatement - ? updateNode(createIf(expression, thenStatement, elseStatement), node) - : node; - } - - export function createDo(statement: Statement, expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.DoStatement); - node.statement = asEmbeddedStatement(statement); - node.expression = expression; - return node; - } - - export function updateDo(node: DoStatement, statement: Statement, expression: Expression) { - return node.statement !== statement - || node.expression !== expression - ? updateNode(createDo(statement, expression), node) - : node; - } - - export function createWhile(expression: Expression, statement: Statement) { - const node = createSynthesizedNode(SyntaxKind.WhileStatement); - node.expression = expression; - node.statement = asEmbeddedStatement(statement); - return node; - } - - export function updateWhile(node: WhileStatement, expression: Expression, statement: Statement) { - return node.expression !== expression - || node.statement !== statement - ? updateNode(createWhile(expression, statement), node) - : node; - } - - export function createFor(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { - const node = createSynthesizedNode(SyntaxKind.ForStatement); - node.initializer = initializer; - node.condition = condition; - node.incrementor = incrementor; - node.statement = asEmbeddedStatement(statement); - return node; - } - - export function updateFor(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) { - return node.initializer !== initializer - || node.condition !== condition - || node.incrementor !== incrementor - || node.statement !== statement - ? updateNode(createFor(initializer, condition, incrementor, statement), node) - : node; - } - - export function createForIn(initializer: ForInitializer, expression: Expression, statement: Statement) { - const node = createSynthesizedNode(SyntaxKind.ForInStatement); - node.initializer = initializer; - node.expression = expression; - node.statement = asEmbeddedStatement(statement); - return node; - } - - export function updateForIn(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) { - return node.initializer !== initializer - || node.expression !== expression - || node.statement !== statement - ? updateNode(createForIn(initializer, expression, statement), node) - : node; - } - - export function createForOf(awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { - const node = createSynthesizedNode(SyntaxKind.ForOfStatement); - node.awaitModifier = awaitModifier; - node.initializer = initializer; - node.expression = isCommaSequence(expression) ? createParen(expression) : expression; - node.statement = asEmbeddedStatement(statement); - return node; - } - - export function updateForOf(node: ForOfStatement, awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) { - return node.awaitModifier !== awaitModifier - || node.initializer !== initializer - || node.expression !== expression - || node.statement !== statement - ? updateNode(createForOf(awaitModifier, initializer, expression, statement), node) - : node; - } - - export function createContinue(label?: string | Identifier): ContinueStatement { - const node = createSynthesizedNode(SyntaxKind.ContinueStatement); - node.label = asName(label); - return node; - } - - export function updateContinue(node: ContinueStatement, label: Identifier | undefined) { - return node.label !== label - ? updateNode(createContinue(label), node) - : node; - } - - export function createBreak(label?: string | Identifier): BreakStatement { - const node = createSynthesizedNode(SyntaxKind.BreakStatement); - node.label = asName(label); - return node; - } - - export function updateBreak(node: BreakStatement, label: Identifier | undefined) { - return node.label !== label - ? updateNode(createBreak(label), node) - : node; - } - - export function createReturn(expression?: Expression): ReturnStatement { - const node = createSynthesizedNode(SyntaxKind.ReturnStatement); - node.expression = expression; - return node; - } - - export function updateReturn(node: ReturnStatement, expression: Expression | undefined) { - return node.expression !== expression - ? updateNode(createReturn(expression), node) - : node; - } - - export function createWith(expression: Expression, statement: Statement) { - const node = createSynthesizedNode(SyntaxKind.WithStatement); - node.expression = expression; - node.statement = asEmbeddedStatement(statement); - return node; - } - - export function updateWith(node: WithStatement, expression: Expression, statement: Statement) { - return node.expression !== expression - || node.statement !== statement - ? updateNode(createWith(expression, statement), node) - : node; - } - - export function createSwitch(expression: Expression, caseBlock: CaseBlock): SwitchStatement { - const node = createSynthesizedNode(SyntaxKind.SwitchStatement); - node.expression = parenthesizeExpressionForList(expression); - node.caseBlock = caseBlock; - return node; - } - - export function updateSwitch(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) { - return node.expression !== expression - || node.caseBlock !== caseBlock - ? updateNode(createSwitch(expression, caseBlock), node) - : node; - } - - export function createLabel(label: string | Identifier, statement: Statement) { - const node = createSynthesizedNode(SyntaxKind.LabeledStatement); - node.label = asName(label); - node.statement = asEmbeddedStatement(statement); - return node; - } - - export function updateLabel(node: LabeledStatement, label: Identifier, statement: Statement) { - return node.label !== label - || node.statement !== statement - ? updateNode(createLabel(label, statement), node) - : node; - } - - export function createThrow(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.ThrowStatement); - node.expression = expression; - return node; - } - - export function updateThrow(node: ThrowStatement, expression: Expression) { - return node.expression !== expression - ? updateNode(createThrow(expression), node) - : node; - } - - export function createTry(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { - const node = createSynthesizedNode(SyntaxKind.TryStatement); - node.tryBlock = tryBlock; - node.catchClause = catchClause; - node.finallyBlock = finallyBlock; - return node; - } - - export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) { - return node.tryBlock !== tryBlock - || node.catchClause !== catchClause - || node.finallyBlock !== finallyBlock - ? updateNode(createTry(tryBlock, catchClause, finallyBlock), node) - : node; - } - - export function createDebuggerStatement() { - return createSynthesizedNode(SyntaxKind.DebuggerStatement); - } - - export function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression) { - /* Internally, one should probably use createTypeScriptVariableDeclaration instead and handle definite assignment assertions */ - const node = createSynthesizedNode(SyntaxKind.VariableDeclaration); - node.name = asName(name); - node.type = type; - node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; - return node; - } - - export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) { - /* Internally, one should probably use updateTypeScriptVariableDeclaration instead and handle definite assignment assertions */ - return node.name !== name - || node.type !== type - || node.initializer !== initializer - ? updateNode(createVariableDeclaration(name, type, initializer), node) - : node; - } - - /* @internal */ - export function createTypeScriptVariableDeclaration(name: string | BindingName, exclaimationToken?: Token, type?: TypeNode, initializer?: Expression) { - const node = createSynthesizedNode(SyntaxKind.VariableDeclaration); - node.name = asName(name); - node.type = type; - node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; - node.exclamationToken = exclaimationToken; - return node; - } - - /* @internal */ - export function updateTypeScriptVariableDeclaration(node: VariableDeclaration, name: BindingName, exclaimationToken: Token | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { - return node.name !== name - || node.type !== type - || node.initializer !== initializer - || node.exclamationToken !== exclaimationToken - ? updateNode(createTypeScriptVariableDeclaration(name, exclaimationToken, type, initializer), node) - : node; - } - - export function createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags = NodeFlags.None) { - const node = createSynthesizedNode(SyntaxKind.VariableDeclarationList); - node.flags |= flags & NodeFlags.BlockScoped; - node.declarations = createNodeArray(declarations); - return node; - } - - export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]) { - return node.declarations !== declarations - ? updateNode(createVariableDeclarationList(declarations, node.flags), node) - : node; - } - - export function createFunctionDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined) { - const node = createSynthesizedNode(SyntaxKind.FunctionDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.asteriskToken = asteriskToken; - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); - node.type = type; - node.body = body; - return node; - } - - export function updateFunctionDeclaration( - node: FunctionDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - asteriskToken: AsteriskToken | undefined, - name: Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - parameters: readonly ParameterDeclaration[], - type: TypeNode | undefined, - body: Block | undefined) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.asteriskToken !== asteriskToken - || node.name !== name - || node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - || node.body !== body - ? updateNode(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) - : node; - } - - /* @internal */ - export function updateFunctionLikeBody(declaration: FunctionLikeDeclaration, body: Block): FunctionLikeDeclaration { - switch (declaration.kind) { - case SyntaxKind.FunctionDeclaration: - return createFunctionDeclaration(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body); - case SyntaxKind.MethodDeclaration: - return createMethod(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.questionToken, declaration.typeParameters, declaration.parameters, declaration.type, body); - case SyntaxKind.GetAccessor: - return createGetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, declaration.type, body); - case SyntaxKind.SetAccessor: - return createSetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, body); - case SyntaxKind.Constructor: - return createConstructor(declaration.decorators, declaration.modifiers, declaration.parameters, body); - case SyntaxKind.FunctionExpression: - return createFunctionExpression(declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body); - case SyntaxKind.ArrowFunction: - return createArrowFunction(declaration.modifiers, declaration.typeParameters, declaration.parameters, declaration.type, declaration.equalsGreaterThanToken, body); - } - } - - export function createClassDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[]) { - const node = createSynthesizedNode(SyntaxKind.ClassDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.heritageClauses = asNodeArray(heritageClauses); - node.members = createNodeArray(members); - return node; - } - - export function updateClassDeclaration( - node: ClassDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier | undefined, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly ClassElement[]) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.typeParameters !== typeParameters - || node.heritageClauses !== heritageClauses - || node.members !== members - ? updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node) - : node; - } - - export function createInterfaceDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly TypeElement[]) { - const node = createSynthesizedNode(SyntaxKind.InterfaceDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.heritageClauses = asNodeArray(heritageClauses); - node.members = createNodeArray(members); - return node; - } - - export function updateInterfaceDeclaration( - node: InterfaceDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - heritageClauses: readonly HeritageClause[] | undefined, - members: readonly TypeElement[]) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.typeParameters !== typeParameters - || node.heritageClauses !== heritageClauses - || node.members !== members - ? updateNode(createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node) - : node; - } - - export function createTypeAliasDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - type: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.TypeAliasDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.typeParameters = asNodeArray(typeParameters); - node.type = type; - return node; - } - - export function updateTypeAliasDeclaration( - node: TypeAliasDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier, - typeParameters: readonly TypeParameterDeclaration[] | undefined, - type: TypeNode) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.typeParameters !== typeParameters - || node.type !== type - ? updateNode(createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type), node) - : node; - } - - export function createEnumDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: string | Identifier, - members: readonly EnumMember[]) { - const node = createSynthesizedNode(SyntaxKind.EnumDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.members = createNodeArray(members); - return node; - } - - export function updateEnumDeclaration( - node: EnumDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - name: Identifier, - members: readonly EnumMember[]) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.members !== members - ? updateNode(createEnumDeclaration(decorators, modifiers, name, members), node) - : node; - } - - export function createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags = NodeFlags.None) { - const node = createSynthesizedNode(SyntaxKind.ModuleDeclaration); - node.flags |= flags & (NodeFlags.Namespace | NodeFlags.NestedNamespace | NodeFlags.GlobalAugmentation); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = name; - node.body = body; - return node; - } - - export function updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.body !== body - ? updateNode(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node) - : node; - } - - export function createModuleBlock(statements: readonly Statement[]) { - const node = createSynthesizedNode(SyntaxKind.ModuleBlock); - node.statements = createNodeArray(statements); - return node; - } - - export function updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]) { - return node.statements !== statements - ? updateNode(createModuleBlock(statements), node) - : node; - } - - export function createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock { - const node = createSynthesizedNode(SyntaxKind.CaseBlock); - node.clauses = createNodeArray(clauses); - return node; - } - - export function updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]) { - return node.clauses !== clauses - ? updateNode(createCaseBlock(clauses), node) - : node; - } - - export function createNamespaceExportDeclaration(name: string | Identifier) { - const node = createSynthesizedNode(SyntaxKind.NamespaceExportDeclaration); - node.name = asName(name); - return node; - } - - export function updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier) { - return node.name !== name - ? updateNode(createNamespaceExportDeclaration(name), node) - : node; - } - - export function createImportEqualsDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference) { - const node = createSynthesizedNode(SyntaxKind.ImportEqualsDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.name = asName(name); - node.moduleReference = moduleReference; - return node; - } - - export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.name !== name - || node.moduleReference !== moduleReference - ? updateNode(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node) - : node; - } - - export function createImportDeclaration( - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - importClause: ImportClause | undefined, - moduleSpecifier: Expression): ImportDeclaration { - const node = createSynthesizedNode(SyntaxKind.ImportDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.importClause = importClause; - node.moduleSpecifier = moduleSpecifier; - return node; - } - - export function updateImportDeclaration( - node: ImportDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - importClause: ImportClause | undefined, - moduleSpecifier: Expression) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.importClause !== importClause - || node.moduleSpecifier !== moduleSpecifier - ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node) - : node; - } - - export function createImportClause(name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly = false): ImportClause { - const node = createSynthesizedNode(SyntaxKind.ImportClause); - node.name = name; - node.namedBindings = namedBindings; - node.isTypeOnly = isTypeOnly; - return node; - } - - export function updateImportClause(node: ImportClause, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly: boolean) { - return node.name !== name - || node.namedBindings !== namedBindings - || node.isTypeOnly !== isTypeOnly - ? updateNode(createImportClause(name, namedBindings, isTypeOnly), node) - : node; - } - - export function createNamespaceImport(name: Identifier): NamespaceImport { - const node = createSynthesizedNode(SyntaxKind.NamespaceImport); - node.name = name; - return node; - } - - export function createNamespaceExport(name: Identifier): NamespaceExport { - const node = createSynthesizedNode(SyntaxKind.NamespaceExport); - node.name = name; - return node; - } - - export function updateNamespaceImport(node: NamespaceImport, name: Identifier) { - return node.name !== name - ? updateNode(createNamespaceImport(name), node) - : node; - } - - export function updateNamespaceExport(node: NamespaceExport, name: Identifier) { - return node.name !== name - ? updateNode(createNamespaceExport(name), node) - : node; - } - - export function createNamedImports(elements: readonly ImportSpecifier[]): NamedImports { - const node = createSynthesizedNode(SyntaxKind.NamedImports); - node.elements = createNodeArray(elements); - return node; - } - - export function updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]) { - return node.elements !== elements - ? updateNode(createNamedImports(elements), node) - : node; - } - - export function createImportSpecifier(propertyName: Identifier | undefined, name: Identifier) { - const node = createSynthesizedNode(SyntaxKind.ImportSpecifier); - node.propertyName = propertyName; - node.name = name; - return node; - } - - export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier) { - return node.propertyName !== propertyName - || node.name !== name - ? updateNode(createImportSpecifier(propertyName, name), node) - : node; - } - - export function createExportAssignment(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.ExportAssignment); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.isExportEquals = isExportEquals; - node.expression = isExportEquals ? parenthesizeBinaryOperand(SyntaxKind.EqualsToken, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : parenthesizeDefaultExpression(expression); - return node; - } - - export function updateExportAssignment(node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.expression !== expression - ? updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node) - : node; - } - - export function createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression, isTypeOnly = false) { - const node = createSynthesizedNode(SyntaxKind.ExportDeclaration); - node.decorators = asNodeArray(decorators); - node.modifiers = asNodeArray(modifiers); - node.isTypeOnly = isTypeOnly; - node.exportClause = exportClause; - node.moduleSpecifier = moduleSpecifier; - return node; - } - - export function updateExportDeclaration( - node: ExportDeclaration, - decorators: readonly Decorator[] | undefined, - modifiers: readonly Modifier[] | undefined, - exportClause: NamedExportBindings | undefined, - moduleSpecifier: Expression | undefined, - isTypeOnly: boolean) { - return node.decorators !== decorators - || node.modifiers !== modifiers - || node.isTypeOnly !== isTypeOnly - || node.exportClause !== exportClause - || node.moduleSpecifier !== moduleSpecifier - ? updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, isTypeOnly), node) - : node; - } - - /* @internal */ - export function createEmptyExports() { - return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined); - } - - export function createNamedExports(elements: readonly ExportSpecifier[]) { - const node = createSynthesizedNode(SyntaxKind.NamedExports); - node.elements = createNodeArray(elements); - return node; - } - - export function updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]) { - return node.elements !== elements - ? updateNode(createNamedExports(elements), node) - : node; - } - - export function createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier) { - const node = createSynthesizedNode(SyntaxKind.ExportSpecifier); - node.propertyName = asName(propertyName); - node.name = asName(name); - return node; - } - - export function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier) { - return node.propertyName !== propertyName - || node.name !== name - ? updateNode(createExportSpecifier(propertyName, name), node) - : node; - } - - // Module references - - export function createExternalModuleReference(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.ExternalModuleReference); - node.expression = expression; - return node; - } - - export function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression) { - return node.expression !== expression - ? updateNode(createExternalModuleReference(expression), node) - : node; - } - - // JSDoc - - export function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression { - const node = createSynthesizedNode(SyntaxKind.JSDocTypeExpression) as JSDocTypeExpression; - node.type = type; - return node; - } - - export function createJSDocTypeTag(typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag { - const tag = createJSDocTag(SyntaxKind.JSDocTypeTag, "type", comment); - tag.typeExpression = typeExpression; - return tag; - } - - export function createJSDocReturnTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag { - const tag = createJSDocTag(SyntaxKind.JSDocReturnTag, "returns", comment); - tag.typeExpression = typeExpression; - return tag; - } - - export function createJSDocThisTag(typeExpression?: JSDocTypeExpression): JSDocThisTag { - const tag = createJSDocTag(SyntaxKind.JSDocThisTag, "this"); - tag.typeExpression = typeExpression; - return tag; - } - - /** - * @deprecated Use `createJSDocParameterTag` to create jsDoc param tag. - */ - export function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag { - const tag = createJSDocTag(SyntaxKind.JSDocParameterTag, "param", comment); - tag.typeExpression = typeExpression; - tag.name = name; - tag.isBracketed = isBracketed; - return tag; - } - - export function createJSDocClassTag(comment?: string): JSDocClassTag { - return createJSDocTag(SyntaxKind.JSDocClassTag, "class", comment); - } - - - export function createJSDocComment(comment?: string | undefined, tags?: NodeArray | undefined) { - const node = createSynthesizedNode(SyntaxKind.JSDocComment) as JSDoc; - node.comment = comment; - node.tags = tags; - return node; - } - - export function createJSDocTag(kind: T["kind"], tagName: string, comment?: string): T { - const node = createSynthesizedNode(kind) as T; - node.tagName = createIdentifier(tagName); - node.comment = comment; - return node; - } - - export function createJSDocAugmentsTag(classExpression: JSDocAugmentsTag["class"], comment?: string) { - const tag = createJSDocTag(SyntaxKind.JSDocAugmentsTag, "augments", comment); - tag.class = classExpression; - return tag; - } - - export function createJSDocEnumTag(typeExpression?: JSDocTypeExpression, comment?: string) { - const tag = createJSDocTag(SyntaxKind.JSDocEnumTag, "enum", comment); - tag.typeExpression = typeExpression; - return tag; - } - - export function createJSDocTemplateTag(constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string) { - const tag = createJSDocTag(SyntaxKind.JSDocTemplateTag, "template", comment); - tag.constraint = constraint; - tag.typeParameters = asNodeArray(typeParameters); - return tag; - } - - export function createJSDocTypedefTag(fullName?: JSDocNamespaceDeclaration | Identifier, name?: Identifier, comment?: string, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral) { - const tag = createJSDocTag(SyntaxKind.JSDocTypedefTag, "typedef", comment); - tag.fullName = fullName; - tag.name = name; - tag.typeExpression = typeExpression; - return tag; - } - - export function createJSDocCallbackTag(fullName: JSDocNamespaceDeclaration | Identifier | undefined, name: Identifier | undefined, comment: string | undefined, typeExpression: JSDocSignature) { - const tag = createJSDocTag(SyntaxKind.JSDocCallbackTag, "callback", comment); - tag.fullName = fullName; - tag.name = name; - tag.typeExpression = typeExpression; - return tag; - } - - export function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag) { - const tag = createSynthesizedNode(SyntaxKind.JSDocSignature) as JSDocSignature; - tag.typeParameters = typeParameters; - tag.parameters = parameters; - tag.type = type; - return tag; - } - - function createJSDocPropertyLikeTag(kind: T["kind"], tagName: "arg" | "argument" | "param", typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string) { - const tag = createJSDocTag(kind, tagName, comment); - tag.typeExpression = typeExpression; - tag.name = name; - tag.isNameFirst = isNameFirst; - tag.isBracketed = isBracketed; - return tag; - } - - export function createJSDocPropertyTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string) { - return createJSDocPropertyLikeTag(SyntaxKind.JSDocPropertyTag, "param", typeExpression, name, isNameFirst, isBracketed, comment); - } - - export function createJSDocParameterTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string) { - return createJSDocPropertyLikeTag(SyntaxKind.JSDocParameterTag, "param", typeExpression, name, isNameFirst, isBracketed, comment); - } - - export function createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean) { - const tag = createSynthesizedNode(SyntaxKind.JSDocTypeLiteral) as JSDocTypeLiteral; - tag.jsDocPropertyTags = jsDocPropertyTags; - tag.isArrayType = isArrayType; - return tag; - } - - export function createJSDocImplementsTag(classExpression: JSDocImplementsTag["class"], comment?: string) { - const tag = createJSDocTag(SyntaxKind.JSDocImplementsTag, "implements", comment); - tag.class = classExpression; - return tag; - } - - export function createJSDocAuthorTag(comment?: string) { - return createJSDocTag(SyntaxKind.JSDocAuthorTag, "author", comment); - } - - export function createJSDocPublicTag() { - return createJSDocTag(SyntaxKind.JSDocPublicTag, "public"); - } - - export function createJSDocPrivateTag() { - return createJSDocTag(SyntaxKind.JSDocPrivateTag, "private"); - } - - export function createJSDocProtectedTag() { - return createJSDocTag(SyntaxKind.JSDocProtectedTag, "protected"); - } - - export function createJSDocReadonlyTag() { - return createJSDocTag(SyntaxKind.JSDocReadonlyTag, "readonly"); - } - - export function appendJSDocToContainer(node: JSDocContainer, jsdoc: JSDoc) { - node.jsDoc = append(node.jsDoc, jsdoc); - return node; - } - - - /* @internal */ - export function createJSDocVariadicType(type: TypeNode): JSDocVariadicType { - const node = createSynthesizedNode(SyntaxKind.JSDocVariadicType) as JSDocVariadicType; - node.type = type; - return node; - } - - /* @internal */ - export function updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType { - return node.type !== type - ? updateNode(createJSDocVariadicType(type), node) - : node; - } - - // JSX - - export function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { - const node = createSynthesizedNode(SyntaxKind.JsxElement); - node.openingElement = openingElement; - node.children = createNodeArray(children); - node.closingElement = closingElement; - return node; - } - - export function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) { - return node.openingElement !== openingElement - || node.children !== children - || node.closingElement !== closingElement - ? updateNode(createJsxElement(openingElement, children, closingElement), node) - : node; - } - - export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { - const node = createSynthesizedNode(SyntaxKind.JsxSelfClosingElement); - node.tagName = tagName; - node.typeArguments = asNodeArray(typeArguments); - node.attributes = attributes; - return node; - } - - export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { - return node.tagName !== tagName - || node.typeArguments !== typeArguments - || node.attributes !== attributes - ? updateNode(createJsxSelfClosingElement(tagName, typeArguments, attributes), node) - : node; - } - - export function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { - const node = createSynthesizedNode(SyntaxKind.JsxOpeningElement); - node.tagName = tagName; - node.typeArguments = asNodeArray(typeArguments); - node.attributes = attributes; - return node; - } - - export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) { - return node.tagName !== tagName - || node.typeArguments !== typeArguments - || node.attributes !== attributes - ? updateNode(createJsxOpeningElement(tagName, typeArguments, attributes), node) - : node; - } - - export function createJsxClosingElement(tagName: JsxTagNameExpression) { - const node = createSynthesizedNode(SyntaxKind.JsxClosingElement); - node.tagName = tagName; - return node; - } - - export function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression) { - return node.tagName !== tagName - ? updateNode(createJsxClosingElement(tagName), node) - : node; - } - - export function createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { - const node = createSynthesizedNode(SyntaxKind.JsxFragment); - node.openingFragment = openingFragment; - node.children = createNodeArray(children); - node.closingFragment = closingFragment; - return node; - } - - export function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean) { - const node = createSynthesizedNode(SyntaxKind.JsxText); - node.text = text; - node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces; - return node; - } - - export function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean) { - return node.text !== text - || node.containsOnlyTriviaWhiteSpaces !== containsOnlyTriviaWhiteSpaces - ? updateNode(createJsxText(text, containsOnlyTriviaWhiteSpaces), node) - : node; - } - - export function createJsxOpeningFragment() { - return createSynthesizedNode(SyntaxKind.JsxOpeningFragment); - } - - export function createJsxJsxClosingFragment() { - return createSynthesizedNode(SyntaxKind.JsxClosingFragment); - } - - export function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) { - return node.openingFragment !== openingFragment - || node.children !== children - || node.closingFragment !== closingFragment - ? updateNode(createJsxFragment(openingFragment, children, closingFragment), node) - : node; - } - - export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression) { - const node = createSynthesizedNode(SyntaxKind.JsxAttribute); - node.name = name; - node.initializer = initializer; - return node; - } - - export function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression) { - return node.name !== name - || node.initializer !== initializer - ? updateNode(createJsxAttribute(name, initializer), node) - : node; - } - - export function createJsxAttributes(properties: readonly JsxAttributeLike[]) { - const node = createSynthesizedNode(SyntaxKind.JsxAttributes); - node.properties = createNodeArray(properties); - return node; - } - - export function updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]) { - return node.properties !== properties - ? updateNode(createJsxAttributes(properties), node) - : node; - } - - export function createJsxSpreadAttribute(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.JsxSpreadAttribute); - node.expression = expression; - return node; - } - - export function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression) { - return node.expression !== expression - ? updateNode(createJsxSpreadAttribute(expression), node) - : node; - } - - export function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) { - const node = createSynthesizedNode(SyntaxKind.JsxExpression); - node.dotDotDotToken = dotDotDotToken; - node.expression = expression; - return node; - } - - export function updateJsxExpression(node: JsxExpression, expression: Expression | undefined) { - return node.expression !== expression - ? updateNode(createJsxExpression(node.dotDotDotToken, expression), node) - : node; - } - - // Clauses - - export function createCaseClause(expression: Expression, statements: readonly Statement[]) { - const node = createSynthesizedNode(SyntaxKind.CaseClause); - node.expression = parenthesizeExpressionForList(expression); - node.statements = createNodeArray(statements); - return node; - } - - export function updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]) { - return node.expression !== expression - || node.statements !== statements - ? updateNode(createCaseClause(expression, statements), node) - : node; - } - - export function createDefaultClause(statements: readonly Statement[]) { - const node = createSynthesizedNode(SyntaxKind.DefaultClause); - node.statements = createNodeArray(statements); - return node; - } - - export function updateDefaultClause(node: DefaultClause, statements: readonly Statement[]) { - return node.statements !== statements - ? updateNode(createDefaultClause(statements), node) - : node; - } - - export function createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]) { - const node = createSynthesizedNode(SyntaxKind.HeritageClause); - node.token = token; - node.types = createNodeArray(types); - return node; - } - - export function updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]) { - return node.types !== types - ? updateNode(createHeritageClause(node.token, types), node) - : node; - } - - export function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block) { - const node = createSynthesizedNode(SyntaxKind.CatchClause); - node.variableDeclaration = isString(variableDeclaration) ? createVariableDeclaration(variableDeclaration) : variableDeclaration; - node.block = block; - return node; - } - - export function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block) { - return node.variableDeclaration !== variableDeclaration - || node.block !== block - ? updateNode(createCatchClause(variableDeclaration, block), node) - : node; - } - - // Property assignments - - export function createPropertyAssignment(name: string | PropertyName, initializer: Expression) { - const node = createSynthesizedNode(SyntaxKind.PropertyAssignment); - node.name = asName(name); - node.questionToken = undefined; - node.initializer = parenthesizeExpressionForList(initializer); - return node; - } - - export function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression) { - return node.name !== name - || node.initializer !== initializer - ? updateNode(createPropertyAssignment(name, initializer), node) - : node; - } - - export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression) { - const node = createSynthesizedNode(SyntaxKind.ShorthandPropertyAssignment); - node.name = asName(name); - node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? parenthesizeExpressionForList(objectAssignmentInitializer) : undefined; - return node; - } - - export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) { - return node.name !== name - || node.objectAssignmentInitializer !== objectAssignmentInitializer - ? updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node) - : node; - } - - export function createSpreadAssignment(expression: Expression) { - const node = createSynthesizedNode(SyntaxKind.SpreadAssignment); - node.expression = parenthesizeExpressionForList(expression); - return node; - } - - export function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) { - return node.expression !== expression - ? updateNode(createSpreadAssignment(expression), node) - : node; - } - - // Enum - - export function createEnumMember(name: string | PropertyName, initializer?: Expression) { - const node = createSynthesizedNode(SyntaxKind.EnumMember); - node.name = asName(name); - node.initializer = initializer && parenthesizeExpressionForList(initializer); - return node; - } - - export function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined) { - return node.name !== name - || node.initializer !== initializer - ? updateNode(createEnumMember(name, initializer), node) - : node; - } - - // Top-level nodes - - export function updateSourceFileNode(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean, libReferences?: SourceFile["libReferenceDirectives"]) { - if ( - node.statements !== statements || - (isDeclarationFile !== undefined && node.isDeclarationFile !== isDeclarationFile) || - (referencedFiles !== undefined && node.referencedFiles !== referencedFiles) || - (typeReferences !== undefined && node.typeReferenceDirectives !== typeReferences) || - (libReferences !== undefined && node.libReferenceDirectives !== libReferences) || - (hasNoDefaultLib !== undefined && node.hasNoDefaultLib !== hasNoDefaultLib) - ) { - const updated = createSynthesizedNode(SyntaxKind.SourceFile); - updated.flags |= node.flags; - updated.statements = createNodeArray(statements); - updated.endOfFileToken = node.endOfFileToken; - updated.fileName = node.fileName; - updated.path = node.path; - updated.text = node.text; - updated.isDeclarationFile = isDeclarationFile === undefined ? node.isDeclarationFile : isDeclarationFile; - updated.referencedFiles = referencedFiles === undefined ? node.referencedFiles : referencedFiles; - updated.typeReferenceDirectives = typeReferences === undefined ? node.typeReferenceDirectives : typeReferences; - updated.hasNoDefaultLib = hasNoDefaultLib === undefined ? node.hasNoDefaultLib : hasNoDefaultLib; - updated.libReferenceDirectives = libReferences === undefined ? node.libReferenceDirectives : libReferences; - if (node.amdDependencies !== undefined) updated.amdDependencies = node.amdDependencies; - if (node.moduleName !== undefined) updated.moduleName = node.moduleName; - if (node.languageVariant !== undefined) updated.languageVariant = node.languageVariant; - if (node.renamedDependencies !== undefined) updated.renamedDependencies = node.renamedDependencies; - if (node.languageVersion !== undefined) updated.languageVersion = node.languageVersion; - if (node.scriptKind !== undefined) updated.scriptKind = node.scriptKind; - if (node.externalModuleIndicator !== undefined) updated.externalModuleIndicator = node.externalModuleIndicator; - if (node.commonJsModuleIndicator !== undefined) updated.commonJsModuleIndicator = node.commonJsModuleIndicator; - if (node.identifiers !== undefined) updated.identifiers = node.identifiers; - if (node.nodeCount !== undefined) updated.nodeCount = node.nodeCount; - if (node.identifierCount !== undefined) updated.identifierCount = node.identifierCount; - if (node.symbolCount !== undefined) updated.symbolCount = node.symbolCount; - if (node.parseDiagnostics !== undefined) updated.parseDiagnostics = node.parseDiagnostics; - if (node.bindDiagnostics !== undefined) updated.bindDiagnostics = node.bindDiagnostics; - if (node.bindSuggestionDiagnostics !== undefined) updated.bindSuggestionDiagnostics = node.bindSuggestionDiagnostics; - if (node.lineMap !== undefined) updated.lineMap = node.lineMap; - if (node.classifiableNames !== undefined) updated.classifiableNames = node.classifiableNames; - if (node.resolvedModules !== undefined) updated.resolvedModules = node.resolvedModules; - if (node.resolvedTypeReferenceDirectiveNames !== undefined) updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames; - if (node.imports !== undefined) updated.imports = node.imports; - if (node.moduleAugmentations !== undefined) updated.moduleAugmentations = node.moduleAugmentations; - if (node.pragmas !== undefined) updated.pragmas = node.pragmas; - if (node.localJsxFactory !== undefined) updated.localJsxFactory = node.localJsxFactory; - if (node.localJsxNamespace !== undefined) updated.localJsxNamespace = node.localJsxNamespace; - return updateNode(updated, node); - } - - return node; - } - - /** - * Creates a shallow, memberwise clone of a node for mutation. - */ - export function getMutableClone(node: T): T { - const clone = getSynthesizedClone(node); - clone.pos = node.pos; - clone.end = node.end; - clone.parent = node.parent; - return clone; - } - - // Transformation nodes - - /** - * Creates a synthetic statement to act as a placeholder for a not-emitted statement in - * order to preserve comments. - * - * @param original The original statement. - */ - export function createNotEmittedStatement(original: Node) { - const node = createSynthesizedNode(SyntaxKind.NotEmittedStatement); - node.original = original; - setTextRange(node, original); - return node; - } - - /** - * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in - * order to properly emit exports. - */ - /* @internal */ - export function createEndOfDeclarationMarker(original: Node) { - const node = createSynthesizedNode(SyntaxKind.EndOfDeclarationMarker); - node.emitNode = {} as EmitNode; - node.original = original; - return node; - } - - /** - * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in - * order to properly emit exports. - */ - /* @internal */ - export function createMergeDeclarationMarker(original: Node) { - const node = createSynthesizedNode(SyntaxKind.MergeDeclarationMarker); - node.emitNode = {} as EmitNode; - node.original = original; - return node; - } - - /** - * Creates a synthetic expression to act as a placeholder for a not-emitted expression in - * order to preserve comments or sourcemap positions. - * - * @param expression The inner expression to emit. - * @param original The original outer expression. - * @param location The location for the expression. Defaults to the positions from "original" if provided. - */ - export function createPartiallyEmittedExpression(expression: Expression, original?: Node) { - const node = createSynthesizedNode(SyntaxKind.PartiallyEmittedExpression); - node.expression = expression; - node.original = original; - setTextRange(node, original); - return node; - } - - export function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createPartiallyEmittedExpression(expression, node.original), node); - } - return node; - } - - function flattenCommaElements(node: Expression): Expression | readonly Expression[] { - if (nodeIsSynthesized(node) && !isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) { - if (node.kind === SyntaxKind.CommaListExpression) { - return (node).elements; - } - if (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.CommaToken) { - return [node.left, node.right]; - } - } - return node; - } - - export function createCommaList(elements: readonly Expression[]) { - const node = createSynthesizedNode(SyntaxKind.CommaListExpression); - node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements)); - return node; - } - - export function updateCommaList(node: CommaListExpression, elements: readonly Expression[]) { - return node.elements !== elements - ? updateNode(createCommaList(elements), node) - : node; - } - - /* @internal */ - export function createSyntheticReferenceExpression(expression: Expression, thisArg: Expression) { - const node = createSynthesizedNode(SyntaxKind.SyntheticReferenceExpression); - node.expression = expression; - node.thisArg = thisArg; - return node; - } - - /* @internal */ - export function updateSyntheticReferenceExpression(node: SyntheticReferenceExpression, expression: Expression, thisArg: Expression) { - return node.expression !== expression - || node.thisArg !== thisArg - ? updateNode(createSyntheticReferenceExpression(expression, thisArg), node) - : node; - } - - export function createBundle(sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) { - const node = createNode(SyntaxKind.Bundle); - node.prepends = prepends; - node.sourceFiles = sourceFiles; - return node; - } - - let allUnscopedEmitHelpers: ReadonlyMap | undefined; - function getAllUnscopedEmitHelpers() { - return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = arrayToMap([ - valuesHelper, - readHelper, - spreadHelper, - spreadArraysHelper, - restHelper, - decorateHelper, - metadataHelper, - paramHelper, - awaiterHelper, - assignHelper, - awaitHelper, - asyncGeneratorHelper, - asyncDelegator, - asyncValues, - extendsHelper, - templateObjectHelper, - generatorHelper, - importStarHelper, - importDefaultHelper, - classPrivateFieldGetHelper, - classPrivateFieldSetHelper, - createBindingHelper, - setModuleDefaultHelper - ], helper => helper.name)); - } - - function createUnparsedSource() { - const node = createNode(SyntaxKind.UnparsedSource); - node.prologues = emptyArray; - node.referencedFiles = emptyArray; - node.libReferenceDirectives = emptyArray; - node.getLineAndCharacterOfPosition = pos => getLineAndCharacterOfPosition(node, pos); - return node; - } - - export function createUnparsedSourceFile(text: string): UnparsedSource; - export function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; - export function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; - export function createUnparsedSourceFile(textOrInputFiles: string | InputFiles, mapPathOrType?: string, mapTextOrStripInternal?: string | boolean): UnparsedSource { - const node = createUnparsedSource(); - let stripInternal: boolean | undefined; - let bundleFileInfo: BundleFileInfo | undefined; - if (!isString(textOrInputFiles)) { - Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts"); - node.fileName = (mapPathOrType === "js" ? textOrInputFiles.javascriptPath : textOrInputFiles.declarationPath) || ""; - node.sourceMapPath = mapPathOrType === "js" ? textOrInputFiles.javascriptMapPath : textOrInputFiles.declarationMapPath; - Object.defineProperties(node, { - text: { get() { return mapPathOrType === "js" ? textOrInputFiles.javascriptText : textOrInputFiles.declarationText; } }, - sourceMapText: { get() { return mapPathOrType === "js" ? textOrInputFiles.javascriptMapText : textOrInputFiles.declarationMapText; } }, - }); - - - if (textOrInputFiles.buildInfo && textOrInputFiles.buildInfo.bundle) { - node.oldFileOfCurrentEmit = textOrInputFiles.oldFileOfCurrentEmit; - Debug.assert(mapTextOrStripInternal === undefined || typeof mapTextOrStripInternal === "boolean"); - stripInternal = mapTextOrStripInternal; - bundleFileInfo = mapPathOrType === "js" ? textOrInputFiles.buildInfo.bundle.js : textOrInputFiles.buildInfo.bundle.dts; - if (node.oldFileOfCurrentEmit) { - parseOldFileOfCurrentEmit(node, Debug.checkDefined(bundleFileInfo)); - return node; - } - } - } - else { - node.fileName = ""; - node.text = textOrInputFiles; - node.sourceMapPath = mapPathOrType; - node.sourceMapText = mapTextOrStripInternal as string; - } - Debug.assert(!node.oldFileOfCurrentEmit); - parseUnparsedSourceFile(node, bundleFileInfo, stripInternal); - return node; - } - - function parseUnparsedSourceFile(node: UnparsedSource, bundleFileInfo: BundleFileInfo | undefined, stripInternal: boolean | undefined) { - let prologues: UnparsedPrologue[] | undefined; - let helpers: UnscopedEmitHelper[] | undefined; - let referencedFiles: FileReference[] | undefined; - let typeReferenceDirectives: string[] | undefined; - let libReferenceDirectives: FileReference[] | undefined; - let texts: UnparsedSourceText[] | undefined; - - for (const section of bundleFileInfo ? bundleFileInfo.sections : emptyArray) { - switch (section.kind) { - case BundleFileSectionKind.Prologue: - (prologues || (prologues = [])).push(createUnparsedNode(section, node) as UnparsedPrologue); - break; - case BundleFileSectionKind.EmitHelpers: - (helpers || (helpers = [])).push(getAllUnscopedEmitHelpers().get(section.data)!); - break; - case BundleFileSectionKind.NoDefaultLib: - node.hasNoDefaultLib = true; - break; - case BundleFileSectionKind.Reference: - (referencedFiles || (referencedFiles = [])).push({ pos: -1, end: -1, fileName: section.data }); - break; - case BundleFileSectionKind.Type: - (typeReferenceDirectives || (typeReferenceDirectives = [])).push(section.data); - break; - case BundleFileSectionKind.Lib: - (libReferenceDirectives || (libReferenceDirectives = [])).push({ pos: -1, end: -1, fileName: section.data }); - break; - case BundleFileSectionKind.Prepend: - const prependNode = createUnparsedNode(section, node) as UnparsedPrepend; - let prependTexts: UnparsedTextLike[] | undefined; - for (const text of section.texts) { - if (!stripInternal || text.kind !== BundleFileSectionKind.Internal) { - (prependTexts || (prependTexts = [])).push(createUnparsedNode(text, node) as UnparsedTextLike); - } - } - prependNode.texts = prependTexts || emptyArray; - (texts || (texts = [])).push(prependNode); - break; - case BundleFileSectionKind.Internal: - if (stripInternal) { - if (!texts) texts = []; - break; - } - // falls through - - case BundleFileSectionKind.Text: - (texts || (texts = [])).push(createUnparsedNode(section, node) as UnparsedTextLike); - break; - default: - Debug.assertNever(section); - } - } - - node.prologues = prologues || emptyArray; - node.helpers = helpers; - node.referencedFiles = referencedFiles || emptyArray; - node.typeReferenceDirectives = typeReferenceDirectives; - node.libReferenceDirectives = libReferenceDirectives || emptyArray; - node.texts = texts || [createUnparsedNode({ kind: BundleFileSectionKind.Text, pos: 0, end: node.text.length }, node)]; - } - - function parseOldFileOfCurrentEmit(node: UnparsedSource, bundleFileInfo: BundleFileInfo) { - Debug.assert(!!node.oldFileOfCurrentEmit); - let texts: UnparsedTextLike[] | undefined; - let syntheticReferences: UnparsedSyntheticReference[] | undefined; - for (const section of bundleFileInfo.sections) { - switch (section.kind) { - case BundleFileSectionKind.Internal: - case BundleFileSectionKind.Text: - (texts || (texts = [])).push(createUnparsedNode(section, node) as UnparsedTextLike); - break; - - case BundleFileSectionKind.NoDefaultLib: - case BundleFileSectionKind.Reference: - case BundleFileSectionKind.Type: - case BundleFileSectionKind.Lib: - (syntheticReferences || (syntheticReferences = [])).push(createUnparsedSyntheticReference(section, node)); - break; - - // Ignore - case BundleFileSectionKind.Prologue: - case BundleFileSectionKind.EmitHelpers: - case BundleFileSectionKind.Prepend: - break; - - default: - Debug.assertNever(section); - } - } - node.texts = texts || emptyArray; - node.helpers = map(bundleFileInfo.sources && bundleFileInfo.sources.helpers, name => getAllUnscopedEmitHelpers().get(name)!); - node.syntheticReferences = syntheticReferences; - return node; - } - - function mapBundleFileSectionKindToSyntaxKind(kind: BundleFileSectionKind): SyntaxKind { - switch (kind) { - case BundleFileSectionKind.Prologue: return SyntaxKind.UnparsedPrologue; - case BundleFileSectionKind.Prepend: return SyntaxKind.UnparsedPrepend; - case BundleFileSectionKind.Internal: return SyntaxKind.UnparsedInternalText; - case BundleFileSectionKind.Text: return SyntaxKind.UnparsedText; - - case BundleFileSectionKind.EmitHelpers: - case BundleFileSectionKind.NoDefaultLib: - case BundleFileSectionKind.Reference: - case BundleFileSectionKind.Type: - case BundleFileSectionKind.Lib: - return Debug.fail(`BundleFileSectionKind: ${kind} not yet mapped to SyntaxKind`); - - default: - return Debug.assertNever(kind); - } - } - - function createUnparsedNode(section: BundleFileSection, parent: UnparsedSource): UnparsedNode { - const node = createNode(mapBundleFileSectionKindToSyntaxKind(section.kind), section.pos, section.end) as UnparsedNode; - node.parent = parent; - node.data = section.data; - return node; - } - - function createUnparsedSyntheticReference(section: BundleFileHasNoDefaultLib | BundleFileReference, parent: UnparsedSource) { - const node = createNode(SyntaxKind.UnparsedSyntheticReference, section.pos, section.end) as UnparsedSyntheticReference; - node.parent = parent; - node.data = section.data; - node.section = section; - return node; - } - - export function createInputFiles( - javascriptText: string, - declarationText: string - ): InputFiles; - export function createInputFiles( - readFileText: (path: string) => string | undefined, - javascriptPath: string, - javascriptMapPath: string | undefined, - declarationPath: string, - declarationMapPath: string | undefined, - buildInfoPath: string | undefined - ): InputFiles; - export function createInputFiles( - javascriptText: string, - declarationText: string, - javascriptMapPath: string | undefined, - javascriptMapText: string | undefined, - declarationMapPath: string | undefined, - declarationMapText: string | undefined - ): InputFiles; - /*@internal*/ - export function createInputFiles( - javascriptText: string, - declarationText: string, - javascriptMapPath: string | undefined, - javascriptMapText: string | undefined, - declarationMapPath: string | undefined, - declarationMapText: string | undefined, - javascriptPath: string | undefined, - declarationPath: string | undefined, - buildInfoPath?: string | undefined, - buildInfo?: BuildInfo, - oldFileOfCurrentEmit?: boolean - ): InputFiles; - export function createInputFiles( - javascriptTextOrReadFileText: string | ((path: string) => string | undefined), - declarationTextOrJavascriptPath: string, - javascriptMapPath?: string, - javascriptMapTextOrDeclarationPath?: string, - declarationMapPath?: string, - declarationMapTextOrBuildInfoPath?: string, - javascriptPath?: string | undefined, - declarationPath?: string | undefined, - buildInfoPath?: string | undefined, - buildInfo?: BuildInfo, - oldFileOfCurrentEmit?: boolean - ): InputFiles { - const node = createNode(SyntaxKind.InputFiles); - if (!isString(javascriptTextOrReadFileText)) { - const cache = createMap(); - const textGetter = (path: string | undefined) => { - if (path === undefined) return undefined; - let value = cache.get(path); - if (value === undefined) { - value = javascriptTextOrReadFileText(path); - cache.set(path, value !== undefined ? value : false); - } - return value !== false ? value as string : undefined; - }; - const definedTextGetter = (path: string) => { - const result = textGetter(path); - return result !== undefined ? result : `/* Input file ${path} was missing */\r\n`; - }; - let buildInfo: BuildInfo | false; - const getAndCacheBuildInfo = (getText: () => string | undefined) => { - if (buildInfo === undefined) { - const result = getText(); - buildInfo = result !== undefined ? getBuildInfo(result) : false; - } - return buildInfo || undefined; - }; - node.javascriptPath = declarationTextOrJavascriptPath; - node.javascriptMapPath = javascriptMapPath; - node.declarationPath = Debug.checkDefined(javascriptMapTextOrDeclarationPath); - node.declarationMapPath = declarationMapPath; - node.buildInfoPath = declarationMapTextOrBuildInfoPath; - Object.defineProperties(node, { - javascriptText: { get() { return definedTextGetter(declarationTextOrJavascriptPath); } }, - javascriptMapText: { get() { return textGetter(javascriptMapPath); } }, // TODO:: if there is inline sourceMap in jsFile, use that - declarationText: { get() { return definedTextGetter(Debug.checkDefined(javascriptMapTextOrDeclarationPath)); } }, - declarationMapText: { get() { return textGetter(declarationMapPath); } }, // TODO:: if there is inline sourceMap in dtsFile, use that - buildInfo: { get() { return getAndCacheBuildInfo(() => textGetter(declarationMapTextOrBuildInfoPath)); } } - }); - } - else { - node.javascriptText = javascriptTextOrReadFileText; - node.javascriptMapPath = javascriptMapPath; - node.javascriptMapText = javascriptMapTextOrDeclarationPath; - node.declarationText = declarationTextOrJavascriptPath; - node.declarationMapPath = declarationMapPath; - node.declarationMapText = declarationMapTextOrBuildInfoPath; - node.javascriptPath = javascriptPath; - node.declarationPath = declarationPath; - node.buildInfoPath = buildInfoPath; - node.buildInfo = buildInfo; - node.oldFileOfCurrentEmit = oldFileOfCurrentEmit; - } - return node; - } - - export function updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) { - if (node.sourceFiles !== sourceFiles || node.prepends !== prepends) { - return createBundle(sourceFiles, prepends); - } - return node; - } - - // Compound nodes - - export function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; - export function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; - export function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { - return createCall( - createFunctionExpression( - /*modifiers*/ undefined, - /*asteriskToken*/ undefined, - /*name*/ undefined, - /*typeParameters*/ undefined, - /*parameters*/ param ? [param] : [], - /*type*/ undefined, - createBlock(statements, /*multiLine*/ true) - ), - /*typeArguments*/ undefined, - /*argumentsArray*/ paramValue ? [paramValue] : [] - ); - } - - export function createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; - export function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; - export function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param?: ParameterDeclaration, paramValue?: Expression) { - return createCall( - createArrowFunction( - /*modifiers*/ undefined, - /*typeParameters*/ undefined, - /*parameters*/ param ? [param] : [], - /*type*/ undefined, - /*equalsGreaterThanToken*/ undefined, - createBlock(statements, /*multiLine*/ true) - ), - /*typeArguments*/ undefined, - /*argumentsArray*/ paramValue ? [paramValue] : [] - ); - } - - - export function createComma(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.CommaToken, right); - } - - export function createLessThan(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.LessThanToken, right); - } - - export function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; - export function createAssignment(left: Expression, right: Expression): BinaryExpression; - export function createAssignment(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.EqualsToken, right); - } - - export function createStrictEquality(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.EqualsEqualsEqualsToken, right); - } - - export function createStrictInequality(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.ExclamationEqualsEqualsToken, right); - } - - export function createAdd(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.PlusToken, right); - } - - export function createSubtract(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.MinusToken, right); - } - - export function createPostfixIncrement(operand: Expression) { - return createPostfix(operand, SyntaxKind.PlusPlusToken); - } - - export function createLogicalAnd(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.AmpersandAmpersandToken, right); - } - - export function createLogicalOr(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.BarBarToken, right); - } - - export function createNullishCoalesce(left: Expression, right: Expression) { - return createBinary(left, SyntaxKind.QuestionQuestionToken, right); - } - - export function createLogicalNot(operand: Expression) { - return createPrefix(SyntaxKind.ExclamationToken, operand); - } - - export function createVoidZero() { - return createVoid(createLiteral(0)); - } - - export function createExportDefault(expression: Expression) { - return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression); - } - - export function createExternalModuleExport(exportName: Identifier) { - return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)])); - } - - // Utilities - - function asName(name: string | T): T | Identifier { - return isString(name) ? createIdentifier(name) : name; - } - - function asExpression(value: string | number | boolean | T): T | StringLiteral | NumericLiteral | BooleanLiteral { - return typeof value === "string" ? createStringLiteral(value) : - typeof value === "number" ? createNumericLiteral(""+value) : - typeof value === "boolean" ? value ? createTrue() : createFalse() : - value; - } - - function asNodeArray(array: readonly T[]): NodeArray; - function asNodeArray(array: readonly T[] | undefined): NodeArray | undefined; - function asNodeArray(array: readonly T[] | undefined): NodeArray | undefined { - return array ? createNodeArray(array) : undefined; - } - - function asToken(value: TKind | Token): Token { - return typeof value === "number" ? createToken(value) : value; - } - - function asEmbeddedStatement(statement: T): T | EmptyStatement; - function asEmbeddedStatement(statement: T | undefined): T | EmptyStatement | undefined; - function asEmbeddedStatement(statement: T | undefined): T | EmptyStatement | undefined { - return statement && isNotEmittedStatement(statement) ? setTextRange(setOriginalNode(createEmptyStatement(), statement), statement) : statement; - } - - /** - * Clears any EmitNode entries from parse-tree nodes. - * @param sourceFile A source file. - */ - export function disposeEmitNodes(sourceFile: SourceFile) { - // During transformation we may need to annotate a parse tree node with transient - // transformation properties. As parse tree nodes live longer than transformation - // nodes, we need to make sure we reclaim any memory allocated for custom ranges - // from these nodes to ensure we do not hold onto entire subtrees just for position - // information. We also need to reset these nodes to a pre-transformation state - // for incremental parsing scenarios so that we do not impact later emit. - sourceFile = getSourceFileOfNode(getParseTreeNode(sourceFile)); - const emitNode = sourceFile && sourceFile.emitNode; - const annotatedNodes = emitNode && emitNode.annotatedNodes; - if (annotatedNodes) { - for (const node of annotatedNodes) { - node.emitNode = undefined; - } - } - } - - /** - * Associates a node with the current transformation, initializing - * various transient transformation properties. - */ - /* @internal */ - export function getOrCreateEmitNode(node: Node): EmitNode { - if (!node.emitNode) { - if (isParseTreeNode(node)) { - // To avoid holding onto transformation artifacts, we keep track of any - // parse tree node we are annotating. This allows us to clean them up after - // all transformations have completed. - if (node.kind === SyntaxKind.SourceFile) { - return node.emitNode = { annotatedNodes: [node] } as EmitNode; - } - - const sourceFile = getSourceFileOfNode(getParseTreeNode(getSourceFileOfNode(node))); - getOrCreateEmitNode(sourceFile).annotatedNodes!.push(node); - } - - node.emitNode = {} as EmitNode; - } - - return node.emitNode; - } - - /** - * Sets `EmitFlags.NoComments` on a node and removes any leading and trailing synthetic comments. - * @internal - */ - export function removeAllComments(node: T): T { - const emitNode = getOrCreateEmitNode(node); - emitNode.flags |= EmitFlags.NoComments; - emitNode.leadingComments = undefined; - emitNode.trailingComments = undefined; - return node; - } - - export function setTextRange(range: T, location: TextRange | undefined): T { - if (location) { - range.pos = location.pos; - range.end = location.end; - } - return range; - } - - /** - * Sets flags that control emit behavior of a node. - */ - export function setEmitFlags(node: T, emitFlags: EmitFlags) { - getOrCreateEmitNode(node).flags = emitFlags; - return node; - } - - /** - * Sets flags that control emit behavior of a node. - */ - /* @internal */ - export function addEmitFlags(node: T, emitFlags: EmitFlags) { - const emitNode = getOrCreateEmitNode(node); - emitNode.flags = emitNode.flags | emitFlags; - return node; - } - - /** - * Gets a custom text range to use when emitting source maps. - */ - export function getSourceMapRange(node: Node): SourceMapRange { - const emitNode = node.emitNode; - return (emitNode && emitNode.sourceMapRange) || node; - } - - /** - * Sets a custom text range to use when emitting source maps. - */ - export function setSourceMapRange(node: T, range: SourceMapRange | undefined) { - getOrCreateEmitNode(node).sourceMapRange = range; - return node; - } - - let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; - - /** - * Create an external source map source file reference - */ - export function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource { - return new (SourceMapSource || (SourceMapSource = objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia); - } - - /** - * Gets the TextRange to use for source maps for a token of a node. - */ - export function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined { - const emitNode = node.emitNode; - const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges; - return tokenSourceMapRanges && tokenSourceMapRanges[token]; - } - - /** - * Sets the TextRange to use for source maps for a token of a node. - */ - export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined) { - const emitNode = getOrCreateEmitNode(node); - const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []); - tokenSourceMapRanges[token] = range; - return node; - } - - /** - * Gets a custom text range to use when emitting comments. - */ - /*@internal*/ - export function getStartsOnNewLine(node: Node) { - const emitNode = node.emitNode; - return emitNode && emitNode.startsOnNewLine; - } - - /** - * Sets a custom text range to use when emitting comments. - */ - /*@internal*/ - export function setStartsOnNewLine(node: T, newLine: boolean) { - getOrCreateEmitNode(node).startsOnNewLine = newLine; - return node; - } - - /** - * Gets a custom text range to use when emitting comments. - */ - export function getCommentRange(node: Node) { - const emitNode = node.emitNode; - return (emitNode && emitNode.commentRange) || node; - } - - /** - * Sets a custom text range to use when emitting comments. - */ - export function setCommentRange(node: T, range: TextRange) { - getOrCreateEmitNode(node).commentRange = range; - return node; - } - - export function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined { - const emitNode = node.emitNode; - return emitNode && emitNode.leadingComments; - } - - export function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined) { - getOrCreateEmitNode(node).leadingComments = comments; - return node; - } - - export function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { - return setSyntheticLeadingComments(node, append(getSyntheticLeadingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); - } - - export function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined { - const emitNode = node.emitNode; - return emitNode && emitNode.trailingComments; - } - - export function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined) { - getOrCreateEmitNode(node).trailingComments = comments; - return node; - } - - export function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { - return setSyntheticTrailingComments(node, append(getSyntheticTrailingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); - } - - export function moveSyntheticComments(node: T, original: Node): T { - setSyntheticLeadingComments(node, getSyntheticLeadingComments(original)); - setSyntheticTrailingComments(node, getSyntheticTrailingComments(original)); - const emit = getOrCreateEmitNode(original); - emit.leadingComments = undefined; - emit.trailingComments = undefined; - return node; - } - - /** @internal */ - export function ignoreSourceNewlines(node: T): T { - getOrCreateEmitNode(node).flags |= EmitFlags.IgnoreSourceNewlines; - return node; - } - - /** - * Gets the constant value to emit for an expression. - */ - export function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression): string | number | undefined { - const emitNode = node.emitNode; - return emitNode && emitNode.constantValue; - } - - /** - * Sets the constant value to emit for an expression. - */ - export function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: string | number): PropertyAccessExpression | ElementAccessExpression { - const emitNode = getOrCreateEmitNode(node); - emitNode.constantValue = value; - return node; - } - - /** - * Adds an EmitHelper to a node. - */ - export function addEmitHelper(node: T, helper: EmitHelper): T { - const emitNode = getOrCreateEmitNode(node); - emitNode.helpers = append(emitNode.helpers, helper); - return node; - } - - /** - * Add EmitHelpers to a node. - */ - export function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T { - if (some(helpers)) { - const emitNode = getOrCreateEmitNode(node); - for (const helper of helpers) { - emitNode.helpers = appendIfUnique(emitNode.helpers, helper); - } - } - return node; - } - - /** - * Removes an EmitHelper from a node. - */ - export function removeEmitHelper(node: Node, helper: EmitHelper): boolean { - const emitNode = node.emitNode; - if (emitNode) { - const helpers = emitNode.helpers; - if (helpers) { - return orderedRemoveItem(helpers, helper); - } - } - return false; - } - - /** - * Gets the EmitHelpers of a node. - */ - export function getEmitHelpers(node: Node): EmitHelper[] | undefined { - const emitNode = node.emitNode; - return emitNode && emitNode.helpers; - } - - /** - * Moves matching emit helpers from a source node to a target node. - */ - export function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean) { - const sourceEmitNode = source.emitNode; - const sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers; - if (!some(sourceEmitHelpers)) return; - - const targetEmitNode = getOrCreateEmitNode(target); - let helpersRemoved = 0; - for (let i = 0; i < sourceEmitHelpers.length; i++) { - const helper = sourceEmitHelpers[i]; - if (predicate(helper)) { - helpersRemoved++; - targetEmitNode.helpers = appendIfUnique(targetEmitNode.helpers, helper); - } - else if (helpersRemoved > 0) { - sourceEmitHelpers[i - helpersRemoved] = helper; - } - } - - if (helpersRemoved > 0) { - sourceEmitHelpers.length -= helpersRemoved; - } - } - - /* @internal */ - export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) { - if (x === y) return Comparison.EqualTo; - if (x.priority === y.priority) return Comparison.EqualTo; - if (x.priority === undefined) return Comparison.GreaterThan; - if (y.priority === undefined) return Comparison.LessThan; - return compareValues(x.priority, y.priority); - } - - export function setOriginalNode(node: T, original: Node | undefined): T { - node.original = original; - if (original) { - const emitNode = original.emitNode; - if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); - } - return node; - } - - function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode | undefined) { - const { - flags, - leadingComments, - trailingComments, - commentRange, - sourceMapRange, - tokenSourceMapRanges, - constantValue, - helpers, - startsOnNewLine, - } = sourceEmitNode; - if (!destEmitNode) destEmitNode = {} as EmitNode; - // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later. - if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments); - if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments); - if (flags) destEmitNode.flags = flags; - if (commentRange) destEmitNode.commentRange = commentRange; - if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange; - if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges!); - if (constantValue !== undefined) destEmitNode.constantValue = constantValue; - if (helpers) destEmitNode.helpers = addRange(destEmitNode.helpers, helpers); - if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine; - return destEmitNode; - } - - function mergeTokenSourceMapRanges(sourceRanges: (TextRange | undefined)[], destRanges: (TextRange | undefined)[]) { - if (!destRanges) destRanges = []; - for (const key in sourceRanges) { - destRanges[key] = sourceRanges[key]; - } - return destRanges; - } -} diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e886c9e5477eb..85c0402f663fb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -14,23 +14,20 @@ namespace ts { let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node { - if (kind === SyntaxKind.SourceFile) { - return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, pos, end); - } - else if (kind === SyntaxKind.Identifier) { - return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, pos, end); - } - else if (kind === SyntaxKind.PrivateIdentifier) { - return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, pos, end); - } - else if (!isNodeKind(kind)) { - return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, pos, end); - } - else { - return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, pos, end); - } - } + /** + * NOTE: You should not use this, it is only exported to support `createNode` in `~/src/compat/deprecations.ts`. + */ + /* @internal */ + export const parseBaseNodeFactory: BaseNodeFactory = { + createBaseSourceFileNode: kind => new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, -1, -1), + createBaseIdentifierNode: kind => new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, -1, -1), + createBasePrivateIdentifierNode: kind => new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, -1, -1), + createBaseTokenNode: kind => new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, -1, -1), + createBaseNode: kind => new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, -1, -1), + }; + + /* @internal */ + export const parseNodeFactory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules, parseBaseNodeFactory); function visitNode(cbNode: (node: Node) => T, node: Node | undefined): T | undefined { return node && cbNode(node); @@ -649,7 +646,7 @@ namespace ts { const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import. // We will manually port the flag to the new source file. - newSourceFile.flags |= (sourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags); + (newSourceFile as Mutable).flags |= (sourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags); return newSourceFile; } @@ -678,21 +675,46 @@ namespace ts { // Share a single scanner across all calls to parse a source file. This helps speed things // up by avoiding the cost of creating/compiling scanners over and over again. const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); + const disallowInAndDecoratorContext = NodeFlags.DisallowInContext | NodeFlags.DecoratorContext; // capture constructors in 'initializeState' to avoid null checks + // tslint:disable variable-name let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + // tslint:enable variable-name - let sourceFile: SourceFile; - let parseDiagnostics: DiagnosticWithLocation[]; + function countNode(node: Node) { + nodeCount++; + return node; + } + + // Rather than using `createBaseNodeFactory` here, we establish a `BaseNodeFactory` that closes over the + // constructors above, which are reset each time `initializeState` is called. + const baseNodeFactory: BaseNodeFactory = { + createBaseSourceFileNode: kind => countNode(new SourceFileConstructor(kind, /*pos*/ 0, /*end*/ 0)), + createBaseIdentifierNode: kind => countNode(new IdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0)), + createBasePrivateIdentifierNode: kind => countNode(new PrivateIdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0)), + createBaseTokenNode: kind => countNode(new TokenConstructor(kind, /*pos*/ 0, /*end*/ 0)), + createBaseNode: kind => countNode(new NodeConstructor(kind, /*pos*/ 0, /*end*/ 0)) + }; + + const factory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules | NodeFactoryFlags.NoNodeConverters | NodeFactoryFlags.NoOriginalNode, baseNodeFactory); + + let fileName: string; + let sourceFlags: NodeFlags; + let sourceText: string; + let languageVersion: ScriptTarget; + let scriptKind: ScriptKind; + let languageVariant: LanguageVariant; + let parseDiagnostics: DiagnosticWithDetachedLocation[]; + let jsDocDiagnostics: DiagnosticWithDetachedLocation[]; let syntaxCursor: IncrementalParser.SyntaxCursor | undefined; let currentToken: SyntaxKind; - let sourceText: string; let nodeCount: number; let identifiers: Map; let privateIdentifiers: Map; @@ -793,9 +815,9 @@ namespace ts { return result; } - initializeState(sourceText, languageVersion, syntaxCursor, scriptKind); + initializeState(fileName, sourceText, languageVersion, syntaxCursor, scriptKind); - const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind); + const result = parseSourceFileWorker(languageVersion, setParentNodes, scriptKind); clearState(); @@ -804,7 +826,7 @@ namespace ts { export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName | undefined { // Choice of `isDeclarationFile` should be arbitrary - initializeState(content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS); + initializeState("", content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS); // Prime the scanner. nextToken(); const entityName = parseEntityName(/*allowReservedWords*/ true); @@ -813,54 +835,58 @@ namespace ts { return isInvalid ? entityName : undefined; } - export function parseJsonText(fileName: string, sourceText: string, languageVersion: ScriptTarget = ScriptTarget.ES2015, syntaxCursor?: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): JsonSourceFile { - initializeState(sourceText, languageVersion, syntaxCursor, ScriptKind.JSON); - // Set source file so that errors will be reported with this file name - sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false); - sourceFile.flags = contextFlags; + export function parseJsonText(fileName: string, sourceText: string, languageVersion: ScriptTarget = ScriptTarget.ES2015, syntaxCursor?: IncrementalParser.SyntaxCursor, setParentNodes = false): JsonSourceFile { + initializeState(fileName, sourceText, languageVersion, syntaxCursor, ScriptKind.JSON); + sourceFlags = contextFlags; // Prime the scanner. nextToken(); const pos = getNodePos(); + let statements, endOfFileToken; if (token() === SyntaxKind.EndOfFileToken) { - sourceFile.statements = createNodeArray([], pos, pos); - sourceFile.endOfFileToken = parseTokenNode(); + statements = createNodeArray([], pos, pos); + endOfFileToken = parseTokenNode(); } else { - const statement = createNode(SyntaxKind.ExpressionStatement) as JsonObjectExpressionStatement; + let expression; switch (token()) { case SyntaxKind.OpenBracketToken: - statement.expression = parseArrayLiteralExpression(); + expression = parseArrayLiteralExpression(); break; case SyntaxKind.TrueKeyword: case SyntaxKind.FalseKeyword: case SyntaxKind.NullKeyword: - statement.expression = parseTokenNode(); + expression = parseTokenNode(); break; case SyntaxKind.MinusToken: if (lookAhead(() => nextToken() === SyntaxKind.NumericLiteral && nextToken() !== SyntaxKind.ColonToken)) { - statement.expression = parsePrefixUnaryExpression() as JsonMinusNumericLiteral; + expression = parsePrefixUnaryExpression() as JsonMinusNumericLiteral; } else { - statement.expression = parseObjectLiteralExpression(); + expression = parseObjectLiteralExpression(); } break; case SyntaxKind.NumericLiteral: case SyntaxKind.StringLiteral: if (lookAhead(() => nextToken() !== SyntaxKind.ColonToken)) { - statement.expression = parseLiteralNode() as StringLiteral | NumericLiteral; + expression = parseLiteralNode() as StringLiteral | NumericLiteral; break; } // falls through default: - statement.expression = parseObjectLiteralExpression(); + expression = parseObjectLiteralExpression(); break; } - finishNode(statement); - sourceFile.statements = createNodeArray([statement], pos); - sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token); + + const statement = factory.createExpressionStatement(expression) as JsonObjectExpressionStatement; + finishNode(statement, pos); + statements = createNodeArray([statement], pos); + endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token); } + // Set source file so that errors will be reported with this file name + const sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false, statements, endOfFileToken, sourceFlags); + if (setParentNodes) { fixupParentReferences(sourceFile); } @@ -868,27 +894,29 @@ namespace ts { sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; - sourceFile.parseDiagnostics = parseDiagnostics; + sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + if (jsDocDiagnostics) { + sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + } const result = sourceFile as JsonSourceFile; clearState(); return result; } - function getLanguageVariant(scriptKind: ScriptKind) { - // .tsx and .jsx files are treated as jsx language variant. - return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; - } - - function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, scriptKind: ScriptKind) { + function initializeState(_fileName: string, _sourceText: string, _languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, _scriptKind: ScriptKind) { NodeConstructor = objectAllocator.getNodeConstructor(); TokenConstructor = objectAllocator.getTokenConstructor(); IdentifierConstructor = objectAllocator.getIdentifierConstructor(); PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor(); SourceFileConstructor = objectAllocator.getSourceFileConstructor(); + fileName = normalizePath(_fileName); sourceText = _sourceText; + languageVersion = _languageVersion; syntaxCursor = _syntaxCursor; + scriptKind = _scriptKind; + languageVariant = getLanguageVariant(_scriptKind); parseDiagnostics = []; parsingContext = 0; @@ -896,6 +924,7 @@ namespace ts { privateIdentifiers = createMap(); identifierCount = 0; nodeCount = 0; + sourceFlags = 0; switch (scriptKind) { case ScriptKind.JS: @@ -915,7 +944,7 @@ namespace ts { scanner.setText(sourceText); scanner.setOnError(scanError); scanner.setScriptTarget(languageVersion); - scanner.setLanguageVariant(getLanguageVariant(scriptKind)); + scanner.setLanguageVariant(languageVariant); } function clearState() { @@ -925,40 +954,50 @@ namespace ts { scanner.setOnError(undefined); // Clear any data. We don't want to accidentally hold onto it for too long. + sourceText = undefined!; + languageVersion = undefined!; + syntaxCursor = undefined; + scriptKind = undefined!; + languageVariant = undefined!; + sourceFlags = 0; parseDiagnostics = undefined!; - sourceFile = undefined!; + jsDocDiagnostics = undefined!; + parsingContext = 0; identifiers = undefined!; - syntaxCursor = undefined; - sourceText = undefined!; notParenthesizedArrow = undefined!; } - function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile { + function parseSourceFileWorker(languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile { const isDeclarationFile = isDeclarationFileName(fileName); if (isDeclarationFile) { contextFlags |= NodeFlags.Ambient; } - sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile); - sourceFile.flags = contextFlags; + sourceFlags = contextFlags; // Prime the scanner. nextToken(); + + const statements = parseList(ParsingContext.SourceElements, parseStatement); + Debug.assert(token() === SyntaxKind.EndOfFileToken); + const endOfFileToken = addJSDocComment(parseTokenNode()); + + const sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile, statements, endOfFileToken, sourceFlags); + // A member of ReadonlyArray isn't assignable to a member of T[] (and prevents a direct cast) - but this is where we set up those members so they can be readonly in the future processCommentPragmas(sourceFile as {} as PragmaContext, sourceText); processPragmasIntoFields(sourceFile as {} as PragmaContext, reportPragmaDiagnostic); - sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement); - Debug.assert(token() === SyntaxKind.EndOfFileToken); - sourceFile.endOfFileToken = addJSDocComment(parseTokenNode()); - setExternalModuleIndicator(sourceFile); sourceFile.commentDirectives = scanner.getCommentDirectives(); sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; - sourceFile.parseDiagnostics = parseDiagnostics; + sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + if (jsDocDiagnostics) { + sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + } if (setParentNodes) { fixupParentReferences(sourceFile); @@ -967,13 +1006,17 @@ namespace ts { return sourceFile; function reportPragmaDiagnostic(pos: number, end: number, diagnostic: DiagnosticMessage) { - parseDiagnostics.push(createFileDiagnostic(sourceFile, pos, end, diagnostic)); + parseDiagnostics.push(createDetachedDiagnostic(fileName, pos, end, diagnostic)); } } + function withJSDoc(node: T, hasJSDoc: boolean): T { + return hasJSDoc ? addJSDocComment(node) : node; + } + function addJSDocComment(node: T): T { Debug.assert(!node.jsDoc); // Should only be called once per node - const jsDoc = mapDefined(getJSDocCommentRanges(node, sourceFile.text), comment => JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); + const jsDoc = mapDefined(getJSDocCommentRanges(node, sourceText), comment => JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); if (jsDoc.length) node.jsDoc = jsDoc; return node; } @@ -983,30 +1026,19 @@ namespace ts { // a syntax tree, and no semantic features, then the binding process is an unnecessary // overhead. This functions allows us to set all the parents, without all the expense of // binding. - forEachChildRecursively(rootNode, bindParentToChild); - - function bindParentToChild(child: Node, parent: Node) { - child.parent = parent; - if (hasJSDocNodes(child)) { - for (const doc of child.jsDoc!) { - bindParentToChild(doc, child); - forEachChildRecursively(doc, bindParentToChild); - } - } - } + setParentRecursive(rootNode, /*incremental*/ true); } - function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean): SourceFile { + function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean, statements: readonly Statement[], endOfFileToken: EndOfFileToken, flags: NodeFlags): SourceFile { // code from createNode is inlined here so createNode won't have to deal with special case of creating source files // this is quite rare comparing to other nodes and createNode should be as fast as possible - const sourceFile = new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length); - nodeCount++; - + const sourceFile = factory.createSourceFile(statements, endOfFileToken, flags); + setTextRangePosWidth(sourceFile, 0, sourceText.length); sourceFile.text = sourceText; sourceFile.bindDiagnostics = []; sourceFile.bindSuggestionDiagnostics = undefined; sourceFile.languageVersion = languageVersion; - sourceFile.fileName = normalizePath(fileName); + sourceFile.fileName = fileName; sourceFile.languageVariant = getLanguageVariant(scriptKind); sourceFile.isDeclarationFile = isDeclarationFile; sourceFile.scriptKind = scriptKind; @@ -1141,7 +1173,7 @@ namespace ts { // Don't report another error if it would just be at the same position as the last error. const lastError = lastOrUndefined(parseDiagnostics); if (!lastError || start !== lastError.start) { - parseDiagnostics.push(createFileDiagnostic(sourceFile, start, length, message, arg0)); + parseDiagnostics.push(createDetachedDiagnostic(fileName, start, length, message, arg0)); } // Mark that we've encountered an error. We'll set an appropriate bit on the next @@ -1165,6 +1197,10 @@ namespace ts { return scanner.getStartPos(); } + function hasPrecedingJSDocComment() { + return scanner.hasPrecedingJSDocComment(); + } + // Use this function to access the current token instead of reading the currentToken // variable. Since function results aren't narrowed in control flow analysis, this ensures // that the type checker doesn't make wrong assumptions about the type of the current @@ -1179,6 +1215,11 @@ namespace ts { return currentToken = scanner.scan(); } + function nextTokenAnd(func: () => T): T { + nextToken(); + return func(); + } + function nextToken(): SyntaxKind { // if the keyword had an escape if (isKeyword(currentToken) && (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape())) { @@ -1359,15 +1400,17 @@ namespace ts { } function parseTokenNode(): T { - const node = createNode(token()); + const pos = getNodePos(); + const kind = token(); nextToken(); - return finishNode(node); + return finishNode(factory.createToken(kind), pos); } function parseTokenNodeJSDoc(): T { - const node = createNode(token()); + const pos = getNodePos(); + const kind = token(); nextTokenJSDoc(); - return finishNode(node); + return finishNode(factory.createToken(kind), pos); } function canParseSemicolon() { @@ -1394,39 +1437,16 @@ namespace ts { } } - function createNode(kind: SyntaxKind, pos?: number): Node { - nodeCount++; - const p = pos! >= 0 ? pos! : scanner.getStartPos(); - return isNodeKind(kind) || kind === SyntaxKind.Unknown ? new NodeConstructor(kind, p, p) : - kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, p, p) : - kind === SyntaxKind.PrivateIdentifier ? new PrivateIdentifierConstructor(kind, p, p) : - new TokenConstructor(kind, p, p); - } - - function createNodeWithJSDoc(kind: SyntaxKind, pos?: number): Node { - const node = createNode(kind, pos); - if (scanner.getTokenFlags() & TokenFlags.PrecedingJSDocComment && (kind !== SyntaxKind.ExpressionStatement || token() !== SyntaxKind.OpenParenToken)) { - addJSDocComment(node); - } - return node; - } - - function createNodeArray(elements: T[], pos: number, end?: number): NodeArray { - // Since the element list of a node array is typically created by starting with an empty array and - // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for - // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation. - const length = elements.length; - const array = >(length >= 1 && length <= 4 ? elements.slice() : elements); - array.pos = pos; - array.end = end === undefined ? scanner.getStartPos() : end; + function createNodeArray(elements: T[], pos: number, end?: number, hasTrailingComma?: boolean): NodeArray { + const array = factory.createNodeArray(elements, hasTrailingComma); + setTextRangePosEnd(array, pos, end ?? scanner.getStartPos()); return array; } - function finishNode(node: T, end?: number): T { - node.end = end === undefined ? scanner.getStartPos() : end; - + function finishNode(node: T, pos: number, end?: number): T { + setTextRangePosEnd(node, pos, end ?? scanner.getStartPos()); if (contextFlags) { - node.flags |= contextFlags; + (node as Mutable).flags |= contextFlags; } // Keep track on the node if we encountered an error while parsing it. If we did, then @@ -1434,7 +1454,7 @@ namespace ts { // flag so that we don't mark any subsequent nodes. if (parseErrorBeforeNextFinishedNode) { parseErrorBeforeNextFinishedNode = false; - node.flags |= NodeFlags.ThisNodeHasError; + (node as Mutable).flags |= NodeFlags.ThisNodeHasError; } return node; @@ -1450,16 +1470,15 @@ namespace ts { parseErrorAtCurrentToken(diagnosticMessage, arg0); } - const result = createNode(kind); - - if (kind === SyntaxKind.Identifier) { - (result as Identifier).escapedText = "" as __String; - } - else if (isLiteralKind(kind) || isTemplateLiteralKind(kind)) { - (result as LiteralLikeNode).text = ""; - } - - return finishNode(result) as T; + const pos = getNodePos(); + const result = + kind === SyntaxKind.Identifier ? factory.createIdentifier("", /*typeArguments*/ undefined, /*originalKeywordKind*/ undefined) : + isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, "", "", /*templateFlags*/ undefined) : + kind === SyntaxKind.NumericLiteral ? factory.createNumericLiteral("", /*numericLiteralFlags*/ undefined) : + kind === SyntaxKind.StringLiteral ? factory.createStringLiteral("", /*isSingleQuote*/ undefined) : + kind === SyntaxKind.MissingDeclaration ? factory.createMissingDeclaration() : + factory.createToken(kind); + return finishNode(result, pos) as T; } function internIdentifier(text: string): string { @@ -1476,15 +1495,12 @@ namespace ts { function createIdentifier(isIdentifier: boolean, diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier { identifierCount++; if (isIdentifier) { - const node = createNode(SyntaxKind.Identifier); - + const pos = getNodePos(); // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker - if (token() !== SyntaxKind.Identifier) { - node.originalKeywordKind = token(); - } - node.escapedText = escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue())); + const originalKeywordKind = token(); + const text = internIdentifier(scanner.getTokenValue()); nextTokenWithoutCheck(); - return finishNode(node); + return finishNode(factory.createIdentifier(text, /*typeArguments*/ undefined, originalKeywordKind), pos); } if (token() === SyntaxKind.PrivateIdentifier) { @@ -1542,16 +1558,14 @@ namespace ts { // PropertyName [Yield]: // LiteralPropertyName // ComputedPropertyName[?Yield] - const node = createNode(SyntaxKind.ComputedPropertyName); + const pos = getNodePos(); parseExpected(SyntaxKind.OpenBracketToken); - // We parse any expression (including a comma expression). But the grammar // says that only an assignment expression is allowed, so the grammar checker // will error if it sees a comma expression. - node.expression = allowInAnd(parseExpression); - + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseBracketToken); - return finishNode(node); + return finishNode(factory.createComputedPropertyName(expression), pos); } function internPrivateIdentifier(text: string): string { @@ -1563,10 +1577,10 @@ namespace ts { } function parsePrivateIdentifier(): PrivateIdentifier { - const node = createNode(SyntaxKind.PrivateIdentifier) as PrivateIdentifier; - node.escapedText = escapeLeadingUnderscores(internPrivateIdentifier(scanner.getTokenText())); + const pos = getNodePos(); + const node = factory.createPrivateIdentifier(internPrivateIdentifier(scanner.getTokenText())); nextToken(); - return finishNode(node); + return finishNode(node, pos); } function parseContextualModifier(t: SyntaxKind): boolean { @@ -2294,17 +2308,13 @@ namespace ts { } parsingContext = saveParsingContext; - const result = createNodeArray(list, listPos); // Recording the trailing comma is deliberately done after the previous // loop, and not just if we see a list terminator. This is because the list // may have ended incorrectly, but it is still important to know if there // was a trailing comma. // Check if the last token was a comma. - if (commaStart >= 0) { - // Always preserve a trailing comma by marking it on the NodeArray - result.hasTrailingComma = true; - } - return result; + // Always preserve a trailing comma by marking it on the NodeArray + return createNodeArray(list, listPos, /*end*/ undefined, commaStart >= 0); } function getExpectedCommaDiagnostic(kind: ParsingContext) { @@ -2336,25 +2346,29 @@ namespace ts { } function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { + const pos = getNodePos(); let entity: EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); - let dotPos = scanner.getStartPos(); + let dotPos = getNodePos(); while (parseOptional(SyntaxKind.DotToken)) { if (token() === SyntaxKind.LessThanToken) { // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting entity.jsdocDotPos = dotPos; break; } - dotPos = scanner.getStartPos(); - entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false) as Identifier); + dotPos = getNodePos(); + entity = finishNode( + factory.createQualifiedName( + entity, + parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false) as Identifier + ), + pos + ); } return entity; } function createQualifiedName(entity: EntityName, name: Identifier): QualifiedName { - const node = createNode(SyntaxKind.QualifiedName, entity.pos) as QualifiedName; - node.left = entity; - node.right = name; - return finishNode(node); + return finishNode(factory.createQualifiedName(entity, name), entity.pos); } function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean): Identifier | PrivateIdentifier { @@ -2396,40 +2410,49 @@ namespace ts { return allowIdentifierNames ? parseIdentifierName() : parseIdentifier(); } - function parseTemplateExpression(isTaggedTemplate: boolean): TemplateExpression { - const template = createNode(SyntaxKind.TemplateExpression); - - template.head = parseTemplateHead(isTaggedTemplate); - Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind"); - + function parseTemplateSpans(isTaggedTemplate: boolean) { + const pos = getNodePos(); const list = []; - const listPos = getNodePos(); - + let node: TemplateSpan; do { - list.push(parseTemplateSpan(isTaggedTemplate)); + node = parseTemplateSpan(isTaggedTemplate); + list.push(node); } - while (last(list).literal.kind === SyntaxKind.TemplateMiddle); - - template.templateSpans = createNodeArray(list, listPos); - - return finishNode(template); + while (node.literal.kind === SyntaxKind.TemplateMiddle); + return createNodeArray(list, pos); } - function parseTemplateSpan(isTaggedTemplate: boolean): TemplateSpan { - const span = createNode(SyntaxKind.TemplateSpan); - span.expression = allowInAnd(parseExpression); + function parseTemplateExpression(isTaggedTemplate: boolean): TemplateExpression { + const pos = getNodePos(); + return finishNode( + factory.createTemplateExpression( + parseTemplateHead(isTaggedTemplate), + parseTemplateSpans(isTaggedTemplate) + ), + pos + ); + } - let literal: TemplateMiddle | TemplateTail; + function parseLiteralOfTemplateSpan(isTaggedTemplate: boolean) { if (token() === SyntaxKind.CloseBraceToken) { reScanTemplateToken(isTaggedTemplate); - literal = parseTemplateMiddleOrTemplateTail(); + return parseTemplateMiddleOrTemplateTail(); } else { - literal = parseExpectedToken(SyntaxKind.TemplateTail, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); + // TODO(rbuckton): Do we need to call `parseExpectedToken` or can we just call `createMissingNode` directly? + return parseExpectedToken(SyntaxKind.TemplateTail, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); } + } - span.literal = literal; - return finishNode(span); + function parseTemplateSpan(isTaggedTemplate: boolean): TemplateSpan { + const pos = getNodePos(); + return finishNode( + factory.createTemplateSpan( + allowInAnd(parseExpression), + parseLiteralOfTemplateSpan(isTaggedTemplate) + ), + pos + ); } function parseLiteralNode(): LiteralExpression { @@ -2451,19 +2474,26 @@ namespace ts { return fragment; } + function getTemplateLiteralRawText(kind: TemplateLiteralToken["kind"]) { + const isLast = kind === SyntaxKind.NoSubstitutionTemplateLiteral || kind === SyntaxKind.TemplateTail; + const tokenText = scanner.getTokenText(); + return tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2)); + } + function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode { - const node = createNode(kind); - node.text = scanner.getTokenValue(); - switch (kind) { - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - case SyntaxKind.TemplateMiddle: - case SyntaxKind.TemplateTail: - const isLast = kind === SyntaxKind.NoSubstitutionTemplateLiteral || kind === SyntaxKind.TemplateTail; - const tokenText = scanner.getTokenText(); - (node).rawText = tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2)); - break; - } + const pos = getNodePos(); + const node = + isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, scanner.getTokenValue(), getTemplateLiteralRawText(kind), scanner.getTokenFlags() & TokenFlags.TemplateLiteralLikeFlags) : + // Octal literals are not allowed in strict mode or ES5 + // Note that theoretically the following condition would hold true literals like 009, + // which is not octal. But because of how the scanner separates the tokens, we would + // never get a token like this. Instead, we would get 00 and 9 as two separate tokens. + // We also do not need to check for negatives because any prefix operator would be part of a + // parent unary expression. + kind === SyntaxKind.NumericLiteral ? factory.createNumericLiteral(scanner.getTokenValue(), scanner.getNumericLiteralFlags()) : + kind === SyntaxKind.StringLiteral ? factory.createStringLiteral(scanner.getTokenValue(), /*isSingleQuote*/ undefined, scanner.hasExtendedUnicodeEscape()) : + isLiteralKind(kind) ? factory.createLiteralLikeNode(kind, scanner.getTokenValue()) : + Debug.fail(); if (scanner.hasExtendedUnicodeEscape()) { node.hasExtendedUnicodeEscape = true; @@ -2473,35 +2503,31 @@ namespace ts { node.isUnterminated = true; } - // Octal literals are not allowed in strict mode or ES5 - // Note that theoretically the following condition would hold true literals like 009, - // which is not octal.But because of how the scanner separates the tokens, we would - // never get a token like this. Instead, we would get 00 and 9 as two separate tokens. - // We also do not need to check for negatives because any prefix operator would be part of a - // parent unary expression. - if (node.kind === SyntaxKind.NumericLiteral) { - (node).numericLiteralFlags = scanner.getTokenFlags() & TokenFlags.NumericLiteralFlags; - } - - if (isTemplateLiteralKind(node.kind)) { - (node).templateFlags = scanner.getTokenFlags() & TokenFlags.ContainsInvalidEscape; - } - nextToken(); - finishNode(node); - - return node; + return finishNode(node, pos); } // TYPES - function parseTypeReference(): TypeReferenceNode { - const node = createNode(SyntaxKind.TypeReference); - node.typeName = parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); + function parseEntityNameOfTypeReference() { + return parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); + } + + function parseTypeArgumentsOfTypeReference() { if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) { - node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); + return parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); } - return finishNode(node); + } + + function parseTypeReference(): TypeReferenceNode { + const pos = getNodePos(); + return finishNode( + factory.createTypeReferenceNode( + parseEntityNameOfTypeReference(), + parseTypeArgumentsOfTypeReference() + ), + pos + ); } // If true, we should abort parsing an error function. @@ -2523,38 +2549,38 @@ namespace ts { function parseThisTypePredicate(lhs: ThisTypeNode): TypePredicateNode { nextToken(); - const node = createNode(SyntaxKind.TypePredicate, lhs.pos) as TypePredicateNode; - node.parameterName = lhs; - node.type = parseType(); - return finishNode(node); + return finishNode(factory.createTypePredicateNode(/*assertsModifier*/ undefined, lhs, parseType()), lhs.pos); } function parseThisTypeNode(): ThisTypeNode { - const node = createNode(SyntaxKind.ThisType) as ThisTypeNode; + const pos = getNodePos(); nextToken(); - return finishNode(node); + return finishNode(factory.createThisTypeNode(), pos); } function parseJSDocAllType(postFixEquals: boolean): JSDocAllType | JSDocOptionalType { - const result = createNode(SyntaxKind.JSDocAllType) as JSDocAllType; + const pos = getNodePos(); + nextToken(); + + const node = factory.createJSDocAllType(); if (postFixEquals) { - return createPostfixType(SyntaxKind.JSDocOptionalType, result) as JSDocOptionalType; + // Trim the trailing `=` from the `*=` token + const end = Math.max(getNodePos() - 1, pos); + return finishNode(factory.createJSDocOptionalType(finishNode(node, pos, end)), pos); } else { - nextToken(); + return finishNode(node, pos); } - return finishNode(result); } function parseJSDocNonNullableType(): TypeNode { - const result = createNode(SyntaxKind.JSDocNonNullableType) as JSDocNonNullableType; + const pos = getNodePos(); nextToken(); - result.type = parseNonArrayType(); - return finishNode(result); + return finishNode(factory.createJSDocNonNullableType(parseNonArrayType()), pos); } function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType { - const pos = scanner.getStartPos(); + const pos = getNodePos(); // skip the ? nextToken(); @@ -2574,44 +2600,53 @@ namespace ts { token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.EqualsToken || token() === SyntaxKind.BarToken) { - - const result = createNode(SyntaxKind.JSDocUnknownType, pos); - return finishNode(result); + return finishNode(factory.createJSDocUnknownType(), pos); } else { - const result = createNode(SyntaxKind.JSDocNullableType, pos); - result.type = parseType(); - return finishNode(result); + return finishNode(factory.createJSDocNullableType(parseType()), pos); } } function parseJSDocFunctionType(): JSDocFunctionType | TypeReferenceNode { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); if (lookAhead(nextTokenIsOpenParen)) { - const result = createNodeWithJSDoc(SyntaxKind.JSDocFunctionType); nextToken(); - fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type | SignatureFlags.JSDoc, result); - return finishNode(result); + const parameters = parseParameters(SignatureFlags.Type | SignatureFlags.JSDoc); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + return withJSDoc(finishNode(factory.createJSDocFunctionType(parameters, type), pos), hasJSDoc); } - const node = createNode(SyntaxKind.TypeReference); - node.typeName = parseIdentifierName(); - return finishNode(node); + return finishNode(factory.createTypeReferenceNode(parseIdentifierName(), /*typeArguments*/ undefined), pos); } function parseJSDocParameter(): ParameterDeclaration { - const parameter = createNode(SyntaxKind.Parameter) as ParameterDeclaration; + const pos = getNodePos(); + let name: Identifier | undefined; if (token() === SyntaxKind.ThisKeyword || token() === SyntaxKind.NewKeyword) { - parameter.name = parseIdentifierName(); + name = parseIdentifierName(); parseExpected(SyntaxKind.ColonToken); } - parameter.type = parseJSDocType(); - return finishNode(parameter); + return finishNode( + factory.createParameterDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + // TODO(rbuckton): JSDoc parameters don't have names (except `this`/`new`), should we manufacture an empty identifier? + name!, + /*questionToken*/ undefined, + parseJSDocType(), + /*initializer*/ undefined + ), + pos + ); } function parseJSDocType(): TypeNode { scanner.setInJSDocType(true); - const moduleSpecifier = parseOptionalToken(SyntaxKind.ModuleKeyword); - if (moduleSpecifier) { - const moduleTag = createNode(SyntaxKind.JSDocNamepathType, moduleSpecifier.pos) as JSDocNamepathType; + const pos = getNodePos(); + if (parseOptional(SyntaxKind.ModuleKeyword)) { + // TODO(rbuckton): We never set the type for a JSDocNamepathType. What should we put here? + const moduleTag = factory.createJSDocNamepathType(/*type*/ undefined!); terminate: while (true) { switch (token()) { case SyntaxKind.CloseBraceToken: @@ -2625,40 +2660,40 @@ namespace ts { } scanner.setInJSDocType(false); - return finishNode(moduleTag); + return finishNode(moduleTag, pos); } - const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken); + const hasDotDotDot = parseOptional(SyntaxKind.DotDotDotToken); let type = parseTypeOrTypePredicate(); scanner.setInJSDocType(false); - if (dotdotdot) { - const variadic = createNode(SyntaxKind.JSDocVariadicType, dotdotdot.pos) as JSDocVariadicType; - variadic.type = type; - type = finishNode(variadic); + if (hasDotDotDot) { + type = finishNode(factory.createJSDocVariadicType(type), pos); } if (token() === SyntaxKind.EqualsToken) { - return createPostfixType(SyntaxKind.JSDocOptionalType, type); + nextToken(); + return finishNode(factory.createJSDocOptionalType(type), pos); } return type; } function parseTypeQuery(): TypeQueryNode { - const node = createNode(SyntaxKind.TypeQuery); + const pos = getNodePos(); parseExpected(SyntaxKind.TypeOfKeyword); - node.exprName = parseEntityName(/*allowReservedWords*/ true); - return finishNode(node); + return finishNode(factory.createTypeQueryNode(parseEntityName(/*allowReservedWords*/ true)), pos); } function parseTypeParameter(): TypeParameterDeclaration { - const node = createNode(SyntaxKind.TypeParameter); - node.name = parseIdentifier(); + const pos = getNodePos(); + const name = parseIdentifier(); + let constraint: TypeNode | undefined; + let expression: Expression | undefined; if (parseOptional(SyntaxKind.ExtendsKeyword)) { // It's not uncommon for people to write improper constraints to a generic. If the // user writes a constraint that is an expression and not an actual type, then parse // it out as an expression (so we can recover well), but report that a type is needed // instead. if (isStartOfType() || !isStartOfExpression()) { - node.constraint = parseType(); + constraint = parseType(); } else { // It was not a type, and it looked like an expression. Parse out an expression @@ -2668,15 +2703,14 @@ namespace ts { // // // We do *not* want to consume the `>` as we're consuming the expression for "". - node.expression = parseUnaryExpressionOrHigher(); + expression = parseUnaryExpressionOrHigher(); } } - if (parseOptional(SyntaxKind.EqualsToken)) { - node.default = parseType(); - } - - return finishNode(node); + const defaultType = parseOptional(SyntaxKind.EqualsToken) ? parseType() : undefined; + const node = factory.createTypeParameterDeclaration(name, constraint, defaultType); + node.expression = expression; + return finishNode(node, pos); } function parseTypeParameters(): NodeArray | undefined { @@ -2685,14 +2719,6 @@ namespace ts { } } - function parseParameterType(): TypeNode | undefined { - if (parseOptional(SyntaxKind.ColonToken)) { - return parseType(); - } - - return undefined; - } - function isStartOfParameter(isJSDocParameter: boolean): boolean { return token() === SyntaxKind.DotDotDotToken || isIdentifierOrPrivateIdentifierOrPattern() || @@ -2701,22 +2727,11 @@ namespace ts { isStartOfType(/*inStartOfParameter*/ !isJSDocParameter); } - function parseParameter(): ParameterDeclaration { - const node = createNodeWithJSDoc(SyntaxKind.Parameter); - if (token() === SyntaxKind.ThisKeyword) { - node.name = createIdentifier(/*isIdentifier*/ true); - node.type = parseParameterType(); - return finishNode(node); - } - - node.decorators = parseDecorators(); - node.modifiers = parseModifiers(); - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - + function parseNameOfParameter(modifiers: ModifiersArray | undefined) { // FormalParameter [Yield,Await]: // BindingElement[?Yield,?Await] - node.name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_cannot_be_used_as_parameters); - if (getFullWidth(node.name) === 0 && !node.modifiers && isModifierKind(token())) { + const name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_cannot_be_used_as_parameters); + if (getFullWidth(name) === 0 && !some(modifiers) && isModifierKind(token())) { // in cases like // 'use strict' // function foo(static) @@ -2727,31 +2742,51 @@ namespace ts { // to avoid this we'll advance cursor to the next token. nextToken(); } + return name; + } - node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - node.type = parseParameterType(); - node.initializer = parseInitializer(); + function parseParameter(): ParameterDeclaration { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + if (token() === SyntaxKind.ThisKeyword) { + const node = factory.createParameterDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + createIdentifier(/*isIdentifier*/ true), + /*questionToken*/ undefined, + parseTypeAnnotation(), + /*initializer*/ undefined + ); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } - return finishNode(node); + // FormalParameter [Yield,Await]: + // BindingElement[?Yield,?Await] + let modifiers; + return withJSDoc( + finishNode( + factory.createParameterDeclaration( + parseDecorators(), + modifiers = parseModifiers(), + parseOptionalToken(SyntaxKind.DotDotDotToken), + parseNameOfParameter(modifiers), + parseOptionalToken(SyntaxKind.QuestionToken), + parseTypeAnnotation(), + parseInitializer() + ), + pos + ), + hasJSDoc + ); } - /** - * Note: If returnToken is EqualsGreaterThanToken, `signature.type` will always be defined. - * @returns If return type parsing succeeds - */ - function fillSignature( - returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, - flags: SignatureFlags, - signature: SignatureDeclaration): boolean { - if (!(flags & SignatureFlags.JSDoc)) { - signature.typeParameters = parseTypeParameters(); - } - const parametersParsedSuccessfully = parseParameterList(signature, flags); - if (shouldParseReturnType(returnToken, !!(flags & SignatureFlags.Type))) { - signature.type = parseTypeOrTypePredicate(); - if (typeHasArrowFunctionBlockingParseError(signature.type)) return false; + function parseReturnType(returnToken: SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode; + function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined; + function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean) { + if (shouldParseReturnType(returnToken, isType)) { + return parseTypeOrTypePredicate(); } - return parametersParsedSuccessfully; } function shouldParseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean { @@ -2771,8 +2806,7 @@ namespace ts { return false; } - // Returns true on success. - function parseParameterList(signature: SignatureDeclaration, flags: SignatureFlags): boolean { + function parseParametersWorker(flags: SignatureFlags) { // FormalParameters [Yield,Await]: (modified) // [empty] // FormalParameterList[?Yield,Await] @@ -2786,25 +2820,43 @@ namespace ts { // // SingleNameBinding [Yield,Await]: // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt - if (!parseExpected(SyntaxKind.OpenParenToken)) { - signature.parameters = createMissingList(); - return false; - } - const savedYieldContext = inYieldContext(); const savedAwaitContext = inAwaitContext(); setYieldContext(!!(flags & SignatureFlags.Yield)); setAwaitContext(!!(flags & SignatureFlags.Await)); - signature.parameters = flags & SignatureFlags.JSDoc ? + const parameters = flags & SignatureFlags.JSDoc ? parseDelimitedList(ParsingContext.JSDocParameters, parseJSDocParameter) : parseDelimitedList(ParsingContext.Parameters, parseParameter); setYieldContext(savedYieldContext); setAwaitContext(savedAwaitContext); - return parseExpected(SyntaxKind.CloseParenToken); + return parameters; + } + + function parseParameters(flags: SignatureFlags): NodeArray { + // FormalParameters [Yield,Await]: (modified) + // [empty] + // FormalParameterList[?Yield,Await] + // + // FormalParameter[Yield,Await]: (modified) + // BindingElement[?Yield,Await] + // + // BindingElement [Yield,Await]: (modified) + // SingleNameBinding[?Yield,?Await] + // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + // + // SingleNameBinding [Yield,Await]: + // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + if (!parseExpected(SyntaxKind.OpenParenToken)) { + return createMissingList(); + } + + const parameters = parseParametersWorker(flags); + parseExpected(SyntaxKind.CloseParenToken); + return parameters; } function parseTypeMemberSemicolon() { @@ -2819,13 +2871,20 @@ namespace ts { } function parseSignatureMember(kind: SyntaxKind.CallSignature | SyntaxKind.ConstructSignature): CallSignatureDeclaration | ConstructSignatureDeclaration { - const node = createNodeWithJSDoc(kind); + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); if (kind === SyntaxKind.ConstructSignature) { parseExpected(SyntaxKind.NewKeyword); } - fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type, node); + + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.Type); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ true); parseTypeMemberSemicolon(); - return finishNode(node); + const node = kind === SyntaxKind.CallSignature + ? factory.createCallSignature(typeParameters, parameters, type) + : factory.createConstructSignature(typeParameters, parameters, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function isIndexSignature(): boolean { @@ -2887,35 +2946,36 @@ namespace ts { return token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.CloseBracketToken; } - function parseIndexSignatureDeclaration(node: IndexSignatureDeclaration): IndexSignatureDeclaration { - node.kind = SyntaxKind.IndexSignature; - node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); - node.type = parseTypeAnnotation(); + function parseIndexSignatureDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): IndexSignatureDeclaration { + const parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); + const type = parseTypeAnnotation(); parseTypeMemberSemicolon(); - return finishNode(node); + const node = factory.createIndexSignature(decorators, modifiers, parameters, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parsePropertyOrMethodSignature(node: PropertySignature | MethodSignature): PropertySignature | MethodSignature { - node.name = parsePropertyName(); - node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + function parsePropertyOrMethodSignature(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): PropertySignature | MethodSignature { + const name = parsePropertyName(); + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + let node: PropertySignature | MethodSignature; if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - node.kind = SyntaxKind.MethodSignature; // Method signatures don't exist in expression contexts. So they have neither // [Yield] nor [Await] - fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type, node); + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.Type); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ true); + node = factory.createMethodSignature(modifiers, name, questionToken, typeParameters, parameters, type); } else { - node.kind = SyntaxKind.PropertySignature; - node.type = parseTypeAnnotation(); - if (token() === SyntaxKind.EqualsToken) { - // Although type literal properties cannot not have initializers, we attempt - // to parse an initializer so we can report in the checker that an interface - // property or type literal property cannot have an initializer. - (node).initializer = parseInitializer(); - } + const type = parseTypeAnnotation(); + node = factory.createPropertySignature(modifiers, name, questionToken, type); + // Although type literal properties cannot not have initializers, we attempt + // to parse an initializer so we can report in the checker that an interface + // property or type literal property cannot have an initializer. + if (token() === SyntaxKind.EqualsToken) node.initializer = parseInitializer(); } parseTypeMemberSemicolon(); - return finishNode(node); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function isTypeMemberStart(): boolean { @@ -2958,12 +3018,13 @@ namespace ts { if (token() === SyntaxKind.NewKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { return parseSignatureMember(SyntaxKind.ConstructSignature); } - const node = createNodeWithJSDoc(SyntaxKind.Unknown); - node.modifiers = parseModifiers(); + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiers(); if (isIndexSignature()) { - return parseIndexSignatureDeclaration(node); + return parseIndexSignatureDeclaration(pos, hasJSDoc, /*decorators*/ undefined, modifiers); } - return parsePropertyOrMethodSignature(node); + return parsePropertyOrMethodSignature(pos, hasJSDoc, modifiers); } function nextTokenIsOpenParenOrLessThan() { @@ -2986,9 +3047,8 @@ namespace ts { } function parseTypeLiteral(): TypeLiteralNode { - const node = createNode(SyntaxKind.TypeLiteral); - node.members = parseObjectTypeMembers(); - return finishNode(node); + const pos = getNodePos(); + return finishNode(factory.createTypeLiteralNode(parseObjectTypeMembers()), pos); } function parseObjectTypeMembers(): NodeArray { @@ -3016,47 +3076,50 @@ namespace ts { } function parseMappedTypeParameter() { - const node = createNode(SyntaxKind.TypeParameter); - node.name = parseIdentifier(); + const pos = getNodePos(); + const name = parseIdentifierName(); parseExpected(SyntaxKind.InKeyword); - node.constraint = parseType(); - return finishNode(node); + const type = parseType(); + return finishNode(factory.createTypeParameterDeclaration(name, type, /*defaultType*/ undefined), pos); } function parseMappedType() { - const node = createNode(SyntaxKind.MappedType); + const pos = getNodePos(); parseExpected(SyntaxKind.OpenBraceToken); + let readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined; if (token() === SyntaxKind.ReadonlyKeyword || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - node.readonlyToken = parseTokenNode(); - if (node.readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { - parseExpectedToken(SyntaxKind.ReadonlyKeyword); + readonlyToken = parseTokenNode(); + if (readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { + parseExpected(SyntaxKind.ReadonlyKeyword); } } parseExpected(SyntaxKind.OpenBracketToken); - node.typeParameter = parseMappedTypeParameter(); + const typeParameter = parseMappedTypeParameter(); parseExpected(SyntaxKind.CloseBracketToken); + let questionToken: QuestionToken | PlusToken | MinusToken | undefined; if (token() === SyntaxKind.QuestionToken || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - node.questionToken = parseTokenNode(); - if (node.questionToken.kind !== SyntaxKind.QuestionToken) { - parseExpectedToken(SyntaxKind.QuestionToken); + questionToken = parseTokenNode(); + if (questionToken.kind !== SyntaxKind.QuestionToken) { + parseExpected(SyntaxKind.QuestionToken); } } - node.type = parseTypeAnnotation(); + const type = parseTypeAnnotation(); parseSemicolon(); parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(node); + return finishNode(factory.createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), pos); } function parseTupleElementType() { const pos = getNodePos(); if (parseOptional(SyntaxKind.DotDotDotToken)) { - const node = createNode(SyntaxKind.RestType, pos); - node.type = parseType(); - return finishNode(node); + return finishNode(factory.createRestTypeNode(parseType()), pos); } const type = parseType(); - if (!(contextFlags & NodeFlags.JSDoc) && type.kind === SyntaxKind.JSDocNullableType && type.pos === (type).type.pos) { - type.kind = SyntaxKind.OptionalType; + if (!(contextFlags & NodeFlags.JSDoc) && isJSDocNullableType(type) && type.pos === type.type.pos) { + const node = factory.createOptionalTypeNode(type.type); + setTextRange(node, type); + (node as Mutable).flags = type.flags; + return node; } return type; } @@ -3074,37 +3137,48 @@ namespace ts { function parseTupleElementNameOrTupleElementType() { if (lookAhead(isTupleElementName)) { - const node = createNode(SyntaxKind.NamedTupleMember); - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - node.name = parseIdentifierName(); - node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const name = parseIdentifierName(); + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); parseExpected(SyntaxKind.ColonToken); - node.type = parseTupleElementType(); - return addJSDocComment(finishNode(node)); + const type = parseTupleElementType(); + const node = factory.createNamedTupleMember(dotDotDotToken, name, questionToken, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); } return parseTupleElementType(); } function parseTupleType(): TupleTypeNode { - const node = createNode(SyntaxKind.TupleType); - node.elements = parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); - return finishNode(node); + const pos = getNodePos(); + return finishNode( + factory.createTupleTypeNode( + parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken) + ), + pos + ); } function parseParenthesizedType(): TypeNode { - const node = createNode(SyntaxKind.ParenthesizedType); + const pos = getNodePos(); parseExpected(SyntaxKind.OpenParenToken); - node.type = parseType(); + const type = parseType(); parseExpected(SyntaxKind.CloseParenToken); - return finishNode(node); + return finishNode(factory.createParenthesizedType(type), pos); } function parseFunctionOrConstructorType(): TypeNode { const pos = getNodePos(); - const kind = parseOptional(SyntaxKind.NewKeyword) ? SyntaxKind.ConstructorType : SyntaxKind.FunctionType; - const node = createNodeWithJSDoc(kind, pos); - fillSignature(SyntaxKind.EqualsGreaterThanToken, SignatureFlags.Type, node); - return finishNode(node); + const hasJSDoc = hasPrecedingJSDocComment(); + const isConstructorType = parseOptional(SyntaxKind.NewKeyword); + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.Type); + const type = parseReturnType(SyntaxKind.EqualsGreaterThanToken, /*isType*/ false); + const node = isConstructorType + ? factory.createConstructorTypeNode(typeParameters, parameters, type) + : factory.createFunctionTypeNode(typeParameters, parameters, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function parseKeywordAndNoDot(): TypeNode | undefined { @@ -3113,23 +3187,18 @@ namespace ts { } function parseLiteralTypeNode(negative?: boolean): LiteralTypeNode { - const node = createNode(SyntaxKind.LiteralType) as LiteralTypeNode; - let unaryMinusExpression!: PrefixUnaryExpression; + const pos = getNodePos(); if (negative) { - unaryMinusExpression = createNode(SyntaxKind.PrefixUnaryExpression) as PrefixUnaryExpression; - unaryMinusExpression.operator = SyntaxKind.MinusToken; nextToken(); } - let expression: BooleanLiteral | LiteralExpression | PrefixUnaryExpression = token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword - ? parseTokenNode() - : parseLiteralLikeNode(token()) as LiteralExpression; + let expression: BooleanLiteral | NullLiteral | LiteralExpression | PrefixUnaryExpression = + token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword || token() === SyntaxKind.NullKeyword ? + parseTokenNode() : + parseLiteralLikeNode(token()) as LiteralExpression; if (negative) { - unaryMinusExpression.operand = expression; - finishNode(unaryMinusExpression); - expression = unaryMinusExpression; + expression = finishNode(factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, expression), pos); } - node.literal = expression; - return finishNode(node); + return finishNode(factory.createLiteralTypeNode(expression), pos); } function isStartOfTypeOfImportType() { @@ -3138,22 +3207,16 @@ namespace ts { } function parseImportType(): ImportTypeNode { - sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport; - const node = createNode(SyntaxKind.ImportType) as ImportTypeNode; - if (parseOptional(SyntaxKind.TypeOfKeyword)) { - node.isTypeOf = true; - } + sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; + const pos = getNodePos(); + const isTypeOf = parseOptional(SyntaxKind.TypeOfKeyword); parseExpected(SyntaxKind.ImportKeyword); parseExpected(SyntaxKind.OpenParenToken); - node.argument = parseType(); + const type = parseType(); parseExpected(SyntaxKind.CloseParenToken); - if (parseOptional(SyntaxKind.DotToken)) { - node.qualifier = parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); - } - if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) { - node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); - } - return finishNode(node); + const qualifier = parseOptional(SyntaxKind.DotToken) ? parseEntityNameOfTypeReference() : undefined; + const typeArguments = parseTypeArgumentsOfTypeReference(); + return finishNode(factory.createImportTypeNode(type, qualifier, typeArguments, isTypeOf), pos); } function nextTokenIsNumericOrBigIntLiteral() { @@ -3195,11 +3258,11 @@ namespace ts { case SyntaxKind.BigIntLiteral: case SyntaxKind.TrueKeyword: case SyntaxKind.FalseKeyword: + case SyntaxKind.NullKeyword: return parseLiteralTypeNode(); case SyntaxKind.MinusToken: return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference(); case SyntaxKind.VoidKeyword: - case SyntaxKind.NullKeyword: return parseTokenNode(); case SyntaxKind.ThisKeyword: { const thisKeyword = parseThisTypeNode(); @@ -3283,33 +3346,32 @@ namespace ts { } function parsePostfixTypeOrHigher(): TypeNode { + const pos = getNodePos(); let type = parseNonArrayType(); while (!scanner.hasPrecedingLineBreak()) { switch (token()) { case SyntaxKind.ExclamationToken: - type = createPostfixType(SyntaxKind.JSDocNonNullableType, type); + nextToken(); + type = finishNode(factory.createJSDocNonNullableType(type), pos); break; case SyntaxKind.QuestionToken: // If not in JSDoc and next token is start of a type we have a conditional type if (!(contextFlags & NodeFlags.JSDoc) && lookAhead(nextTokenIsStartOfType)) { return type; } - type = createPostfixType(SyntaxKind.JSDocNullableType, type); + nextToken(); + type = finishNode(factory.createJSDocNullableType(type), pos); break; case SyntaxKind.OpenBracketToken: parseExpected(SyntaxKind.OpenBracketToken); if (isStartOfType()) { - const node = createNode(SyntaxKind.IndexedAccessType, type.pos) as IndexedAccessTypeNode; - node.objectType = type; - node.indexType = parseType(); + const indexType = parseType(); parseExpected(SyntaxKind.CloseBracketToken); - type = finishNode(node); + type = finishNode(factory.createIndexedAccessTypeNode(type, indexType), pos); } else { - const node = createNode(SyntaxKind.ArrayType, type.pos) as ArrayTypeNode; - node.elementType = type; parseExpected(SyntaxKind.CloseBracketToken); - type = finishNode(node); + type = finishNode(factory.createArrayTypeNode(type), pos); } break; default: @@ -3319,28 +3381,28 @@ namespace ts { return type; } - function createPostfixType(kind: SyntaxKind, type: TypeNode) { - nextToken(); - const postfix = createNode(kind, type.pos) as OptionalTypeNode | JSDocOptionalType | JSDocNonNullableType | JSDocNullableType; - postfix.type = type; - return finishNode(postfix); - } - function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword) { - const node = createNode(SyntaxKind.TypeOperator); + const pos = getNodePos(); parseExpected(operator); - node.operator = operator; - node.type = parseTypeOperatorOrHigher(); - return finishNode(node); + return finishNode(factory.createTypeOperatorNode(operator, parseTypeOperatorOrHigher()), pos); + } + + function parseTypeParameterOfInferType() { + const pos = getNodePos(); + return finishNode( + factory.createTypeParameterDeclaration( + parseIdentifier(), + /*constraint*/ undefined, + /*defaultType*/ undefined + ), + pos + ); } function parseInferType(): InferTypeNode { - const node = createNode(SyntaxKind.InferType); + const pos = getNodePos(); parseExpected(SyntaxKind.InferKeyword); - const typeParameter = createNode(SyntaxKind.TypeParameter); - typeParameter.name = parseIdentifier(); - node.typeParameter = finishNode(typeParameter); - return finishNode(node); + return finishNode(factory.createInferTypeNode(parseTypeParameterOfInferType()), pos); } function parseTypeOperatorOrHigher(): TypeNode { @@ -3356,8 +3418,12 @@ namespace ts { return parsePostfixTypeOrHigher(); } - function parseUnionOrIntersectionType(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, parseConstituentType: () => TypeNode, operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken): TypeNode { - const start = scanner.getStartPos(); + function parseUnionOrIntersectionType( + operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken, + parseConstituentType: () => TypeNode, + createTypeNode: (types: NodeArray) => UnionOrIntersectionTypeNode + ): TypeNode { + const pos = getNodePos(); const hasLeadingOperator = parseOptional(operator); let type = parseConstituentType(); if (token() === operator || hasLeadingOperator) { @@ -3365,19 +3431,17 @@ namespace ts { while (parseOptional(operator)) { types.push(parseConstituentType()); } - const node = createNode(kind, start); - node.types = createNodeArray(types, start); - type = finishNode(node); + type = finishNode(createTypeNode(createNodeArray(types, pos)), pos); } return type; } function parseIntersectionTypeOrHigher(): TypeNode { - return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseTypeOperatorOrHigher, SyntaxKind.AmpersandToken); + return parseUnionOrIntersectionType(SyntaxKind.AmpersandToken, parseTypeOperatorOrHigher, factory.createIntersectionTypeNode); } function parseUnionTypeOrHigher(): TypeNode { - return parseUnionOrIntersectionType(SyntaxKind.UnionType, parseIntersectionTypeOrHigher, SyntaxKind.BarToken); + return parseUnionOrIntersectionType(SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode); } function isStartOfFunctionType(): boolean { @@ -3435,14 +3499,11 @@ namespace ts { } function parseTypeOrTypePredicate(): TypeNode { + const pos = getNodePos(); const typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix); const type = parseType(); if (typePredicateVariable) { - const node = createNode(SyntaxKind.TypePredicate, typePredicateVariable.pos); - node.assertsModifier = undefined; - node.parameterName = typePredicateVariable; - node.type = type; - return finishNode(node); + return finishNode(factory.createTypePredicateNode(/*assertsModifier*/ undefined, typePredicateVariable, type), pos); } else { return type; @@ -3458,11 +3519,11 @@ namespace ts { } function parseAssertsTypePredicate(): TypeNode { - const node = createNode(SyntaxKind.TypePredicate); - node.assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword); - node.parameterName = token() === SyntaxKind.ThisKeyword ? parseThisTypeNode() : parseIdentifier(); - node.type = parseOptional(SyntaxKind.IsKeyword) ? parseType() : undefined; - return finishNode(node); + const pos = getNodePos(); + const assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword); + const parameterName = token() === SyntaxKind.ThisKeyword ? parseThisTypeNode() : parseIdentifier(); + const type = parseOptional(SyntaxKind.IsKeyword) ? parseType() : undefined; + return finishNode(factory.createTypePredicateNode(assertsModifier, parameterName, type), pos); } function parseType(): TypeNode { @@ -3475,17 +3536,16 @@ namespace ts { if (isStartOfFunctionType() || token() === SyntaxKind.NewKeyword) { return parseFunctionOrConstructorType(); } + const pos = getNodePos(); const type = parseUnionTypeOrHigher(); if (!noConditionalTypes && !scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.ExtendsKeyword)) { - const node = createNode(SyntaxKind.ConditionalType, type.pos); - node.checkType = type; // The type following 'extends' is not permitted to be another conditional type - node.extendsType = parseTypeWorker(/*noConditionalTypes*/ true); + const extendsType = parseTypeWorker(/*noConditionalTypes*/ true); parseExpected(SyntaxKind.QuestionToken); - node.trueType = parseTypeWorker(); + const trueType = parseTypeWorker(); parseExpected(SyntaxKind.ColonToken); - node.falseType = parseTypeWorker(); - return finishNode(node); + const falseType = parseTypeWorker(); + return finishNode(factory.createConditionalTypeNode(type, extendsType, trueType, falseType), pos); } return type; } @@ -3580,10 +3640,11 @@ namespace ts { setDecoratorContext(/*val*/ false); } + const pos = getNodePos(); let expr = parseAssignmentExpressionOrHigher(); let operatorToken: BinaryOperatorToken; while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) { - expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher()); + expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher(), pos); } if (saveDecoratorContext) { @@ -3638,13 +3699,14 @@ namespace ts { // Otherwise, we try to parse out the conditional expression bit. We want to allow any // binary expression here, so we pass in the 'lowest' precedence here so that it matches // and consumes anything. - const expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); + const pos = getNodePos(); + const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single // identifier and the current token is an arrow. if (expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { - return parseSimpleArrowFunctionExpression(expr); + return parseSimpleArrowFunctionExpression(pos, expr, /*asyncModifier*/ undefined); } // Now see if we might be in cases '2' or '3'. @@ -3654,11 +3716,11 @@ namespace ts { // Note: we call reScanGreaterToken so that we get an appropriately merged token // for cases like `> > =` becoming `>>=` if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { - return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); + return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher(), pos); } // It wasn't an assignment or a lambda. This is a conditional expression: - return parseConditionalExpressionRest(expr); + return parseConditionalExpressionRest(expr, pos); } function isYieldExpression(): boolean { @@ -3695,7 +3757,7 @@ namespace ts { } function parseYieldExpression(): YieldExpression { - const node = createNode(SyntaxKind.YieldExpression); + const pos = getNodePos(); // YieldExpression[In] : // yield @@ -3705,39 +3767,41 @@ namespace ts { if (!scanner.hasPrecedingLineBreak() && (token() === SyntaxKind.AsteriskToken || isStartOfExpression())) { - node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - node.expression = parseAssignmentExpressionOrHigher(); - return finishNode(node); + return finishNode( + factory.createYieldExpression( + parseOptionalToken(SyntaxKind.AsteriskToken), + parseAssignmentExpressionOrHigher() + ), + pos + ); } else { // if the next token is not on the same line as yield. or we don't have an '*' or // the start of an expression, then this is just a simple "yield" expression. - return finishNode(node); + return finishNode(factory.createYieldExpression(/*asteriskToken*/ undefined, /*expression*/ undefined), pos); } } - function parseSimpleArrowFunctionExpression(identifier: Identifier, asyncModifier?: NodeArray | undefined): ArrowFunction { + function parseSimpleArrowFunctionExpression(pos: number, identifier: Identifier, asyncModifier?: NodeArray | undefined): ArrowFunction { Debug.assert(token() === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); - let node: ArrowFunction; - if (asyncModifier) { - node = createNode(SyntaxKind.ArrowFunction, asyncModifier.pos); - node.modifiers = asyncModifier; - } - else { - node = createNode(SyntaxKind.ArrowFunction, identifier.pos); - } - - const parameter = createNode(SyntaxKind.Parameter, identifier.pos); - parameter.name = identifier; - finishNode(parameter); - - node.parameters = createNodeArray([parameter], parameter.pos, parameter.end); + const parameter = factory.createParameterDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + identifier, + /*questionToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + ); + finishNode(parameter, identifier.pos); - node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); - node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier); + const parameters = createNodeArray([parameter], parameter.pos, parameter.end); + const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); + const body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier); + const node = factory.createArrowFunction(asyncModifier, /*typeParameters*/ undefined, parameters, /*type*/ undefined, equalsGreaterThanToken, body); - return addJSDocComment(finishNode(node)); + return addJSDocComment(finishNode(node, pos)); } function tryParseParenthesizedArrowFunctionExpression(): Expression | undefined { @@ -3751,26 +3815,9 @@ namespace ts { // following => or { token. Otherwise, we *might* have an arrow function. Try to parse // it out, but don't allow any ambiguity, and return 'undefined' if this could be an // expression instead. - const arrowFunction = triState === Tristate.True - ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true) - : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead); - - if (!arrowFunction) { - // Didn't appear to actually be a parenthesized arrow function. Just bail out. - return undefined; - } - - const isAsync = hasModifierOfKind(arrowFunction, SyntaxKind.AsyncKeyword); - - // If we have an arrow, then try to parse the body. Even if not, try to parse if we - // have an opening brace, just in case we're in an error state. - const lastToken = token(); - arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); - arrowFunction.body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken) - ? parseArrowFunctionExpressionBody(isAsync) - : parseIdentifier(); - - return finishNode(arrowFunction); + return triState === Tristate.True ? + parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true) : + tryParse(parsePossibleParenthesizedArrowFunctionExpression); } // True -> We definitely expect a parenthesized arrow function here. @@ -3885,7 +3932,7 @@ namespace ts { } // JSX overrides - if (sourceFile.languageVariant === LanguageVariant.JSX) { + if (languageVariant === LanguageVariant.JSX) { const isArrowFunctionInJsx = lookAhead(() => { const third = nextToken(); if (third === SyntaxKind.ExtendsKeyword) { @@ -3916,13 +3963,13 @@ namespace ts { } } - function parsePossibleParenthesizedArrowFunctionExpressionHead(): ArrowFunction | undefined { + function parsePossibleParenthesizedArrowFunctionExpression(): ArrowFunction | undefined { const tokenPos = scanner.getTokenPos(); if (notParenthesizedArrow && notParenthesizedArrow.has(tokenPos.toString())) { return undefined; } - const result = parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false); + const result = parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ false); if (!result) { (notParenthesizedArrow || (notParenthesizedArrow = createMap())).set(tokenPos.toString(), true); } @@ -3934,9 +3981,10 @@ namespace ts { // We do a check here so that we won't be doing unnecessarily call to "lookAhead" if (token() === SyntaxKind.AsyncKeyword) { if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === Tristate.True) { + const pos = getNodePos(); const asyncModifier = parseModifiersForArrowFunction(); - const expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); - return parseSimpleArrowFunctionExpression(expr, asyncModifier); + const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); + return parseSimpleArrowFunctionExpression(pos, expr, asyncModifier); } } return undefined; @@ -3954,7 +4002,7 @@ namespace ts { return Tristate.False; } // Check for un-parenthesized AsyncArrowFunction - const expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); + const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); if (!scanner.hasPrecedingLineBreak() && expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { return Tristate.True; } @@ -3963,10 +4011,11 @@ namespace ts { return Tristate.False; } - function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction | undefined { - const node = createNodeWithJSDoc(SyntaxKind.ArrowFunction); - node.modifiers = parseModifiersForArrowFunction(); - const isAsync = hasModifierOfKind(node, SyntaxKind.AsyncKeyword) ? SignatureFlags.Await : SignatureFlags.None; + function parseParenthesizedArrowFunctionExpression(allowAmbiguity: boolean): ArrowFunction | undefined { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiersForArrowFunction(); + const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; // Arrow functions are never generators. // // If we're speculatively parsing a signature for a parenthesized arrow function, then @@ -3974,7 +4023,24 @@ namespace ts { // a => (b => c) // And think that "(b =>" was actually a parenthesized arrow function with a missing // close paren. - if (!fillSignature(SyntaxKind.ColonToken, isAsync, node) && !allowAmbiguity) { + const typeParameters = parseTypeParameters(); + + let parameters: NodeArray; + if (!parseExpected(SyntaxKind.OpenParenToken)) { + if (!allowAmbiguity) { + return undefined; + } + parameters = createMissingList(); + } + else { + parameters = parseParametersWorker(isAsync); + if (!parseExpected(SyntaxKind.CloseParenToken) && !allowAmbiguity) { + return undefined; + } + } + + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) { return undefined; } @@ -3987,13 +4053,22 @@ namespace ts { // - "a ? (b): function() {}" will too, since function() is a valid JSDoc function type. // // So we need just a bit of lookahead to ensure that it can only be a signature. - const hasJSDocFunctionType = node.type && isJSDocFunctionType(node.type); + const hasJSDocFunctionType = type && isJSDocFunctionType(type); if (!allowAmbiguity && token() !== SyntaxKind.EqualsGreaterThanToken && (hasJSDocFunctionType || token() !== SyntaxKind.OpenBraceToken)) { // Returning undefined here will cause our caller to rewind to where we started from. return undefined; } - return node; + // If we have an arrow, then try to parse the body. Even if not, try to parse if we + // have an opening brace, just in case we're in an error state. + const lastToken = token(); + const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); + const body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken) + ? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier)) + : parseIdentifier(); + + const node = factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function parseArrowFunctionExpressionBody(isAsync: boolean): Block | Expression { @@ -4028,7 +4103,7 @@ namespace ts { : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher); } - function parseConditionalExpressionRest(leftOperand: Expression): Expression { + function parseConditionalExpressionRest(leftOperand: Expression, pos: number): Expression { // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); if (!questionToken) { @@ -4037,27 +4112,32 @@ namespace ts { // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and // we do not that for the 'whenFalse' part. - const node = createNode(SyntaxKind.ConditionalExpression, leftOperand.pos); - node.condition = leftOperand; - node.questionToken = questionToken; - node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher); - node.colonToken = parseExpectedToken(SyntaxKind.ColonToken); - node.whenFalse = nodeIsPresent(node.colonToken) - ? parseAssignmentExpressionOrHigher() - : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); - return finishNode(node); + let colonToken; + return finishNode( + factory.createConditionalExpression( + leftOperand, + questionToken, + doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher), + colonToken = parseExpectedToken(SyntaxKind.ColonToken), + nodeIsPresent(colonToken) + ? parseAssignmentExpressionOrHigher() + : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)) + ), + pos + ); } - function parseBinaryExpressionOrHigher(precedence: number): Expression { + function parseBinaryExpressionOrHigher(precedence: OperatorPrecedence): Expression { + const pos = getNodePos(); const leftOperand = parseUnaryExpressionOrHigher(); - return parseBinaryExpressionRest(precedence, leftOperand); + return parseBinaryExpressionRest(precedence, leftOperand, pos); } function isInOrOfKeyword(t: SyntaxKind) { return t === SyntaxKind.InKeyword || t === SyntaxKind.OfKeyword; } - function parseBinaryExpressionRest(precedence: number, leftOperand: Expression): Expression { + function parseBinaryExpressionRest(precedence: OperatorPrecedence, leftOperand: Expression, pos: number): Expression { while (true) { // We either have a binary operator here, or we're finished. We call // reScanGreaterToken so that we merge token sequences like > and = into >= @@ -4113,7 +4193,7 @@ namespace ts { } } else { - leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); + leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence), pos); } } @@ -4128,49 +4208,32 @@ namespace ts { return getBinaryOperatorPrecedence(token()) > 0; } - function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression): BinaryExpression { - const node = createNode(SyntaxKind.BinaryExpression, left.pos); - node.left = left; - node.operatorToken = operatorToken; - node.right = right; - return finishNode(node); + function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression, pos: number): BinaryExpression { + return finishNode(factory.createBinaryExpression(left, operatorToken, right), pos); } function makeAsExpression(left: Expression, right: TypeNode): AsExpression { - const node = createNode(SyntaxKind.AsExpression, left.pos); - node.expression = left; - node.type = right; - return finishNode(node); + return finishNode(factory.createAsExpression(left, right), left.pos); } function parsePrefixUnaryExpression() { - const node = createNode(SyntaxKind.PrefixUnaryExpression); - node.operator = token(); - nextToken(); - node.operand = parseSimpleUnaryExpression(); - - return finishNode(node); + const pos = getNodePos(); + return finishNode(factory.createPrefixUnaryExpression(token(), nextTokenAnd(parseSimpleUnaryExpression)), pos); } function parseDeleteExpression() { - const node = createNode(SyntaxKind.DeleteExpression); - nextToken(); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); + const pos = getNodePos(); + return finishNode(factory.createDeleteExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); } function parseTypeOfExpression() { - const node = createNode(SyntaxKind.TypeOfExpression); - nextToken(); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); + const pos = getNodePos(); + return finishNode(factory.createTypeOfExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); } function parseVoidExpression() { - const node = createNode(SyntaxKind.VoidExpression); - nextToken(); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); + const pos = getNodePos(); + return finishNode(factory.createVoidExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); } function isAwaitExpression(): boolean { @@ -4187,10 +4250,8 @@ namespace ts { } function parseAwaitExpression() { - const node = createNode(SyntaxKind.AwaitExpression); - nextToken(); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); + const pos = getNodePos(); + return finishNode(factory.createAwaitExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); } /** @@ -4211,9 +4272,10 @@ namespace ts { * 5) --UnaryExpression[?Yield] */ if (isUpdateExpression()) { + const pos = getNodePos(); const updateExpression = parseUpdateExpression(); return token() === SyntaxKind.AsteriskAsteriskToken ? - parseBinaryExpressionRest(getBinaryOperatorPrecedence(token()), updateExpression) : + parseBinaryExpressionRest(getBinaryOperatorPrecedence(token()), updateExpression, pos) : updateExpression; } @@ -4310,7 +4372,7 @@ namespace ts { return false; case SyntaxKind.LessThanToken: // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression - if (sourceFile.languageVariant !== LanguageVariant.JSX) { + if (languageVariant !== LanguageVariant.JSX) { return false; } // We are in JSX context and the token is part of JSXElement. @@ -4333,13 +4395,10 @@ namespace ts { */ function parseUpdateExpression(): UpdateExpression { if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) { - const node = createNode(SyntaxKind.PrefixUnaryExpression); - node.operator = token(); - nextToken(); - node.operand = parseLeftHandSideExpressionOrHigher(); - return finishNode(node); + const pos = getNodePos(); + return finishNode(factory.createPrefixUnaryExpression(token(), nextTokenAnd(parseLeftHandSideExpressionOrHigher)), pos); } - else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { + else if (languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { // JSXElement is part of primaryExpression return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); } @@ -4348,11 +4407,9 @@ namespace ts { Debug.assert(isLeftHandSideExpression(expression)); if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) { - const node = createNode(SyntaxKind.PostfixUnaryExpression, expression.pos); - node.operand = expression; - node.operator = token(); + const operator = token(); nextToken(); - return finishNode(node); + return finishNode(factory.createPostfixUnaryExpression(expression, operator), expression.pos); } return expression; @@ -4390,6 +4447,7 @@ namespace ts { // the last two CallExpression productions. 2) We see 'import' which must start import call. // 3)we have a MemberExpression which either completes the LeftHandSideExpression, // or starts the beginning of the first four CallExpression productions. + const pos = getNodePos(); let expression: MemberExpression; if (token() === SyntaxKind.ImportKeyword) { if (lookAhead(nextTokenIsOpenParenOrLessThan)) { @@ -4398,20 +4456,15 @@ namespace ts { // var foo3 = require("subfolder // import * as foo1 from "module-from-node // We want this import to be a statement rather than import call expression - sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport; + sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; expression = parseTokenNode(); } else if (lookAhead(nextTokenIsDot)) { // This is an 'import.*' metaproperty (i.e. 'import.meta') - const fullStart = scanner.getStartPos(); nextToken(); // advance past the 'import' nextToken(); // advance past the dot - const node = createNode(SyntaxKind.MetaProperty, fullStart) as MetaProperty; - node.keywordToken = SyntaxKind.ImportKeyword; - node.name = parseIdentifierName(); - expression = finishNode(node); - - sourceFile.flags |= NodeFlags.PossiblyContainsImportMeta; + expression = finishNode(factory.createMetaProperty(SyntaxKind.ImportKeyword, parseIdentifierName()), pos); + sourceFlags |= NodeFlags.PossiblyContainsImportMeta; } else { expression = parseMemberExpressionOrHigher(); @@ -4424,7 +4477,7 @@ namespace ts { // Now, we *may* be complete. However, we might have consumed the start of a // CallExpression or OptionalExpression. As such, we need to consume the rest // of it here to be complete. - return parseCallExpressionRest(expression); + return parseCallExpressionRest(pos, expression); } function parseMemberExpressionOrHigher(): MemberExpression { @@ -4475,11 +4528,13 @@ namespace ts { // // Because CallExpression and MemberExpression are left recursive, we need to bottom out // of the recursion immediately. So we parse out a primary expression to start with. + const pos = getNodePos(); const expression = parsePrimaryExpression(); - return parseMemberExpressionRest(expression, /*allowOptionalChain*/ true); + return parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); } function parseSuperExpression(): MemberExpression { + const pos = getNodePos(); const expression = parseTokenNode(); if (token() === SyntaxKind.LessThanToken) { const startPos = getNodePos(); @@ -4495,37 +4550,27 @@ namespace ts { // If we have seen "super" it must be followed by '(' or '.'. // If it wasn't then just try to parse out a '.' and report an error. - const node = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); - node.expression = expression; parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic - node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true); - return finishNode(node); + return finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true)), pos); } function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number): JsxElement | JsxSelfClosingElement | JsxFragment { + const pos = getNodePos(); const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); let result: JsxElement | JsxSelfClosingElement | JsxFragment; if (opening.kind === SyntaxKind.JsxOpeningElement) { - const node = createNode(SyntaxKind.JsxElement, opening.pos); - node.openingElement = opening; + const children = parseJsxChildren(opening); + const closingElement = parseJsxClosingElement(inExpressionContext); - node.children = parseJsxChildren(node.openingElement); - node.closingElement = parseJsxClosingElement(inExpressionContext); - - if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) { - parseErrorAtRange(node.closingElement, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, node.openingElement.tagName)); + if (!tagNamesAreEquivalent(opening.tagName, closingElement.tagName)) { + parseErrorAtRange(closingElement, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, opening.tagName)); } - result = finishNode(node); + result = finishNode(factory.createJsxElement(opening, children, closingElement), pos); } else if (opening.kind === SyntaxKind.JsxOpeningFragment) { - const node = createNode(SyntaxKind.JsxFragment, opening.pos); - node.openingFragment = opening; - node.children = parseJsxChildren(node.openingFragment); - node.closingFragment = parseJsxClosingFragment(inExpressionContext); - - result = finishNode(node); + result = finishNode(factory.createJsxFragment(opening, parseJsxChildren(opening), parseJsxClosingFragment(inExpressionContext)), pos); } else { Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement); @@ -4544,14 +4589,10 @@ namespace ts { const topBadPos = typeof topInvalidNodePosition === "undefined" ? result.pos : topInvalidNodePosition; const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true, topBadPos)); if (invalidElement) { - const badNode = createNode(SyntaxKind.BinaryExpression, result.pos); - badNode.end = invalidElement.end; - badNode.left = result; - badNode.right = invalidElement; - badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false); - badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos; + const operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false); + setTextRangePosWidth(operatorToken, invalidElement.pos, 0); parseErrorAt(skipTrivia(sourceText, topBadPos), invalidElement.end, Diagnostics.JSX_expressions_must_have_one_parent_element); - return badNode; + return finishNode(factory.createBinaryExpression(result, operatorToken as Token, invalidElement), pos); } } @@ -4559,11 +4600,10 @@ namespace ts { } function parseJsxText(): JsxText { - const node = createNode(SyntaxKind.JsxText); - node.text = scanner.getTokenValue(); - node.containsOnlyTriviaWhiteSpaces = currentToken === SyntaxKind.JsxTextAllWhiteSpaces; + const pos = getNodePos(); + const node = factory.createJsxText(scanner.getTokenValue(), currentToken === SyntaxKind.JsxTextAllWhiteSpaces); currentToken = scanner.scanJsxToken(); - return finishNode(node); + return finishNode(node, pos); } function parseJsxChild(openingTag: JsxOpeningElement | JsxOpeningFragment, token: JsxTokenSyntaxKind): JsxChild | undefined { @@ -4614,21 +4654,19 @@ namespace ts { } function parseJsxAttributes(): JsxAttributes { - const jsxAttributes = createNode(SyntaxKind.JsxAttributes); - jsxAttributes.properties = parseList(ParsingContext.JsxAttributes, parseJsxAttribute); - return finishNode(jsxAttributes); + const pos = getNodePos(); + return finishNode(factory.createJsxAttributes(parseList(ParsingContext.JsxAttributes, parseJsxAttribute)), pos); } function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment { - const fullStart = scanner.getStartPos(); + const pos = getNodePos(); parseExpected(SyntaxKind.LessThanToken); if (token() === SyntaxKind.GreaterThanToken) { // See below for explanation of scanJsxText - const node: JsxOpeningFragment = createNode(SyntaxKind.JsxOpeningFragment, fullStart); scanJsxText(); - return finishNode(node); + return finishNode(factory.createJsxOpeningFragment(), pos); } const tagName = parseJsxElementName(); @@ -4641,8 +4679,8 @@ namespace ts { // Closing tag, so scan the immediately-following text with the JSX scanning instead // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate // scanning errors - node = createNode(SyntaxKind.JsxOpeningElement, fullStart); scanJsxText(); + node = factory.createJsxOpeningElement(tagName, typeArguments, attributes); } else { parseExpected(SyntaxKind.SlashToken); @@ -4653,17 +4691,14 @@ namespace ts { parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); scanJsxText(); } - node = createNode(SyntaxKind.JsxSelfClosingElement, fullStart); + node = factory.createJsxSelfClosingElement(tagName, typeArguments, attributes); } - node.tagName = tagName; - node.typeArguments = typeArguments; - node.attributes = attributes; - - return finishNode(node); + return finishNode(node, pos); } function parseJsxElementName(): JsxTagNameExpression { + const pos = getNodePos(); scanJsxIdentifier(); // JsxElement can have name in the form of // propertyAccessExpression @@ -4673,27 +4708,25 @@ namespace ts { let expression: JsxTagNameExpression = token() === SyntaxKind.ThisKeyword ? parseTokenNode() : parseIdentifierName(); while (parseOptional(SyntaxKind.DotToken)) { - const propertyAccess: JsxTagNamePropertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); - propertyAccess.expression = expression; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false); - expression = finishNode(propertyAccess); + expression = finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false)), pos) as JsxTagNamePropertyAccess; } return expression; } function parseJsxExpression(inExpressionContext: boolean): JsxExpression | undefined { - const node = createNode(SyntaxKind.JsxExpression); - + const pos = getNodePos(); if (!parseExpected(SyntaxKind.OpenBraceToken)) { return undefined; } + let dotDotDotToken: DotDotDotToken | undefined; + let expression: Expression | undefined; if (token() !== SyntaxKind.CloseBraceToken) { - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); // Only an AssignmentExpression is valid here per the JSX spec, // but we can unambiguously parse a comma sequence and provide // a better error message in grammar checking. - node.expression = parseExpression(); + expression = parseExpression(); } if (inExpressionContext) { parseExpected(SyntaxKind.CloseBraceToken); @@ -4704,7 +4737,7 @@ namespace ts { } } - return finishNode(node); + return finishNode(factory.createJsxExpression(dotDotDotToken, expression), pos); } function parseJsxAttribute(): JsxAttribute | JsxSpreadAttribute { @@ -4713,34 +4746,31 @@ namespace ts { } scanJsxIdentifier(); - const node = createNode(SyntaxKind.JsxAttribute); - node.name = parseIdentifierName(); - if (token() === SyntaxKind.EqualsToken) { - switch (scanJsxAttributeValue()) { - case SyntaxKind.StringLiteral: - node.initializer = parseLiteralNode(); - break; - default: - node.initializer = parseJsxExpression(/*inExpressionContext*/ true); - break; - } - } - return finishNode(node); + const pos = getNodePos(); + return finishNode( + factory.createJsxAttribute( + parseIdentifierName(), + token() !== SyntaxKind.EqualsToken ? undefined : + scanJsxAttributeValue() === SyntaxKind.StringLiteral ? parseLiteralNode() as StringLiteral : + parseJsxExpression(/*inExpressionContext*/ true) + ), + pos + ); } function parseJsxSpreadAttribute(): JsxSpreadAttribute { - const node = createNode(SyntaxKind.JsxSpreadAttribute); + const pos = getNodePos(); parseExpected(SyntaxKind.OpenBraceToken); parseExpected(SyntaxKind.DotDotDotToken); - node.expression = parseExpression(); + const expression = parseExpression(); parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(node); + return finishNode(factory.createJsxSpreadAttribute(expression), pos); } function parseJsxClosingElement(inExpressionContext: boolean): JsxClosingElement { - const node = createNode(SyntaxKind.JsxClosingElement); + const pos = getNodePos(); parseExpected(SyntaxKind.LessThanSlashToken); - node.tagName = parseJsxElementName(); + const tagName = parseJsxElementName(); if (inExpressionContext) { parseExpected(SyntaxKind.GreaterThanToken); } @@ -4748,11 +4778,11 @@ namespace ts { parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); scanJsxText(); } - return finishNode(node); + return finishNode(factory.createJsxClosingElement(tagName), pos); } function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment { - const node = createNode(SyntaxKind.JsxClosingFragment); + const pos = getNodePos(); parseExpected(SyntaxKind.LessThanSlashToken); if (tokenIsIdentifierOrKeyword(token())) { parseErrorAtRange(parseJsxElementName(), Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment); @@ -4764,16 +4794,16 @@ namespace ts { parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); scanJsxText(); } - return finishNode(node); + return finishNode(factory.createJsxJsxClosingFragment(), pos); } function parseTypeAssertion(): TypeAssertion { - const node = createNode(SyntaxKind.TypeAssertionExpression); + const pos = getNodePos(); parseExpected(SyntaxKind.LessThanToken); - node.type = parseType(); + const type = parseType(); parseExpected(SyntaxKind.GreaterThanToken); - node.expression = parseSimpleUnaryExpression(); - return finishNode(node); + const expression = parseSimpleUnaryExpression(); + return finishNode(factory.createTypeAssertion(type, expression), pos); } function nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate() { @@ -4801,7 +4831,7 @@ namespace ts { if (expr.flags & NodeFlags.OptionalChain) { // this is part of an optional chain. Walk down from `node` to `expression` and set the flag. while (isNonNullExpression(node)) { - node.flags |= NodeFlags.OptionalChain; + (node as Mutable).flags |= NodeFlags.OptionalChain; node = node.expression; } return true; @@ -4810,44 +4840,40 @@ namespace ts { return false; } - function parsePropertyAccessExpressionRest(expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { - const propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); - propertyAccess.expression = expression; - propertyAccess.questionDotToken = questionDotToken; - propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true); - if (questionDotToken || tryReparseOptionalChain(expression)) { - propertyAccess.flags |= NodeFlags.OptionalChain; - if (isPrivateIdentifier(propertyAccess.name)) { - parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); - } + function parsePropertyAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { + const name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true); + const isOptionalChain = questionDotToken || tryReparseOptionalChain(expression); + const propertyAccess = isOptionalChain ? + factory.createPropertyAccessChain(expression, questionDotToken, name) : + factory.createPropertyAccessExpression(expression, name); + if (isOptionalChain && isPrivateIdentifier(propertyAccess.name)) { + parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); } - return finishNode(propertyAccess); + return finishNode(propertyAccess, pos); } - function parseElementAccessExpressionRest(expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { - const indexedAccess = createNode(SyntaxKind.ElementAccessExpression, expression.pos); - indexedAccess.expression = expression; - indexedAccess.questionDotToken = questionDotToken; - + function parseElementAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { + let argumentExpression: Expression; if (token() === SyntaxKind.CloseBracketToken) { - indexedAccess.argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument); + argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument); } else { const argument = allowInAnd(parseExpression); if (isStringOrNumericLiteralLike(argument)) { argument.text = internIdentifier(argument.text); } - indexedAccess.argumentExpression = argument; + argumentExpression = argument; } parseExpected(SyntaxKind.CloseBracketToken); - if (questionDotToken || tryReparseOptionalChain(expression)) { - indexedAccess.flags |= NodeFlags.OptionalChain; - } - return finishNode(indexedAccess); + + const indexedAccess = questionDotToken || tryReparseOptionalChain(expression) ? + factory.createElementAccessChain(expression, questionDotToken, argumentExpression) : + factory.createElementAccessExpression(expression, argumentExpression); + return finishNode(indexedAccess, pos); } - function parseMemberExpressionRest(expression: LeftHandSideExpression, allowOptionalChain: boolean): MemberExpression { + function parseMemberExpressionRest(pos: number, expression: LeftHandSideExpression, allowOptionalChain: boolean): MemberExpression { while (true) { let questionDotToken: QuestionDotToken | undefined; let isPropertyAccess = false; @@ -4860,26 +4886,24 @@ namespace ts { } if (isPropertyAccess) { - expression = parsePropertyAccessExpressionRest(expression, questionDotToken); + expression = parsePropertyAccessExpressionRest(pos, expression, questionDotToken); continue; } if (!questionDotToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { nextToken(); - const nonNullExpression = createNode(SyntaxKind.NonNullExpression, expression.pos); - nonNullExpression.expression = expression; - expression = finishNode(nonNullExpression); + expression = finishNode(factory.createNonNullExpression(expression), pos); continue; } // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName if ((questionDotToken || !inDecoratorContext()) && parseOptional(SyntaxKind.OpenBracketToken)) { - expression = parseElementAccessExpressionRest(expression, questionDotToken); + expression = parseElementAccessExpressionRest(pos, expression, questionDotToken); continue; } if (isTemplateStartOfTaggedTemplate()) { - expression = parseTaggedTemplateRest(expression, questionDotToken, /*typeArguments*/ undefined); + expression = parseTaggedTemplateRest(pos, expression, questionDotToken, /*typeArguments*/ undefined); continue; } @@ -4891,25 +4915,25 @@ namespace ts { return token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead; } - function parseTaggedTemplateRest(tag: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, typeArguments: NodeArray | undefined) { - const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, tag.pos); - tagExpression.tag = tag; - tagExpression.questionDotToken = questionDotToken; - tagExpression.typeArguments = typeArguments; - tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral - ? (reScanTemplateHeadOrNoSubstitutionTemplate(), parseLiteralNode()) - : parseTemplateExpression(/*isTaggedTemplate*/ true); + function parseTaggedTemplateRest(pos: number, tag: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, typeArguments: NodeArray | undefined) { + const tagExpression = factory.createTaggedTemplateExpression( + tag, + typeArguments, + token() === SyntaxKind.NoSubstitutionTemplateLiteral ? + (reScanTemplateHeadOrNoSubstitutionTemplate(), parseLiteralNode() as NoSubstitutionTemplateLiteral) : + parseTemplateExpression(/*isTaggedTemplate*/ true) + ); if (questionDotToken || tag.flags & NodeFlags.OptionalChain) { - tagExpression.flags |= NodeFlags.OptionalChain; + (tagExpression as Mutable).flags |= NodeFlags.OptionalChain; } - return finishNode(tagExpression); + tagExpression.questionDotToken = questionDotToken; + return finishNode(tagExpression, pos); } - function parseCallExpressionRest(expression: LeftHandSideExpression): LeftHandSideExpression { + function parseCallExpressionRest(pos: number, expression: LeftHandSideExpression): LeftHandSideExpression { while (true) { - expression = parseMemberExpressionRest(expression, /*allowOptionalChain*/ true); + expression = parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); const questionDotToken = parseOptionalToken(SyntaxKind.QuestionDotToken); - // handle 'foo<()' if (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken) { // See if this is the start of a generic invocation. If so, consume it and @@ -4919,41 +4943,30 @@ namespace ts { const typeArguments = tryParse(parseTypeArgumentsInExpression); if (typeArguments) { if (isTemplateStartOfTaggedTemplate()) { - expression = parseTaggedTemplateRest(expression, questionDotToken, typeArguments); + expression = parseTaggedTemplateRest(pos, expression, questionDotToken, typeArguments); continue; } - const callExpr = createNode(SyntaxKind.CallExpression, expression.pos); - callExpr.expression = expression; - callExpr.questionDotToken = questionDotToken; - callExpr.typeArguments = typeArguments; - callExpr.arguments = parseArgumentList(); - if (questionDotToken || tryReparseOptionalChain(expression)) { - callExpr.flags |= NodeFlags.OptionalChain; - } - expression = finishNode(callExpr); + const argumentList = parseArgumentList(); + const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? + factory.createCallChain(expression, questionDotToken, typeArguments, argumentList) : + factory.createCallExpression(expression, typeArguments, argumentList); + expression = finishNode(callExpr, pos); continue; } } else if (token() === SyntaxKind.OpenParenToken) { - const callExpr = createNode(SyntaxKind.CallExpression, expression.pos); - callExpr.expression = expression; - callExpr.questionDotToken = questionDotToken; - callExpr.arguments = parseArgumentList(); - if (questionDotToken || tryReparseOptionalChain(expression)) { - callExpr.flags |= NodeFlags.OptionalChain; - } - expression = finishNode(callExpr); + const argumentList = parseArgumentList(); + const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? + factory.createCallChain(expression, questionDotToken, /*typeArguments*/ undefined, argumentList) : + factory.createCallExpression(expression, /*typeArguments*/ undefined, argumentList); + expression = finishNode(callExpr, pos); continue; } if (questionDotToken) { // We failed to parse anything, so report a missing identifier here. - const propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos) as PropertyAccessExpression; - propertyAccess.expression = expression; - propertyAccess.questionDotToken = questionDotToken; - propertyAccess.name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics.Identifier_expected); - propertyAccess.flags |= NodeFlags.OptionalChain; - expression = finishNode(propertyAccess); + const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics.Identifier_expected); + expression = finishNode(factory.createPropertyAccessChain(expression, questionDotToken, name), pos); } break; } @@ -5077,23 +5090,24 @@ namespace ts { } function parseParenthesizedExpression(): ParenthesizedExpression { - const node = createNodeWithJSDoc(SyntaxKind.ParenthesizedExpression); + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); - return finishNode(node); + return withJSDoc(finishNode(factory.createParenthesizedExpression(expression), pos), hasJSDoc); } function parseSpreadElement(): Expression { - const node = createNode(SyntaxKind.SpreadElement); + const pos = getNodePos(); parseExpected(SyntaxKind.DotDotDotToken); - node.expression = parseAssignmentExpressionOrHigher(); - return finishNode(node); + const expression = parseAssignmentExpressionOrHigher(); + return finishNode(factory.createSpreadElement(expression), pos); } function parseArgumentOrArrayLiteralElement(): Expression { return token() === SyntaxKind.DotDotDotToken ? parseSpreadElement() : - token() === SyntaxKind.CommaToken ? createNode(SyntaxKind.OmittedExpression) : + token() === SyntaxKind.CommaToken ? finishNode(factory.createOmittedExpression(), getNodePos()) : parseAssignmentExpressionOrHigher(); } @@ -5102,44 +5116,43 @@ namespace ts { } function parseArrayLiteralExpression(): ArrayLiteralExpression { - const node = createNode(SyntaxKind.ArrayLiteralExpression); + const pos = getNodePos(); parseExpected(SyntaxKind.OpenBracketToken); - if (scanner.hasPrecedingLineBreak()) { - node.multiLine = true; - } - node.elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement); + const multiLine = scanner.hasPrecedingLineBreak(); + const elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement); parseExpected(SyntaxKind.CloseBracketToken); - return finishNode(node); + return finishNode(factory.createArrayLiteralExpression(elements, multiLine), pos); } function parseObjectLiteralElement(): ObjectLiteralElementLike { - const node = createNodeWithJSDoc(SyntaxKind.Unknown); + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); if (parseOptionalToken(SyntaxKind.DotDotDotToken)) { - node.kind = SyntaxKind.SpreadAssignment; - (node).expression = parseAssignmentExpressionOrHigher(); - return finishNode(node); + const expression = parseAssignmentExpressionOrHigher(); + return withJSDoc(finishNode(factory.createSpreadAssignment(expression), pos), hasJSDoc); } - node.decorators = parseDecorators(); - node.modifiers = parseModifiers(); + const decorators = parseDecorators(); + const modifiers = parseModifiers(); if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(node, SyntaxKind.GetAccessor); + return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, SyntaxKind.GetAccessor); } if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(node, SyntaxKind.SetAccessor); + return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, SyntaxKind.SetAccessor); } const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); const tokenIsIdentifier = isIdentifier(); - node.name = parsePropertyName(); + const name = parsePropertyName(); + // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker. - (node).questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - (node).exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken); + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + const exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken); if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseMethodDeclaration(node, asteriskToken); + return parseMethodDeclaration(pos, hasJSDoc, decorators, modifiers, asteriskToken, name, questionToken, exclamationToken); } // check if it is short-hand property assignment or normal property assignment @@ -5147,42 +5160,45 @@ namespace ts { // CoverInitializedName[Yield] : // IdentifierReference[?Yield] Initializer[In, ?Yield] // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern + let node: Mutable; const isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== SyntaxKind.ColonToken); if (isShorthandPropertyAssignment) { - node.kind = SyntaxKind.ShorthandPropertyAssignment; const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken); - if (equalsToken) { - (node).equalsToken = equalsToken; - (node).objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher); - } + const objectAssignmentInitializer = equalsToken ? allowInAnd(parseAssignmentExpressionOrHigher) : undefined; + node = factory.createShorthandPropertyAssignment(name as Identifier, objectAssignmentInitializer); + // Save equals token for error reporting. + // TODO(rbuckton): Consider manufacturing this when we need to report an error as it is otherwise not useful. + node.equalsToken = equalsToken; } else { - node.kind = SyntaxKind.PropertyAssignment; parseExpected(SyntaxKind.ColonToken); - (node).initializer = allowInAnd(parseAssignmentExpressionOrHigher); + const initializer = allowInAnd(parseAssignmentExpressionOrHigher); + node = factory.createPropertyAssignment(name, initializer); } - return finishNode(node); + // Decorators, Modifiers, questionToken, and exclamationToken are not supported by property assignments and are reported in the grammar checker + node.decorators = decorators; + node.modifiers = modifiers; + node.questionToken = questionToken; + node.exclamationToken = exclamationToken; + return withJSDoc(finishNode(node, pos), hasJSDoc); } function parseObjectLiteralExpression(): ObjectLiteralExpression { - const node = createNode(SyntaxKind.ObjectLiteralExpression); + const pos = getNodePos(); const openBracePosition = scanner.getTokenPos(); parseExpected(SyntaxKind.OpenBraceToken); - if (scanner.hasPrecedingLineBreak()) { - node.multiLine = true; - } - - node.properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); + const multiLine = scanner.hasPrecedingLineBreak(); + const properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); if (!parseExpected(SyntaxKind.CloseBraceToken)) { const lastError = lastOrUndefined(parseDiagnostics); if (lastError && lastError.code === Diagnostics._0_expected.code) { addRelatedInfo( lastError, - createFileDiagnostic(sourceFile, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) + createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) ); } } - return finishNode(node); + return finishNode(factory.createObjectLiteralExpression(properties, multiLine), pos); } function parseFunctionExpression(): FunctionExpression { @@ -5196,27 +5212,30 @@ namespace ts { setDecoratorContext(/*val*/ false); } - const node = createNodeWithJSDoc(SyntaxKind.FunctionExpression); - node.modifiers = parseModifiers(); + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiers(); parseExpected(SyntaxKind.FunctionKeyword); - node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - - const isGenerator = node.asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = hasModifierOfKind(node, SyntaxKind.AsyncKeyword) ? SignatureFlags.Await : SignatureFlags.None; - node.name = + const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; + const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; + const name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : isAsync ? doInAwaitContext(parseOptionalIdentifier) : parseOptionalIdentifier(); - fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node); - node.body = parseFunctionBlock(isGenerator | isAsync); + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(isGenerator | isAsync); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlock(isGenerator | isAsync); if (saveDecoratorContext) { setDecoratorContext(/*val*/ true); } - return finishNode(node); + const node = factory.createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function parseOptionalIdentifier(): Identifier | undefined { @@ -5224,65 +5243,60 @@ namespace ts { } function parseNewExpressionOrNewDotTarget(): NewExpression | MetaProperty { - const fullStart = scanner.getStartPos(); + const pos = getNodePos(); parseExpected(SyntaxKind.NewKeyword); if (parseOptional(SyntaxKind.DotToken)) { - const node = createNode(SyntaxKind.MetaProperty, fullStart); - node.keywordToken = SyntaxKind.NewKeyword; - node.name = parseIdentifierName(); - return finishNode(node); + const name = parseIdentifierName(); + return finishNode(factory.createMetaProperty(SyntaxKind.NewKeyword, name), pos); } + const expressionPos = getNodePos(); let expression: MemberExpression = parsePrimaryExpression(); let typeArguments; while (true) { - expression = parseMemberExpressionRest(expression, /*allowOptionalChain*/ false); + expression = parseMemberExpressionRest(expressionPos, expression, /*allowOptionalChain*/ false); typeArguments = tryParse(parseTypeArgumentsInExpression); if (isTemplateStartOfTaggedTemplate()) { Debug.assert(!!typeArguments, "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'"); - expression = parseTaggedTemplateRest(expression, /*optionalChain*/ undefined, typeArguments); + expression = parseTaggedTemplateRest(expressionPos, expression, /*optionalChain*/ undefined, typeArguments); typeArguments = undefined; } break; } - const node = createNode(SyntaxKind.NewExpression, fullStart); - node.expression = expression; - node.typeArguments = typeArguments; + let argumentsArray: NodeArray | undefined; if (token() === SyntaxKind.OpenParenToken) { - node.arguments = parseArgumentList(); + argumentsArray = parseArgumentList(); } - else if (node.typeArguments) { - parseErrorAt(fullStart, scanner.getStartPos(), Diagnostics.A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list); + else if (typeArguments) { + parseErrorAt(pos, scanner.getStartPos(), Diagnostics.A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list); } - return finishNode(node); + return finishNode(factory.createNewExpression(expression, typeArguments, argumentsArray), pos); } // STATEMENTS function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block { - const node = createNode(SyntaxKind.Block); + const pos = getNodePos(); const openBracePosition = scanner.getTokenPos(); if (parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage) || ignoreMissingOpenBrace) { - if (scanner.hasPrecedingLineBreak()) { - node.multiLine = true; - } - - node.statements = parseList(ParsingContext.BlockStatements, parseStatement); + const multiLine = scanner.hasPrecedingLineBreak(); + const statements = parseList(ParsingContext.BlockStatements, parseStatement); if (!parseExpected(SyntaxKind.CloseBraceToken)) { const lastError = lastOrUndefined(parseDiagnostics); if (lastError && lastError.code === Diagnostics._0_expected.code) { addRelatedInfo( lastError, - createFileDiagnostic(sourceFile, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) + createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) ); } } + return finishNode(factory.createBlock(statements, multiLine), pos); } else { - node.statements = createMissingList(); + const statements = createMissingList(); + return finishNode(factory.createBlock(statements, /*multiLine*/ undefined), pos); } - return finishNode(node); } function parseFunctionBlock(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block { @@ -5312,29 +5326,29 @@ namespace ts { } function parseEmptyStatement(): Statement { - const node = createNode(SyntaxKind.EmptyStatement); + const pos = getNodePos(); parseExpected(SyntaxKind.SemicolonToken); - return finishNode(node); + return finishNode(factory.createEmptyStatement(), pos); } function parseIfStatement(): IfStatement { - const node = createNode(SyntaxKind.IfStatement); + const pos = getNodePos(); parseExpected(SyntaxKind.IfKeyword); parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); - node.thenStatement = parseStatement(); - node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; - return finishNode(node); + const thenStatement = parseStatement(); + const elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; + return finishNode(factory.createIfStatement(expression, thenStatement, elseStatement), pos); } function parseDoStatement(): DoStatement { - const node = createNode(SyntaxKind.DoStatement); + const pos = getNodePos(); parseExpected(SyntaxKind.DoKeyword); - node.statement = parseStatement(); + const statement = parseStatement(); parseExpected(SyntaxKind.WhileKeyword); parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html @@ -5342,17 +5356,17 @@ namespace ts { // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby // do;while(0)x will have a semicolon inserted before x. parseOptional(SyntaxKind.SemicolonToken); - return finishNode(node); + return finishNode(factory.createDoStatement(statement, expression), pos); } function parseWhileStatement(): WhileStatement { - const node = createNode(SyntaxKind.WhileStatement); + const pos = getNodePos(); parseExpected(SyntaxKind.WhileKeyword); parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); - node.statement = parseStatement(); - return finishNode(node); + const statement = parseStatement(); + return finishNode(factory.createWhileStatement(expression, statement), pos); } function parseForOrForInOrForOfStatement(): Statement { @@ -5370,186 +5384,187 @@ namespace ts { initializer = disallowInAnd(parseExpression); } } - let forOrForInOrForOfStatement: IterationStatement; + + let node: IterationStatement; if (awaitToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) { - const forOfStatement = createNode(SyntaxKind.ForOfStatement, pos); - forOfStatement.awaitModifier = awaitToken; - forOfStatement.initializer = initializer; - forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher); + const expression = allowInAnd(parseAssignmentExpressionOrHigher); parseExpected(SyntaxKind.CloseParenToken); - forOrForInOrForOfStatement = forOfStatement; + node = factory.createForOfStatement(awaitToken, initializer, expression, parseStatement()); } else if (parseOptional(SyntaxKind.InKeyword)) { - const forInStatement = createNode(SyntaxKind.ForInStatement, pos); - forInStatement.initializer = initializer; - forInStatement.expression = allowInAnd(parseExpression); + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); - forOrForInOrForOfStatement = forInStatement; + node = factory.createForInStatement(initializer, expression, parseStatement()); } else { - const forStatement = createNode(SyntaxKind.ForStatement, pos); - forStatement.initializer = initializer; parseExpected(SyntaxKind.SemicolonToken); - if (token() !== SyntaxKind.SemicolonToken && token() !== SyntaxKind.CloseParenToken) { - forStatement.condition = allowInAnd(parseExpression); - } + const condition = token() !== SyntaxKind.SemicolonToken && token() !== SyntaxKind.CloseParenToken + ? allowInAnd(parseExpression) + : undefined; parseExpected(SyntaxKind.SemicolonToken); - if (token() !== SyntaxKind.CloseParenToken) { - forStatement.incrementor = allowInAnd(parseExpression); - } + const incrementor = token() !== SyntaxKind.CloseParenToken + ? allowInAnd(parseExpression) + : undefined; parseExpected(SyntaxKind.CloseParenToken); - forOrForInOrForOfStatement = forStatement; + node = factory.createForStatement(initializer, condition, incrementor, parseStatement()); } - forOrForInOrForOfStatement.statement = parseStatement(); - - return finishNode(forOrForInOrForOfStatement); + return finishNode(node, pos); } function parseBreakOrContinueStatement(kind: SyntaxKind): BreakOrContinueStatement { - const node = createNode(kind); + const pos = getNodePos(); parseExpected(kind === SyntaxKind.BreakStatement ? SyntaxKind.BreakKeyword : SyntaxKind.ContinueKeyword); - if (!canParseSemicolon()) { - node.label = parseIdentifier(); - } + const label = canParseSemicolon() ? undefined : parseIdentifier(); parseSemicolon(); - return finishNode(node); + const node = kind === SyntaxKind.BreakStatement + ? factory.createBreakStatement(label) + : factory.createContinueStatement(label); + return finishNode(node, pos); } function parseReturnStatement(): ReturnStatement { - const node = createNode(SyntaxKind.ReturnStatement); - + const pos = getNodePos(); parseExpected(SyntaxKind.ReturnKeyword); - if (!canParseSemicolon()) { - node.expression = allowInAnd(parseExpression); - } - + const expression = canParseSemicolon() ? undefined : allowInAnd(parseExpression); parseSemicolon(); - return finishNode(node); + return finishNode(factory.createReturnStatement(expression), pos); } function parseWithStatement(): WithStatement { - const node = createNode(SyntaxKind.WithStatement); + const pos = getNodePos(); parseExpected(SyntaxKind.WithKeyword); parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); - node.statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); - return finishNode(node); + const statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); + return finishNode(factory.createWithStatement(expression, statement), pos); } function parseCaseClause(): CaseClause { - const node = createNode(SyntaxKind.CaseClause); + const pos = getNodePos(); parseExpected(SyntaxKind.CaseKeyword); - node.expression = allowInAnd(parseExpression); + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.ColonToken); - node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); - return finishNode(node); + const statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); + return finishNode(factory.createCaseClause(expression, statements), pos); } function parseDefaultClause(): DefaultClause { - const node = createNode(SyntaxKind.DefaultClause); + const pos = getNodePos(); parseExpected(SyntaxKind.DefaultKeyword); parseExpected(SyntaxKind.ColonToken); - node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); - return finishNode(node); + const statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); + return finishNode(factory.createDefaultClause(statements), pos); } function parseCaseOrDefaultClause(): CaseOrDefaultClause { return token() === SyntaxKind.CaseKeyword ? parseCaseClause() : parseDefaultClause(); } + function parseCaseBlock(): CaseBlock { + const pos = getNodePos(); + parseExpected(SyntaxKind.OpenBraceToken); + const clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause); + parseExpected(SyntaxKind.CloseBraceToken); + return finishNode(factory.createCaseBlock(clauses), pos); + } + function parseSwitchStatement(): SwitchStatement { - const node = createNode(SyntaxKind.SwitchStatement); + const pos = getNodePos(); parseExpected(SyntaxKind.SwitchKeyword); parseExpected(SyntaxKind.OpenParenToken); - node.expression = allowInAnd(parseExpression); + const expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); - const caseBlock = createNode(SyntaxKind.CaseBlock); - parseExpected(SyntaxKind.OpenBraceToken); - caseBlock.clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause); - parseExpected(SyntaxKind.CloseBraceToken); - node.caseBlock = finishNode(caseBlock); - return finishNode(node); + const caseBlock = parseCaseBlock(); + return finishNode(factory.createSwitchStatement(expression, caseBlock), pos); } function parseThrowStatement(): ThrowStatement { // ThrowStatement[Yield] : // throw [no LineTerminator here]Expression[In, ?Yield]; + const pos = getNodePos(); + parseExpected(SyntaxKind.ThrowKeyword); + // Because of automatic semicolon insertion, we need to report error if this // throw could be terminated with a semicolon. Note: we can't call 'parseExpression' // directly as that might consume an expression on the following line. // We just return 'undefined' in that case. The actual error will be reported in the // grammar walker. - const node = createNode(SyntaxKind.ThrowStatement); - parseExpected(SyntaxKind.ThrowKeyword); - node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression); + // TODO(rbuckton): Should we use `createMissingNode` here instead? + const expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression); parseSemicolon(); - return finishNode(node); + return finishNode(factory.createThrowStatement(expression!), pos); } // TODO: Review for error recovery function parseTryStatement(): TryStatement { - const node = createNode(SyntaxKind.TryStatement); + const pos = getNodePos(); parseExpected(SyntaxKind.TryKeyword); - node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); - node.catchClause = token() === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; + const tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); + const catchClause = token() === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; // If we don't have a catch clause, then we must have a finally clause. Try to parse // one out no matter what. - if (!node.catchClause || token() === SyntaxKind.FinallyKeyword) { + let finallyBlock: Block | undefined; + if (!catchClause || token() === SyntaxKind.FinallyKeyword) { parseExpected(SyntaxKind.FinallyKeyword); - node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); + finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); } - return finishNode(node); + return finishNode(factory.createTryStatement(tryBlock, catchClause, finallyBlock), pos); } function parseCatchClause(): CatchClause { - const result = createNode(SyntaxKind.CatchClause); + const pos = getNodePos(); parseExpected(SyntaxKind.CatchKeyword); + let variableDeclaration; if (parseOptional(SyntaxKind.OpenParenToken)) { - result.variableDeclaration = parseVariableDeclaration(); + variableDeclaration = parseVariableDeclaration(); parseExpected(SyntaxKind.CloseParenToken); } else { // Keep shape of node to avoid degrading performance. - result.variableDeclaration = undefined; + variableDeclaration = undefined; } - result.block = parseBlock(/*ignoreMissingOpenBrace*/ false); - return finishNode(result); + const block = parseBlock(/*ignoreMissingOpenBrace*/ false); + return finishNode(factory.createCatchClause(variableDeclaration, block), pos); } function parseDebuggerStatement(): Statement { - const node = createNode(SyntaxKind.DebuggerStatement); + const pos = getNodePos(); parseExpected(SyntaxKind.DebuggerKeyword); parseSemicolon(); - return finishNode(node); + return finishNode(factory.createDebuggerStatement(), pos); } function parseExpressionOrLabeledStatement(): ExpressionStatement | LabeledStatement { // Avoiding having to do the lookahead for a labeled statement by just trying to parse // out an expression, seeing if it is identifier and then seeing if it is followed by // a colon. - const node = createNodeWithJSDoc(token() === SyntaxKind.Identifier ? SyntaxKind.Unknown : SyntaxKind.ExpressionStatement); + const pos = getNodePos(); + let hasJSDoc = hasPrecedingJSDocComment(); + let node: ExpressionStatement | LabeledStatement; + const hasParen = token() === SyntaxKind.OpenParenToken; const expression = allowInAnd(parseExpression); - if (expression.kind === SyntaxKind.Identifier && parseOptional(SyntaxKind.ColonToken)) { - node.kind = SyntaxKind.LabeledStatement; - (node).label = expression; - (node).statement = parseStatement(); + if (ts.isIdentifier(expression) && parseOptional(SyntaxKind.ColonToken)) { + node = factory.createLabeledStatement(expression, parseStatement()); } else { - node.kind = SyntaxKind.ExpressionStatement; - (node).expression = expression; parseSemicolon(); + node = factory.createExpressionStatement(expression); + if (hasParen) { + // do not parse the same jsdoc twice + hasJSDoc = false; + } } - return finishNode(node); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function nextTokenIsIdentifierOrKeywordOnSameLine() { @@ -5735,16 +5750,16 @@ namespace ts { case SyntaxKind.OpenBraceToken: return parseBlock(/*ignoreMissingOpenBrace*/ false); case SyntaxKind.VarKeyword: - return parseVariableStatement(createNodeWithJSDoc(SyntaxKind.VariableDeclaration)); + return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined); case SyntaxKind.LetKeyword: if (isLetDeclaration()) { - return parseVariableStatement(createNodeWithJSDoc(SyntaxKind.VariableDeclaration)); + return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined); } break; case SyntaxKind.FunctionKeyword: - return parseFunctionDeclaration(createNodeWithJSDoc(SyntaxKind.FunctionDeclaration)); + return parseFunctionDeclaration(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined); case SyntaxKind.ClassKeyword: - return parseClassDeclaration(createNodeWithJSDoc(SyntaxKind.ClassDeclaration)); + return parseClassDeclaration(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined); case SyntaxKind.IfKeyword: return parseIfStatement(); case SyntaxKind.DoKeyword: @@ -5805,11 +5820,13 @@ namespace ts { } function parseDeclaration(): Statement { - const modifiers = lookAhead(() => (parseDecorators(), parseModifiers())); + // TODO: Can we hold onto the parsed decorators/modifiers and advance the scanner + // if we can't reuse the declaration, so that we don't do this work twice? + // // `parseListElement` attempted to get the reused node at this position, // but the ambient context flag was not yet set, so the node appeared // not reusable in that context. - const isAmbient = some(modifiers, isDeclareModifier); + const isAmbient = some(lookAhead(() => (parseDecorators(), parseModifiers())), isDeclareModifier); if (isAmbient) { const node = tryReuseAmbientDeclaration(); if (node) { @@ -5817,17 +5834,18 @@ namespace ts { } } - const node = createNodeWithJSDoc(SyntaxKind.Unknown); - node.decorators = parseDecorators(); - node.modifiers = parseModifiers(); + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const decorators = parseDecorators(); + const modifiers = parseModifiers(); if (isAmbient) { - for (const m of node.modifiers!) { - m.flags |= NodeFlags.Ambient; + for (const m of modifiers!) { + (m as Mutable).flags |= NodeFlags.Ambient; } - return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(node)); + return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(pos, hasJSDoc, decorators, modifiers)); } else { - return parseDeclarationWorker(node); + return parseDeclarationWorker(pos, hasJSDoc, decorators, modifiers); } } @@ -5840,48 +5858,48 @@ namespace ts { }); } - function parseDeclarationWorker(node: Statement): Statement { + function parseDeclarationWorker(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): Statement { switch (token()) { case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: - return parseVariableStatement(node); + return parseVariableStatement(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.FunctionKeyword: - return parseFunctionDeclaration(node); + return parseFunctionDeclaration(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.ClassKeyword: - return parseClassDeclaration(node); + return parseClassDeclaration(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.InterfaceKeyword: - return parseInterfaceDeclaration(node); + return parseInterfaceDeclaration(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.TypeKeyword: - return parseTypeAliasDeclaration(node); + return parseTypeAliasDeclaration(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.EnumKeyword: - return parseEnumDeclaration(node); + return parseEnumDeclaration(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.GlobalKeyword: case SyntaxKind.ModuleKeyword: case SyntaxKind.NamespaceKeyword: - return parseModuleDeclaration(node); + return parseModuleDeclaration(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.ImportKeyword: - return parseImportDeclarationOrImportEqualsDeclaration(node); + return parseImportDeclarationOrImportEqualsDeclaration(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.ExportKeyword: nextToken(); switch (token()) { case SyntaxKind.DefaultKeyword: case SyntaxKind.EqualsToken: - return parseExportAssignment(node); + return parseExportAssignment(pos, hasJSDoc, decorators, modifiers); case SyntaxKind.AsKeyword: - return parseNamespaceExportDeclaration(node); + return parseNamespaceExportDeclaration(pos, hasJSDoc, decorators, modifiers); default: - return parseExportDeclaration(node); + return parseExportDeclaration(pos, hasJSDoc, decorators, modifiers); } default: - if (node.decorators || node.modifiers) { + if (decorators || modifiers) { // We reached this point because we encountered decorators and/or modifiers and assumed a declaration // would follow. For recovery and error reporting purposes, return an incomplete declaration. - const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); - missing.pos = node.pos; - missing.decorators = node.decorators; - missing.modifiers = node.modifiers; - return finishNode(missing); + const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); + setTextRangePos(missing, pos); + missing.decorators = decorators; + missing.modifiers = modifiers; + return missing; } return undefined!; // TODO: GH#18217 } @@ -5904,47 +5922,48 @@ namespace ts { // DECLARATIONS function parseArrayBindingElement(): ArrayBindingElement { + const pos = getNodePos(); if (token() === SyntaxKind.CommaToken) { - return createNode(SyntaxKind.OmittedExpression); + return finishNode(factory.createOmittedExpression(), pos); } - const node = createNode(SyntaxKind.BindingElement); - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - node.name = parseIdentifierOrPattern(); - node.initializer = parseInitializer(); - return finishNode(node); + const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const name = parseIdentifierOrPattern(); + const initializer = parseInitializer(); + return finishNode(factory.createBindingElement(dotDotDotToken, /*propertyName*/ undefined, name, initializer), pos); } function parseObjectBindingElement(): BindingElement { - const node = createNode(SyntaxKind.BindingElement); - node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const pos = getNodePos(); + const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); const tokenIsIdentifier = isIdentifier(); - const propertyName = parsePropertyName(); + let propertyName: PropertyName | undefined = parsePropertyName(); + let name: BindingName; if (tokenIsIdentifier && token() !== SyntaxKind.ColonToken) { - node.name = propertyName; + name = propertyName; + propertyName = undefined; } else { parseExpected(SyntaxKind.ColonToken); - node.propertyName = propertyName; - node.name = parseIdentifierOrPattern(); + name = parseIdentifierOrPattern(); } - node.initializer = parseInitializer(); - return finishNode(node); + const initializer = parseInitializer(); + return finishNode(factory.createBindingElement(dotDotDotToken, propertyName, name, initializer), pos); } function parseObjectBindingPattern(): ObjectBindingPattern { - const node = createNode(SyntaxKind.ObjectBindingPattern); + const pos = getNodePos(); parseExpected(SyntaxKind.OpenBraceToken); - node.elements = parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement); + const elements = parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement); parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(node); + return finishNode(factory.createObjectBindingPattern(elements), pos); } function parseArrayBindingPattern(): ArrayBindingPattern { - const node = createNode(SyntaxKind.ArrayBindingPattern); + const pos = getNodePos(); parseExpected(SyntaxKind.OpenBracketToken); - node.elements = parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement); + const elements = parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement); parseExpected(SyntaxKind.CloseBracketToken); - return finishNode(node); + return finishNode(factory.createArrayBindingPattern(elements), pos); } function isIdentifierOrPrivateIdentifierOrPattern() { @@ -5969,30 +5988,31 @@ namespace ts { } function parseVariableDeclaration(allowExclamation?: boolean): VariableDeclaration { - const node = createNode(SyntaxKind.VariableDeclaration); - node.name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations); - if (allowExclamation && node.name.kind === SyntaxKind.Identifier && + const pos = getNodePos(); + const name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations); + let exclamationToken: ExclamationToken | undefined; + if (allowExclamation && name.kind === SyntaxKind.Identifier && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { - node.exclamationToken = parseTokenNode>(); - } - node.type = parseTypeAnnotation(); - if (!isInOrOfKeyword(token())) { - node.initializer = parseInitializer(); + exclamationToken = parseTokenNode>(); } - return finishNode(node); + const type = parseTypeAnnotation(); + const initializer = isInOrOfKeyword(token()) ? undefined : parseInitializer(); + const node = factory.createVariableDeclaration(name, exclamationToken, type, initializer); + return finishNode(node, pos); } function parseVariableDeclarationList(inForStatementInitializer: boolean): VariableDeclarationList { - const node = createNode(SyntaxKind.VariableDeclarationList); + const pos = getNodePos(); + let flags: NodeFlags = 0; switch (token()) { case SyntaxKind.VarKeyword: break; case SyntaxKind.LetKeyword: - node.flags |= NodeFlags.Let; + flags |= NodeFlags.Let; break; case SyntaxKind.ConstKeyword: - node.flags |= NodeFlags.Const; + flags |= NodeFlags.Const; break; default: Debug.fail(); @@ -6009,43 +6029,49 @@ namespace ts { // So we need to look ahead to determine if 'of' should be treated as a keyword in // this context. // The checker will then give an error that there is an empty declaration list. + let declarations; if (token() === SyntaxKind.OfKeyword && lookAhead(canFollowContextualOfKeyword)) { - node.declarations = createMissingList(); + declarations = createMissingList(); } else { const savedDisallowIn = inDisallowInContext(); setDisallowInContext(inForStatementInitializer); - node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations, + declarations = parseDelimitedList(ParsingContext.VariableDeclarations, inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation); setDisallowInContext(savedDisallowIn); } - return finishNode(node); + return finishNode(factory.createVariableDeclarationList(declarations, flags), pos); } function canFollowContextualOfKeyword(): boolean { return nextTokenIsIdentifier() && nextToken() === SyntaxKind.CloseParenToken; } - function parseVariableStatement(node: VariableStatement): VariableStatement { - node.kind = SyntaxKind.VariableStatement; - node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false); + function parseVariableStatement(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): VariableStatement { + const declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false); parseSemicolon(); - return finishNode(node); + const node = factory.createVariableStatement(modifiers, declarationList); + // Decorators are not allowed on a variable statement, so we keep track of them to report them in the grammar checker. + node.decorators = decorators; + return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseFunctionDeclaration(node: FunctionDeclaration): FunctionDeclaration { - node.kind = SyntaxKind.FunctionDeclaration; + function parseFunctionDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): FunctionDeclaration { + const modifierFlags = modifiersToFlags(modifiers); parseExpected(SyntaxKind.FunctionKeyword); - node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - node.name = hasModifierOfKind(node, SyntaxKind.DefaultKeyword) ? parseOptionalIdentifier() : parseIdentifier(); - const isGenerator = node.asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = hasModifierOfKind(node, SyntaxKind.AsyncKeyword) ? SignatureFlags.Await : SignatureFlags.None; - fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node); - node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, Diagnostics.or_expected); - return finishNode(node); + const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + const name = modifierFlags & ModifierFlags.Default ? parseOptionalIdentifier() : parseIdentifier(); + const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; + const isAsync = modifierFlags & ModifierFlags.Async ? SignatureFlags.Await : SignatureFlags.None; + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(isGenerator | isAsync); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, Diagnostics.or_expected); + const node = factory.createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function parseConstructorName() { @@ -6060,57 +6086,101 @@ namespace ts { } } - function tryParseConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration | undefined { + function tryParseConstructorDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ConstructorDeclaration | undefined { return tryParse(() => { if (parseConstructorName()) { - node.kind = SyntaxKind.Constructor; - fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node); - node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); - return finishNode(node); + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.None); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); + const node = factory.createConstructorDeclaration(decorators, modifiers, parameters, body); + // Attach `typeParameters` and `type` if they exist so that we can report them in the grammar checker. + node.typeParameters = typeParameters; + node.type = type; + return withJSDoc(finishNode(node, pos), hasJSDoc); } }); } - function parseMethodDeclaration(node: MethodDeclaration, asteriskToken: AsteriskToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration { - node.kind = SyntaxKind.MethodDeclaration; - node.asteriskToken = asteriskToken; + function parseMethodDeclaration( + pos: number, + hasJSDoc: boolean, + decorators: NodeArray | undefined, + modifiers: NodeArray | undefined, + asteriskToken: AsteriskToken | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + exclamationToken: ExclamationToken | undefined, + diagnosticMessage?: DiagnosticMessage + ): MethodDeclaration { const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = hasModifierOfKind(node, SyntaxKind.AsyncKeyword) ? SignatureFlags.Await : SignatureFlags.None; - fillSignature(SyntaxKind.ColonToken, isGenerator | isAsync, node); - node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage); - return finishNode(node); - } - - function parsePropertyDeclaration(node: PropertyDeclaration): PropertyDeclaration { - node.kind = SyntaxKind.PropertyDeclaration; - if (!node.questionToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { - node.exclamationToken = parseTokenNode>(); - } - node.type = parseTypeAnnotation(); - node.initializer = doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext | NodeFlags.DisallowInContext, parseInitializer); - + const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(isGenerator | isAsync); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage); + const node = factory.createMethodDeclaration( + decorators, + modifiers, + asteriskToken, + name, + questionToken, + typeParameters, + parameters, + type, + body + ); + // An exclamation token on a method is invalid syntax and will be handled by the grammar checker + node.exclamationToken = exclamationToken; + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parsePropertyDeclaration( + pos: number, + hasJSDoc: boolean, + decorators: NodeArray | undefined, + modifiers: NodeArray | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined + ): PropertyDeclaration { + const exclamationToken = !questionToken && !scanner.hasPrecedingLineBreak() ? parseOptionalToken(SyntaxKind.ExclamationToken) : undefined; + const type = parseTypeAnnotation(); + const initializer = doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext | NodeFlags.DisallowInContext, parseInitializer); parseSemicolon(); - return finishNode(node); + const node = factory.createPropertyDeclaration(decorators, modifiers, name, questionToken || exclamationToken, type, initializer); + return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parsePropertyOrMethodDeclaration(node: PropertyDeclaration | MethodDeclaration): PropertyDeclaration | MethodDeclaration { + function parsePropertyOrMethodDeclaration( + pos: number, + hasJSDoc: boolean, + decorators: NodeArray | undefined, + modifiers: NodeArray | undefined + ): PropertyDeclaration | MethodDeclaration { const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - node.name = parsePropertyName(); + const name = parsePropertyName(); // Note: this is not legal as per the grammar. But we allow it in the parser and // report an error in the grammar checker. - node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseMethodDeclaration(node, asteriskToken, Diagnostics.or_expected); + return parseMethodDeclaration(pos, hasJSDoc, decorators, modifiers, asteriskToken, name, questionToken, /*exclamationToken*/ undefined, Diagnostics.or_expected); } - return parsePropertyDeclaration(node); + return parsePropertyDeclaration(pos, hasJSDoc, decorators, modifiers, name, questionToken); } - function parseAccessorDeclaration(node: AccessorDeclaration, kind: AccessorDeclaration["kind"]): AccessorDeclaration { - node.kind = kind; - node.name = parsePropertyName(); - fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node); - node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None); - return finishNode(node); + function parseAccessorDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined, kind: AccessorDeclaration["kind"]): AccessorDeclaration { + const name = parsePropertyName(); + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.None); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(SignatureFlags.None); + const node = kind === SyntaxKind.GetAccessor + ? factory.createGetAccessorDeclaration(decorators, modifiers, name, parameters, type, body) + : factory.createSetAccessorDeclaration(decorators, modifiers, name, parameters, body); + // Keep track of `typeParameters` (for both) and `type` (for setters) if they were parsed those indicate grammar errors + node.typeParameters = typeParameters; + if (type && node.kind === SyntaxKind.SetAccessor) (node as Mutable).type = type; + return withJSDoc(finishNode(node, pos), hasJSDoc); } function isClassMemberStart(): boolean { @@ -6182,20 +6252,42 @@ namespace ts { return false; } + function tryParseDecorator(): Decorator | undefined { + const pos = getNodePos(); + if (!parseOptional(SyntaxKind.AtToken)) { + return undefined; + } + const expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher); + return finishNode(factory.createDecorator(expression), pos); + } + function parseDecorators(): NodeArray | undefined { - let list: Decorator[] | undefined; - const listPos = getNodePos(); - while (true) { - const decoratorStart = getNodePos(); - if (!parseOptional(SyntaxKind.AtToken)) { - break; + const pos = getNodePos(); + let list, decorator; + while (decorator = tryParseDecorator()) { + list = append(list, decorator); + } + return list && createNodeArray(list, pos); + } + + function tryParseModifier(permitInvalidConstAsModifier?: boolean): Modifier | undefined { + const pos = getNodePos(); + const kind = token(); + + if (token() === SyntaxKind.ConstKeyword && permitInvalidConstAsModifier) { + // We need to ensure that any subsequent modifiers appear on the same line + // so that when 'const' is a standalone declaration, we don't issue an error. + if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) { + return undefined; + } + } + else { + if (!parseAnyContextualModifier()) { + return undefined; } - const decorator = createNode(SyntaxKind.Decorator, decoratorStart); - decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher); - finishNode(decorator); - (list || (list = [])).push(decorator); } - return list && createNodeArray(list, listPos); + + return finishNode(factory.createToken(kind as Modifier["kind"]), pos); } /* @@ -6206,71 +6298,53 @@ namespace ts { * In such situations, 'permitInvalidConstAsModifier' should be set to true. */ function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray | undefined { - let list: Modifier[] | undefined; - const listPos = getNodePos(); - while (true) { - const modifierStart = scanner.getStartPos(); - const modifierKind = token(); - - if (token() === SyntaxKind.ConstKeyword && permitInvalidConstAsModifier) { - // We need to ensure that any subsequent modifiers appear on the same line - // so that when 'const' is a standalone declaration, we don't issue an error. - if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) { - break; - } - } - else { - if (!parseAnyContextualModifier()) { - break; - } - } - - const modifier = finishNode(createNode(modifierKind, modifierStart)); - (list || (list = [])).push(modifier); + const pos = getNodePos(); + let list, modifier; + while (modifier = tryParseModifier(permitInvalidConstAsModifier)) { + list = append(list, modifier); } - return list && createNodeArray(list, listPos); + return list && createNodeArray(list, pos); } function parseModifiersForArrowFunction(): NodeArray | undefined { let modifiers: NodeArray | undefined; if (token() === SyntaxKind.AsyncKeyword) { - const modifierStart = scanner.getStartPos(); - const modifierKind = token(); + const pos = getNodePos(); nextToken(); - const modifier = finishNode(createNode(modifierKind, modifierStart)); - modifiers = createNodeArray([modifier], modifierStart); + const modifier = finishNode(factory.createToken(SyntaxKind.AsyncKeyword), pos); + modifiers = createNodeArray([modifier], pos); } return modifiers; } function parseClassElement(): ClassElement { + const pos = getNodePos(); if (token() === SyntaxKind.SemicolonToken) { - const result = createNode(SyntaxKind.SemicolonClassElement); nextToken(); - return finishNode(result); + return finishNode(factory.createSemicolonClassElement(), pos); } - const node = createNodeWithJSDoc(SyntaxKind.Unknown); - node.decorators = parseDecorators(); - node.modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true); + const hasJSDoc = hasPrecedingJSDocComment(); + const decorators = parseDecorators(); + const modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true); if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(node, SyntaxKind.GetAccessor); + return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, SyntaxKind.GetAccessor); } if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(node, SyntaxKind.SetAccessor); + return parseAccessorDeclaration(pos, hasJSDoc, decorators, modifiers, SyntaxKind.SetAccessor); } if (token() === SyntaxKind.ConstructorKeyword || token() === SyntaxKind.StringLiteral) { - const constructorDeclaration = tryParseConstructorDeclaration(node); + const constructorDeclaration = tryParseConstructorDeclaration(pos, hasJSDoc, decorators, modifiers); if (constructorDeclaration) { return constructorDeclaration; } } if (isIndexSignature()) { - return parseIndexSignatureDeclaration(node); + return parseIndexSignatureDeclaration(pos, hasJSDoc, decorators, modifiers); } // It is very important that we check this *after* checking indexers because @@ -6280,22 +6354,22 @@ namespace ts { token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.OpenBracketToken) { - const isAmbient = node.modifiers && some(node.modifiers, isDeclareModifier); + const isAmbient = some(modifiers, isDeclareModifier); if (isAmbient) { - for (const m of node.modifiers!) { - m.flags |= NodeFlags.Ambient; + for (const m of modifiers!) { + (m as Mutable).flags |= NodeFlags.Ambient; } - return doInsideOfContext(NodeFlags.Ambient, () => parsePropertyOrMethodDeclaration(node as PropertyDeclaration | MethodDeclaration)); + return doInsideOfContext(NodeFlags.Ambient, () => parsePropertyOrMethodDeclaration(pos, hasJSDoc, decorators, modifiers)); } else { - return parsePropertyOrMethodDeclaration(node as PropertyDeclaration | MethodDeclaration); + return parsePropertyOrMethodDeclaration(pos, hasJSDoc, decorators, modifiers); } } - if (node.decorators || node.modifiers) { + if (decorators || modifiers) { // treat this as a property declaration with a missing name. - node.name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); - return parsePropertyDeclaration(node); + const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); + return parsePropertyDeclaration(pos, hasJSDoc, decorators, modifiers, name, /*questionToken*/ undefined); } // 'isClassMemberStart' should have hinted not to attempt parsing. @@ -6303,31 +6377,34 @@ namespace ts { } function parseClassExpression(): ClassExpression { - return parseClassDeclarationOrExpression(createNodeWithJSDoc(SyntaxKind.Unknown), SyntaxKind.ClassExpression); + return parseClassDeclarationOrExpression(getNodePos(), hasPrecedingJSDocComment(), /*decorators*/ undefined, /*modifiers*/ undefined, SyntaxKind.ClassExpression); } - function parseClassDeclaration(node: ClassLikeDeclaration): ClassDeclaration { - return parseClassDeclarationOrExpression(node, SyntaxKind.ClassDeclaration); + function parseClassDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ClassDeclaration { + return parseClassDeclarationOrExpression(pos, hasJSDoc, decorators, modifiers, SyntaxKind.ClassDeclaration); } - function parseClassDeclarationOrExpression(node: ClassLikeDeclaration, kind: ClassLikeDeclaration["kind"]): ClassLikeDeclaration { - node.kind = kind; + function parseClassDeclarationOrExpression(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined, kind: ClassLikeDeclaration["kind"]): ClassLikeDeclaration { parseExpected(SyntaxKind.ClassKeyword); - node.name = parseNameOfClassDeclarationOrExpression(); - node.typeParameters = parseTypeParameters(); - node.heritageClauses = parseHeritageClauses(); + const name = parseNameOfClassDeclarationOrExpression(); + const typeParameters = parseTypeParameters(); + const heritageClauses = parseHeritageClauses(); + let members; if (parseExpected(SyntaxKind.OpenBraceToken)) { // ClassTail[Yield,Await] : (Modified) See 14.5 // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } - node.members = parseClassMembers(); + members = parseClassMembers(); parseExpected(SyntaxKind.CloseBraceToken); } else { - node.members = createMissingList(); + members = createMissingList(); } - return finishNode(node); + const node = kind === SyntaxKind.ClassDeclaration + ? factory.createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) + : factory.createClassExpression(decorators, modifiers, name, typeParameters, heritageClauses, members); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function parseNameOfClassDeclarationOrExpression(): Identifier | undefined { @@ -6357,20 +6434,19 @@ namespace ts { } function parseHeritageClause(): HeritageClause { + const pos = getNodePos(); const tok = token(); Debug.assert(tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword); // isListElement() should ensure this. - const node = createNode(SyntaxKind.HeritageClause); - node.token = tok; nextToken(); - node.types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments); - return finishNode(node); + const types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments); + return finishNode(factory.createHeritageClause(tok, types), pos); } function parseExpressionWithTypeArguments(): ExpressionWithTypeArguments { - const node = createNode(SyntaxKind.ExpressionWithTypeArguments); - node.expression = parseLeftHandSideExpressionOrHigher(); - node.typeArguments = tryParseTypeArguments(); - return finishNode(node); + const pos = getNodePos(); + const expression = parseLeftHandSideExpressionOrHigher(); + const typeArguments = tryParseTypeArguments(); + return finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); } function tryParseTypeArguments(): NodeArray | undefined { @@ -6386,25 +6462,25 @@ namespace ts { return parseList(ParsingContext.ClassMembers, parseClassElement); } - function parseInterfaceDeclaration(node: InterfaceDeclaration): InterfaceDeclaration { - node.kind = SyntaxKind.InterfaceDeclaration; + function parseInterfaceDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): InterfaceDeclaration { parseExpected(SyntaxKind.InterfaceKeyword); - node.name = parseIdentifier(); - node.typeParameters = parseTypeParameters(); - node.heritageClauses = parseHeritageClauses(); - node.members = parseObjectTypeMembers(); - return finishNode(node); + const name = parseIdentifier(); + const typeParameters = parseTypeParameters(); + const heritageClauses = parseHeritageClauses(); + const members = parseObjectTypeMembers(); + const node = factory.createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members); + return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseTypeAliasDeclaration(node: TypeAliasDeclaration): TypeAliasDeclaration { - node.kind = SyntaxKind.TypeAliasDeclaration; + function parseTypeAliasDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): TypeAliasDeclaration { parseExpected(SyntaxKind.TypeKeyword); - node.name = parseIdentifier(); - node.typeParameters = parseTypeParameters(); + const name = parseIdentifier(); + const typeParameters = parseTypeParameters(); parseExpected(SyntaxKind.EqualsToken); - node.type = parseType(); + const type = parseType(); parseSemicolon(); - return finishNode(node); + const node = factory.createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); } // In an ambient declaration, the grammar only allows integer literals as initializers. @@ -6412,76 +6488,81 @@ namespace ts { // ConstantEnumMemberSection, which starts at the beginning of an enum declaration // or any time an integer literal initializer is encountered. function parseEnumMember(): EnumMember { - const node = createNodeWithJSDoc(SyntaxKind.EnumMember); - node.name = parsePropertyName(); - node.initializer = allowInAnd(parseInitializer); - return finishNode(node); + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const name = parsePropertyName(); + const initializer = allowInAnd(parseInitializer); + return withJSDoc(finishNode(factory.createEnumMember(name, initializer), pos), hasJSDoc); } - function parseEnumDeclaration(node: EnumDeclaration): EnumDeclaration { - node.kind = SyntaxKind.EnumDeclaration; + function parseEnumDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): EnumDeclaration { parseExpected(SyntaxKind.EnumKeyword); - node.name = parseIdentifier(); + const name = parseIdentifier(); + let members; if (parseExpected(SyntaxKind.OpenBraceToken)) { - node.members = doOutsideOfYieldAndAwaitContext(() => parseDelimitedList(ParsingContext.EnumMembers, parseEnumMember)); + members = doOutsideOfYieldAndAwaitContext(() => parseDelimitedList(ParsingContext.EnumMembers, parseEnumMember)); parseExpected(SyntaxKind.CloseBraceToken); } else { - node.members = createMissingList(); + members = createMissingList(); } - return finishNode(node); + const node = factory.createEnumDeclaration(decorators, modifiers, name, members); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function parseModuleBlock(): ModuleBlock { - const node = createNode(SyntaxKind.ModuleBlock); + const pos = getNodePos(); + let statements; if (parseExpected(SyntaxKind.OpenBraceToken)) { - node.statements = parseList(ParsingContext.BlockStatements, parseStatement); + statements = parseList(ParsingContext.BlockStatements, parseStatement); parseExpected(SyntaxKind.CloseBraceToken); } else { - node.statements = createMissingList(); + statements = createMissingList(); } - return finishNode(node); + return finishNode(factory.createModuleBlock(statements), pos); } - function parseModuleOrNamespaceDeclaration(node: ModuleDeclaration, flags: NodeFlags): ModuleDeclaration { - node.kind = SyntaxKind.ModuleDeclaration; + function parseModuleOrNamespaceDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined, flags: NodeFlags): ModuleDeclaration { // If we are parsing a dotted namespace name, we want to // propagate the 'Namespace' flag across the names if set. const namespaceFlag = flags & NodeFlags.Namespace; - node.flags |= flags; - node.name = parseIdentifier(); - node.body = parseOptional(SyntaxKind.DotToken) - ? parseModuleOrNamespaceDeclaration(createNode(SyntaxKind.Unknown), NodeFlags.NestedNamespace | namespaceFlag) + const name = parseIdentifier(); + const body = parseOptional(SyntaxKind.DotToken) + ? parseModuleOrNamespaceDeclaration(getNodePos(), /*hasJSDoc*/ false, /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag) : parseModuleBlock(); - return finishNode(node); + const node = factory.createModuleDeclaration(decorators, modifiers, name, body, flags); + return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseAmbientExternalModuleDeclaration(node: ModuleDeclaration): ModuleDeclaration { - node.kind = SyntaxKind.ModuleDeclaration; + function parseAmbientExternalModuleDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ModuleDeclaration { + let flags: NodeFlags = 0; + let name; if (token() === SyntaxKind.GlobalKeyword) { // parse 'global' as name of global scope augmentation - node.name = parseIdentifier(); - node.flags |= NodeFlags.GlobalAugmentation; + name = parseIdentifier(); + flags |= NodeFlags.GlobalAugmentation; } else { - node.name = parseLiteralNode(); - node.name.text = internIdentifier(node.name.text); + name = parseLiteralNode(); + name.text = internIdentifier(name.text); } + let body: ModuleBlock | undefined; if (token() === SyntaxKind.OpenBraceToken) { - node.body = parseModuleBlock(); + body = parseModuleBlock(); } else { parseSemicolon(); } - return finishNode(node); + const node = factory.createModuleDeclaration(decorators, modifiers, name, body, flags); + return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseModuleDeclaration(node: ModuleDeclaration): ModuleDeclaration { + function parseModuleDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ModuleDeclaration { let flags: NodeFlags = 0; if (token() === SyntaxKind.GlobalKeyword) { // global augmentation - return parseAmbientExternalModuleDeclaration(node); + return parseAmbientExternalModuleDeclaration(pos, hasJSDoc, decorators, modifiers); } else if (parseOptional(SyntaxKind.NamespaceKeyword)) { flags |= NodeFlags.Namespace; @@ -6489,10 +6570,10 @@ namespace ts { else { parseExpected(SyntaxKind.ModuleKeyword); if (token() === SyntaxKind.StringLiteral) { - return parseAmbientExternalModuleDeclaration(node); + return parseAmbientExternalModuleDeclaration(pos, hasJSDoc, decorators, modifiers); } } - return parseModuleOrNamespaceDeclaration(node, flags); + return parseModuleOrNamespaceDeclaration(pos, hasJSDoc, decorators, modifiers, flags); } function isExternalModuleReference() { @@ -6508,16 +6589,19 @@ namespace ts { return nextToken() === SyntaxKind.SlashToken; } - function parseNamespaceExportDeclaration(node: NamespaceExportDeclaration): NamespaceExportDeclaration { - node.kind = SyntaxKind.NamespaceExportDeclaration; + function parseNamespaceExportDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): NamespaceExportDeclaration { parseExpected(SyntaxKind.AsKeyword); parseExpected(SyntaxKind.NamespaceKeyword); - node.name = parseIdentifier(); + const name = parseIdentifier(); parseSemicolon(); - return finishNode(node); + const node = factory.createNamespaceExportDeclaration(name); + // NamespaceExportDeclaration nodes cannot have decorators or modifiers, so we attach them here so we can report them in the grammar checker + node.decorators = decorators; + node.modifiers = modifiers; + return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseImportDeclarationOrImportEqualsDeclaration(node: ImportEqualsDeclaration | ImportDeclaration): ImportEqualsDeclaration | ImportDeclaration { + function parseImportDeclarationOrImportEqualsDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ImportEqualsDeclaration | ImportDeclaration { parseExpected(SyntaxKind.ImportKeyword); const afterImportPos = scanner.getStartPos(); @@ -6536,25 +6620,25 @@ namespace ts { } if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration()) { - return parseImportEqualsDeclaration(node, identifier, isTypeOnly); + return parseImportEqualsDeclaration(pos, hasJSDoc, decorators, modifiers, identifier, isTypeOnly); } - // Import statement - node.kind = SyntaxKind.ImportDeclaration; // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; + let importClause: ImportClause | undefined; if (identifier || // import id - token() === SyntaxKind.AsteriskToken || // import * + token() === SyntaxKind.AsteriskToken || // import * token() === SyntaxKind.OpenBraceToken // import { ) { - (node).importClause = parseImportClause(identifier, afterImportPos, isTypeOnly); + importClause = parseImportClause(identifier, afterImportPos, isTypeOnly); parseExpected(SyntaxKind.FromKeyword); } - (node).moduleSpecifier = parseModuleSpecifier(); + const moduleSpecifier = parseModuleSpecifier(); parseSemicolon(); - return finishNode(node); + const node = factory.createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function tokenAfterImportDefinitelyProducesImportDeclaration() { @@ -6567,20 +6651,19 @@ namespace ts { return token() === SyntaxKind.CommaToken || token() === SyntaxKind.FromKeyword; } - function parseImportEqualsDeclaration(node: ImportEqualsDeclaration, identifier: Identifier, isTypeOnly: boolean): ImportEqualsDeclaration { - node.kind = SyntaxKind.ImportEqualsDeclaration; - node.name = identifier; + function parseImportEqualsDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined, identifier: Identifier, isTypeOnly: boolean): ImportEqualsDeclaration { parseExpected(SyntaxKind.EqualsToken); - node.moduleReference = parseModuleReference(); + const moduleReference = parseModuleReference(); parseSemicolon(); - const finished = finishNode(node); + const node = factory.createImportEqualsDeclaration(decorators, modifiers, identifier, moduleReference); + const finished = withJSDoc(finishNode(node, pos), hasJSDoc); if (isTypeOnly) { parseErrorAtRange(finished, Diagnostics.Only_ECMAScript_imports_may_use_import_type); } return finished; } - function parseImportClause(identifier: Identifier | undefined, fullStart: number, isTypeOnly: boolean) { + function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean) { // ImportClause: // ImportedDefaultBinding // NameSpaceImport @@ -6588,23 +6671,15 @@ namespace ts { // ImportedDefaultBinding, NameSpaceImport // ImportedDefaultBinding, NamedImports - const importClause = createNode(SyntaxKind.ImportClause, fullStart); - importClause.isTypeOnly = isTypeOnly; - - if (identifier) { - // ImportedDefaultBinding: - // ImportedBinding - importClause.name = identifier; - } - // If there was no default import or if there is comma token after default import // parse namespace or named imports - if (!importClause.name || + let namedBindings: NamespaceImport | NamedImports | undefined; + if (!identifier || parseOptional(SyntaxKind.CommaToken)) { - importClause.namedBindings = token() === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(SyntaxKind.NamedImports); + namedBindings = token() === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(SyntaxKind.NamedImports); } - return finishNode(importClause); + return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings), pos); } function parseModuleReference() { @@ -6614,12 +6689,12 @@ namespace ts { } function parseExternalModuleReference() { - const node = createNode(SyntaxKind.ExternalModuleReference); + const pos = getNodePos(); parseExpected(SyntaxKind.RequireKeyword); parseExpected(SyntaxKind.OpenParenToken); - node.expression = parseModuleSpecifier(); + const expression = parseModuleSpecifier(); parseExpected(SyntaxKind.CloseParenToken); - return finishNode(node); + return finishNode(factory.createExternalModuleReference(expression), pos); } function parseModuleSpecifier(): Expression { @@ -6639,17 +6714,17 @@ namespace ts { function parseNamespaceImport(): NamespaceImport { // NameSpaceImport: // * as ImportedBinding - const namespaceImport = createNode(SyntaxKind.NamespaceImport); + const pos = getNodePos(); parseExpected(SyntaxKind.AsteriskToken); parseExpected(SyntaxKind.AsKeyword); - namespaceImport.name = parseIdentifier(); - return finishNode(namespaceImport); + const name = parseIdentifier(); + return finishNode(factory.createNamespaceImport(name), pos); } function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports; function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports; function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports { - const node = createNode(kind); + const pos = getNodePos(); // NamedImports: // { } @@ -6659,22 +6734,22 @@ namespace ts { // ImportsList: // ImportSpecifier // ImportsList, ImportSpecifier - node.elements = | NodeArray>parseBracketedList(ParsingContext.ImportOrExportSpecifiers, - kind === SyntaxKind.NamedImports ? parseImportSpecifier : parseExportSpecifier, - SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken); - return finishNode(node); + const node = kind === SyntaxKind.NamedImports + ? factory.createNamedImports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseImportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken)) + : factory.createNamedExports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseExportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken)); + return finishNode(node, pos); } function parseExportSpecifier() { - return parseImportOrExportSpecifier(SyntaxKind.ExportSpecifier); + return parseImportOrExportSpecifier(SyntaxKind.ExportSpecifier) as ExportSpecifier; } function parseImportSpecifier() { - return parseImportOrExportSpecifier(SyntaxKind.ImportSpecifier); + return parseImportOrExportSpecifier(SyntaxKind.ImportSpecifier) as ImportSpecifier; } function parseImportOrExportSpecifier(kind: SyntaxKind): ImportOrExportSpecifier { - const node = createNode(kind); + const pos = getNodePos(); // ImportSpecifier: // BindingIdentifier // IdentifierName as BindingIdentifier @@ -6685,65 +6760,71 @@ namespace ts { let checkIdentifierStart = scanner.getTokenPos(); let checkIdentifierEnd = scanner.getTextPos(); const identifierName = parseIdentifierName(); + let propertyName: Identifier | undefined; + let name: Identifier; if (token() === SyntaxKind.AsKeyword) { - node.propertyName = identifierName; + propertyName = identifierName; parseExpected(SyntaxKind.AsKeyword); checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); checkIdentifierStart = scanner.getTokenPos(); checkIdentifierEnd = scanner.getTextPos(); - node.name = parseIdentifierName(); + name = parseIdentifierName(); } else { - node.name = identifierName; + name = identifierName; } if (kind === SyntaxKind.ImportSpecifier && checkIdentifierIsKeyword) { parseErrorAt(checkIdentifierStart, checkIdentifierEnd, Diagnostics.Identifier_expected); } - return finishNode(node); + const node = kind === SyntaxKind.ImportSpecifier + ? factory.createImportSpecifier(propertyName, name) + : factory.createExportSpecifier(propertyName, name); + return finishNode(node, pos); } function parseNamespaceExport(pos: number): NamespaceExport { - const node = createNode(SyntaxKind.NamespaceExport, pos); - node.name = parseIdentifier(); - return finishNode(node); + return finishNode(factory.createNamespaceExport(parseIdentifier()), pos); } - function parseExportDeclaration(node: ExportDeclaration): ExportDeclaration { - node.kind = SyntaxKind.ExportDeclaration; - node.isTypeOnly = parseOptional(SyntaxKind.TypeKeyword); - const namespaceExportPos = scanner.getStartPos(); + function parseExportDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ExportDeclaration { + let exportClause: NamedExportBindings | undefined; + let moduleSpecifier: Expression | undefined; + const isTypeOnly = parseOptional(SyntaxKind.TypeKeyword); + const namespaceExportPos = getNodePos(); if (parseOptional(SyntaxKind.AsteriskToken)) { if (parseOptional(SyntaxKind.AsKeyword)) { - node.exportClause = parseNamespaceExport(namespaceExportPos); + exportClause = parseNamespaceExport(namespaceExportPos); } parseExpected(SyntaxKind.FromKeyword); - node.moduleSpecifier = parseModuleSpecifier(); + moduleSpecifier = parseModuleSpecifier(); } else { - node.exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); + exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. if (token() === SyntaxKind.FromKeyword || (token() === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { parseExpected(SyntaxKind.FromKeyword); - node.moduleSpecifier = parseModuleSpecifier(); + moduleSpecifier = parseModuleSpecifier(); } } parseSemicolon(); - return finishNode(node); + const node = factory.createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier); + return withJSDoc(finishNode(node, pos), hasJSDoc); } - function parseExportAssignment(node: ExportAssignment): ExportAssignment { - node.kind = SyntaxKind.ExportAssignment; + function parseExportAssignment(pos: number, hasJSDoc: boolean, decorators: NodeArray | undefined, modifiers: NodeArray | undefined): ExportAssignment { + let isExportEquals: boolean | undefined; if (parseOptional(SyntaxKind.EqualsToken)) { - node.isExportEquals = true; + isExportEquals = true; } else { parseExpected(SyntaxKind.DefaultKeyword); } - node.expression = parseAssignmentExpressionOrHigher(); + const expression = parseAssignmentExpressionOrHigher(); parseSemicolon(); - return finishNode(node); + const node = factory.createExportAssignment(decorators, modifiers, isExportEquals, expression); + return withJSDoc(finishNode(node, pos), hasJSDoc); } function setExternalModuleIndicator(sourceFile: SourceFile) { @@ -6756,10 +6837,10 @@ namespace ts { function isAnExternalModuleIndicatorNode(node: Node) { return hasModifierOfKind(node, SyntaxKind.ExportKeyword) - || node.kind === SyntaxKind.ImportEqualsDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference - || node.kind === SyntaxKind.ImportDeclaration - || node.kind === SyntaxKind.ExportAssignment - || node.kind === SyntaxKind.ExportDeclaration ? node : undefined; + || isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) + || isImportDeclaration(node) + || isExportAssignment(node) + || isExportDeclaration(node) ? node : undefined; } function getImportMetaIfNecessary(sourceFile: SourceFile) { @@ -6817,12 +6898,17 @@ namespace ts { export namespace JSDocParser { export function parseJSDocTypeExpressionForTests(content: string, start: number | undefined, length: number | undefined): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined { - initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); - sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false); + initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); scanner.setText(content, start, length); currentToken = scanner.scan(); const jsDocTypeExpression = parseJSDocTypeExpression(); - const diagnostics = parseDiagnostics; + + const sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false, [], factory.createToken(SyntaxKind.EndOfFileToken), NodeFlags.None); + const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + if (jsDocDiagnostics) { + sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + } + clearState(); return jsDocTypeExpression ? { jsDocTypeExpression, diagnostics } : undefined; @@ -6830,23 +6916,24 @@ namespace ts { // Parses out a JSDoc type expression. export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression { - const result = createNode(SyntaxKind.JSDocTypeExpression); - + const pos = getNodePos(); const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken); - result.type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); + const type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); if (!mayOmitBraces || hasBrace) { parseExpectedJSDoc(SyntaxKind.CloseBraceToken); } + const result = factory.createJSDocTypeExpression(type); fixupParentReferences(result); - return finishNode(result); + return finishNode(result, pos); } export function parseIsolatedJSDocComment(content: string, start: number | undefined, length: number | undefined): { jsDoc: JSDoc, diagnostics: Diagnostic[] } | undefined { - initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); - sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; + initializeState("", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); const jsDoc = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); - const diagnostics = parseDiagnostics; + + const sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; + const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); clearState(); return jsDoc ? { jsDoc, diagnostics } : undefined; @@ -6858,20 +6945,17 @@ namespace ts { const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; const comment = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); - if (comment) { - comment.parent = parent; - } + setParent(comment, parent); if (contextFlags & NodeFlags.JavaScriptFile) { - if (!sourceFile.jsDocDiagnostics) { - sourceFile.jsDocDiagnostics = []; + if (!jsDocDiagnostics) { + jsDocDiagnostics = []; } - sourceFile.jsDocDiagnostics.push(...parseDiagnostics); + jsDocDiagnostics.push(...parseDiagnostics); } currentToken = saveToken; parseDiagnostics.length = saveParseDiagnosticsLength; parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; - return comment; } @@ -7004,10 +7088,9 @@ namespace ts { } function createJSDocComment(): JSDoc { - const result = createNode(SyntaxKind.JSDocComment, start); - result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd); - result.comment = comments.length ? comments.join("") : undefined; - return finishNode(result, end); + const comment = comments.length ? comments.join("") : undefined; + const tagsArray = tags && createNodeArray(tags, tagsPos, tagsEnd); + return finishNode(factory.createJSDocComment(comment, tagsArray), start, end); } function isNextNonwhitespaceTokenEndOfFile(): boolean { @@ -7070,36 +7153,36 @@ namespace ts { let tag: JSDocTag | undefined; switch (tagName.escapedText) { case "author": - tag = parseAuthorTag(start, tagName, margin); + tag = parseAuthorTag(start, tagName, margin, indentText); break; case "implements": - tag = parseImplementsTag(start, tagName); + tag = parseImplementsTag(start, tagName, margin, indentText); break; case "augments": case "extends": - tag = parseAugmentsTag(start, tagName); + tag = parseAugmentsTag(start, tagName, margin, indentText); break; case "class": case "constructor": - tag = parseSimpleTag(start, SyntaxKind.JSDocClassTag, tagName); + tag = parseSimpleTag(start, factory.createJSDocClassTag, tagName, margin, indentText); break; case "public": - tag = parseSimpleTag(start, SyntaxKind.JSDocPublicTag, tagName); + tag = parseSimpleTag(start, factory.createJSDocPublicTag, tagName, margin, indentText); break; case "private": - tag = parseSimpleTag(start, SyntaxKind.JSDocPrivateTag, tagName); + tag = parseSimpleTag(start, factory.createJSDocPrivateTag, tagName, margin, indentText); break; case "protected": - tag = parseSimpleTag(start, SyntaxKind.JSDocProtectedTag, tagName); + tag = parseSimpleTag(start, factory.createJSDocProtectedTag, tagName, margin, indentText); break; case "readonly": - tag = parseSimpleTag(start, SyntaxKind.JSDocReadonlyTag, tagName); + tag = parseSimpleTag(start, factory.createJSDocReadonlyTag, tagName, margin, indentText); break; case "this": - tag = parseThisTag(start, tagName); + tag = parseThisTag(start, tagName, margin, indentText); break; case "enum": - tag = parseEnumTag(start, tagName); + tag = parseEnumTag(start, tagName, margin, indentText); break; case "arg": case "argument": @@ -7107,33 +7190,33 @@ namespace ts { return parseParameterOrPropertyTag(start, tagName, PropertyLikeParse.Parameter, margin); case "return": case "returns": - tag = parseReturnTag(start, tagName); + tag = parseReturnTag(start, tagName, margin, indentText); break; case "template": - tag = parseTemplateTag(start, tagName); + tag = parseTemplateTag(start, tagName, margin, indentText); break; case "type": - tag = parseTypeTag(start, tagName); + tag = parseTypeTag(start, tagName, margin, indentText); break; case "typedef": - tag = parseTypedefTag(start, tagName, margin); + tag = parseTypedefTag(start, tagName, margin, indentText); break; case "callback": - tag = parseCallbackTag(start, tagName, margin); + tag = parseCallbackTag(start, tagName, margin, indentText); break; default: - tag = parseUnknownTag(start, tagName); + tag = parseUnknownTag(start, tagName, margin, indentText); break; } + return tag; + } - if (!tag.comment) { - // some tags, like typedef and callback, have already parsed their comments earlier - if (!indentText) { - margin += tag.end - tag.pos; - } - tag.comment = parseTagComments(margin, indentText.slice(margin)); + function parseTrailingTagComments(pos: number, end: number, margin: number, indentText: string) { + // some tags, like typedef and callback, have already parsed their comments earlier + if (!indentText) { + margin += end - pos; } - return tag; + return parseTagComments(margin, indentText.slice(margin)); } function parseTagComments(indent: number, initialMargin?: string): string | undefined { @@ -7231,10 +7314,9 @@ namespace ts { return comments.length === 0 ? undefined : comments.join(""); } - function parseUnknownTag(start: number, tagName: Identifier) { - const result = createNode(SyntaxKind.JSDocTag, start); - result.tagName = tagName; - return finishNode(result); + function parseUnknownTag(start: number, tagName: Identifier, indent: number, indentText: string) { + const end = getNodePos(); + return finishNode(factory.createJSDocUnknownTag(tagName, parseTrailingTagComments(start, end, indent, indentText)), start, end); } function addTag(tag: JSDocTag | undefined): void { @@ -7304,30 +7386,22 @@ namespace ts { typeExpression = tryParseTypeExpression(); } - const result = target === PropertyLikeParse.Property ? - createNode(SyntaxKind.JSDocPropertyTag, start) : - createNode(SyntaxKind.JSDocParameterTag, start); const comment = parseTagComments(indent + scanner.getStartPos() - start); const nestedTypeLiteral = target !== PropertyLikeParse.CallbackParameter && parseNestedTypeLiteral(typeExpression, name, target, indent); if (nestedTypeLiteral) { typeExpression = nestedTypeLiteral; isNameFirst = true; } - result.tagName = tagName; - result.typeExpression = typeExpression; - result.name = name; - result.isNameFirst = isNameFirst; - result.isBracketed = isBracketed; - result.comment = comment; - return finishNode(result); + const result = target === PropertyLikeParse.Property + ? factory.createJSDocPropertyTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment) + : factory.createJSDocParameterTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment); + return finishNode(result, start); } function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse, indent: number) { if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) { - const typeLiteralExpression = createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos()); + const pos = getNodePos(); let child: JSDocPropertyLikeTag | JSDocTypeTag | false; - let jsdocTypeLiteral: JSDocTypeLiteral; - const start = scanner.getStartPos(); let children: JSDocPropertyLikeTag[] | undefined; while (child = tryParse(() => parseChildParameterOrPropertyTag(target, indent, name))) { if (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) { @@ -7335,58 +7409,49 @@ namespace ts { } } if (children) { - jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); - jsdocTypeLiteral.jsDocPropertyTags = children; - if (typeExpression.type.kind === SyntaxKind.ArrayType) { - jsdocTypeLiteral.isArrayType = true; - } - typeLiteralExpression.type = finishNode(jsdocTypeLiteral); - return finishNode(typeLiteralExpression); + const literal = finishNode(factory.createJSDocTypeLiteral(children, typeExpression.type.kind === SyntaxKind.ArrayType), pos); + return finishNode(factory.createJSDocTypeExpression(literal), pos); } } } - function parseReturnTag(start: number, tagName: Identifier): JSDocReturnTag { + function parseReturnTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocReturnTag { if (some(tags, isJSDocReturnTag)) { parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText); } - const result = createNode(SyntaxKind.JSDocReturnTag, start); - result.tagName = tagName; - result.typeExpression = tryParseTypeExpression(); - return finishNode(result); + const typeExpression = tryParseTypeExpression(); + const end = getNodePos(); + return finishNode(factory.createJSDocReturnTag(tagName, typeExpression, parseTrailingTagComments(start, end, indent, indentText)), start, end); } - function parseTypeTag(start: number, tagName: Identifier): JSDocTypeTag { + function parseTypeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocTypeTag { if (some(tags, isJSDocTypeTag)) { parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText); } - const result = createNode(SyntaxKind.JSDocTypeTag, start); - result.tagName = tagName; - result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); - return finishNode(result); + const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); + const end = getNodePos(); + const comments = indent !== undefined && indentText !== undefined ? parseTrailingTagComments(start, end, indent, indentText) : undefined; + return finishNode(factory.createJSDocTypeTag(tagName, typeExpression, comments), start, end); } - function parseAuthorTag(start: number, tagName: Identifier, indent: number): JSDocAuthorTag { - const result = createNode(SyntaxKind.JSDocAuthorTag, start); - result.tagName = tagName; - + function parseAuthorTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocAuthorTag { const authorInfoWithEmail = tryParse(() => tryParseAuthorNameAndEmail()); if (!authorInfoWithEmail) { - return finishNode(result); + const end = getNodePos(); + return finishNode(factory.createJSDocAuthorTag(tagName, parseTrailingTagComments(start, end, indent, indentText)), start, end); } - result.comment = authorInfoWithEmail; - + let comments = authorInfoWithEmail; if (lookAhead(() => nextToken() !== SyntaxKind.NewLineTrivia)) { const comment = parseTagComments(indent); if (comment) { - result.comment += comment; + comments += comment; } } - return finishNode(result); + return finishNode(factory.createJSDocAuthorTag(tagName, comments), start); } function tryParseAuthorNameAndEmail(): string | undefined { @@ -7431,26 +7496,25 @@ namespace ts { } } - function parseImplementsTag(start: number, tagName: Identifier): JSDocImplementsTag { - const result = createNode(SyntaxKind.JSDocImplementsTag, start); - result.tagName = tagName; - result.class = parseExpressionWithTypeArgumentsForAugments(); - return finishNode(result); + function parseImplementsTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocImplementsTag { + const className = parseExpressionWithTypeArgumentsForAugments(); + const end = getNodePos(); + return finishNode(factory.createJSDocImplementsTag(tagName, className, parseTrailingTagComments(start, end, margin, indentText)), start, end); } - function parseAugmentsTag(start: number, tagName: Identifier): JSDocAugmentsTag { - const result = createNode(SyntaxKind.JSDocAugmentsTag, start); - result.tagName = tagName; - result.class = parseExpressionWithTypeArgumentsForAugments(); - return finishNode(result); + function parseAugmentsTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocAugmentsTag { + const className = parseExpressionWithTypeArgumentsForAugments(); + const end = getNodePos(); + return finishNode(factory.createJSDocAugmentsTag(tagName, className, parseTrailingTagComments(start, end, margin, indentText)), start, end); } function parseExpressionWithTypeArgumentsForAugments(): ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression } { const usedBrace = parseOptional(SyntaxKind.OpenBraceToken); - const node = createNode(SyntaxKind.ExpressionWithTypeArguments) as ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression }; - node.expression = parsePropertyAccessEntityNameExpression(); - node.typeArguments = tryParseTypeArguments(); - const res = finishNode(node); + const pos = getNodePos(); + const expression = parsePropertyAccessEntityNameExpression(); + const typeArguments = tryParseTypeArguments(); + const node = factory.createExpressionWithTypeArguments(expression, typeArguments) as ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression }; + const res = finishNode(node, pos); if (usedBrace) { parseExpected(SyntaxKind.CloseBraceToken); } @@ -7458,59 +7522,50 @@ namespace ts { } function parsePropertyAccessEntityNameExpression() { + const pos = getNodePos(); let node: Identifier | PropertyAccessEntityNameExpression = parseJSDocIdentifierName(); while (parseOptional(SyntaxKind.DotToken)) { - const prop: PropertyAccessEntityNameExpression = createNode(SyntaxKind.PropertyAccessExpression, node.pos) as PropertyAccessEntityNameExpression; - prop.expression = node; - prop.name = parseJSDocIdentifierName(); - node = finishNode(prop); + const name = parseJSDocIdentifierName(); + node = finishNode(factory.createPropertyAccessExpression(node, name), pos) as PropertyAccessEntityNameExpression; } return node; } - function parseSimpleTag(start: number, kind: SyntaxKind, tagName: Identifier): JSDocTag { - const tag = createNode(kind, start); - tag.tagName = tagName; - return finishNode(tag); + function parseSimpleTag(start: number, createTag: (tagName: Identifier | undefined, comment?: string) => JSDocTag, tagName: Identifier, margin: number, indentText: string): JSDocTag { + const end = getNodePos(); + return finishNode(createTag(tagName, parseTrailingTagComments(start, end, margin, indentText)), start, end); } - function parseThisTag(start: number, tagName: Identifier): JSDocThisTag { - const tag = createNode(SyntaxKind.JSDocThisTag, start); - tag.tagName = tagName; - tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); + function parseThisTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocThisTag { + const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); skipWhitespace(); - return finishNode(tag); + const end = getNodePos(); + return finishNode(factory.createJSDocThisTag(tagName, typeExpression, parseTrailingTagComments(start, end, margin, indentText)), start, end); } - function parseEnumTag(start: number, tagName: Identifier): JSDocEnumTag { - const tag = createNode(SyntaxKind.JSDocEnumTag, start); - tag.tagName = tagName; - tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); + function parseEnumTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocEnumTag { + const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); skipWhitespace(); - return finishNode(tag); + const end = getNodePos(); + return finishNode(factory.createJSDocEnumTag(tagName, typeExpression, parseTrailingTagComments(start, end, margin, indentText)), start, end); } - function parseTypedefTag(start: number, tagName: Identifier, indent: number): JSDocTypedefTag { - const typeExpression = tryParseTypeExpression(); + function parseTypedefTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocTypedefTag { + let typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined = tryParseTypeExpression(); skipWhitespaceOrAsterisk(); - const typedefTag = createNode(SyntaxKind.JSDocTypedefTag, start); - typedefTag.tagName = tagName; - typedefTag.fullName = parseJSDocTypeNameWithNamespace(); - typedefTag.name = getJSDocTypeAliasName(typedefTag.fullName); + const fullName = parseJSDocTypeNameWithNamespace(); skipWhitespace(); - typedefTag.comment = parseTagComments(indent); + let comment = parseTagComments(indent); - typedefTag.typeExpression = typeExpression; let end: number | undefined; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { let child: JSDocTypeTag | JSDocPropertyTag | false; - let jsdocTypeLiteral: JSDocTypeLiteral | undefined; let childTypeTag: JSDocTypeTag | undefined; + let jsDocPropertyTags: JSDocPropertyTag[] | undefined; + let hasChildren = false; while (child = tryParse(() => parseChildPropertyTag(indent))) { - if (!jsdocTypeLiteral) { - jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); - } + hasChildren = true; if (child.kind === SyntaxKind.JSDocTypeTag) { if (childTypeTag) { parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags); @@ -7518,7 +7573,7 @@ namespace ts { if (lastError) { addRelatedInfo( lastError, - createDiagnosticForNode(sourceFile, Diagnostics.The_tag_was_first_specified_here) + createDetachedDiagnostic(fileName, 0, 0, Diagnostics.The_tag_was_first_specified_here) ); } break; @@ -7528,22 +7583,30 @@ namespace ts { } } else { - jsdocTypeLiteral.jsDocPropertyTags = append(jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray, child); + jsDocPropertyTags = append(jsDocPropertyTags, child); } } - if (jsdocTypeLiteral) { - if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) { - jsdocTypeLiteral.isArrayType = true; - } - typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + if (hasChildren) { + const isArrayType = typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType; + const jsdocTypeLiteral = factory.createJSDocTypeLiteral(jsDocPropertyTags, isArrayType); + typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? childTypeTag.typeExpression : - finishNode(jsdocTypeLiteral); - end = typedefTag.typeExpression.end; + finishNode(jsdocTypeLiteral, start); + end = typeExpression.end; } } // Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace - return finishNode(typedefTag, end || typedefTag.comment !== undefined ? scanner.getStartPos() : (typedefTag.fullName || typedefTag.typeExpression || typedefTag.tagName).end); + end = end || comment !== undefined ? + getNodePos() : + (fullName ?? typeExpression ?? tagName).end; + + if (!comment) { + comment = parseTrailingTagComments(start, end, indent, indentText); + } + + const typedefTag = factory.createJSDocTypedefTag(tagName, typeExpression, fullName, comment); + return finishNode(typedefTag, start, end); } function parseJSDocTypeNameWithNamespace(nested?: boolean) { @@ -7553,13 +7616,15 @@ namespace ts { } const typeNameOrNamespaceName = parseJSDocIdentifierName(); if (parseOptional(SyntaxKind.DotToken)) { - const jsDocNamespaceNode = createNode(SyntaxKind.ModuleDeclaration, pos); - if (nested) { - jsDocNamespaceNode.flags |= NodeFlags.NestedNamespace; - } - jsDocNamespaceNode.name = typeNameOrNamespaceName; - jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(/*nested*/ true); - return finishNode(jsDocNamespaceNode); + const body = parseJSDocTypeNameWithNamespace(/*nested*/ true); + const jsDocNamespaceNode = factory.createModuleDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + typeNameOrNamespaceName, + body, + nested ? NodeFlags.NestedNamespace : undefined + ) as JSDocNamespaceDeclaration; + return finishNode(jsDocNamespaceNode, pos); } if (nested) { @@ -7568,20 +7633,22 @@ namespace ts { return typeNameOrNamespaceName; } - function parseCallbackTag(start: number, tagName: Identifier, indent: number): JSDocCallbackTag { - const callbackTag = createNode(SyntaxKind.JSDocCallbackTag, start) as JSDocCallbackTag; - callbackTag.tagName = tagName; - callbackTag.fullName = parseJSDocTypeNameWithNamespace(); - callbackTag.name = getJSDocTypeAliasName(callbackTag.fullName); - skipWhitespace(); - callbackTag.comment = parseTagComments(indent); + function parseCallbackTagParameters(indent: number) { + const pos = getNodePos(); let child: JSDocParameterTag | false; - const jsdocSignature = createNode(SyntaxKind.JSDocSignature, start) as JSDocSignature; - jsdocSignature.parameters = []; + let parameters; while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as JSDocParameterTag)) { - jsdocSignature.parameters = append(jsdocSignature.parameters as MutableNodeArray, child); + parameters = append(parameters, child); } + return createNodeArray(parameters || [], pos); + } + + function parseCallbackTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocCallbackTag { + const fullName = parseJSDocTypeNameWithNamespace(); + skipWhitespace(); + let comment = parseTagComments(indent); + const parameters = parseCallbackTagParameters(indent); const returnTag = tryParse(() => { if (parseOptionalJsdoc(SyntaxKind.AtToken)) { const tag = parseTag(indent); @@ -7590,23 +7657,12 @@ namespace ts { } } }); - if (returnTag) { - jsdocSignature.type = returnTag; - } - callbackTag.typeExpression = finishNode(jsdocSignature); - return finishNode(callbackTag); - } - - function getJSDocTypeAliasName(fullName: JSDocNamespaceBody | undefined) { - if (fullName) { - let rightNode = fullName; - while (true) { - if (ts.isIdentifier(rightNode) || !rightNode.body) { - return ts.isIdentifier(rightNode) ? rightNode : rightNode.name; - } - rightNode = rightNode.body; - } + const typeExpression = finishNode(factory.createJSDocSignature(/*typeParameters*/ undefined, parameters, returnTag), start); + const end = getNodePos(); + if (!comment) { + comment = parseTrailingTagComments(start, end, indent, indentText); } + return finishNode(factory.createJSDocCallbackTag(tagName, typeExpression, fullName, comment), start, end); } function escapedTextsEqual(a: EntityName, b: EntityName): boolean { @@ -7691,30 +7747,39 @@ namespace ts { return parseParameterOrPropertyTag(start, tagName, target, indent); } - function parseTemplateTag(start: number, tagName: Identifier): JSDocTemplateTag { - // the template tag looks like '@template {Constraint} T,U,V' - let constraint: JSDocTypeExpression | undefined; - if (token() === SyntaxKind.OpenBraceToken) { - constraint = parseJSDocTypeExpression(); - } + function parseTemplateTagTypeParameter() { + const typeParameterPos = getNodePos(); + const name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); + return finishNode(factory.createTypeParameterDeclaration(name, /*constraint*/ undefined, /*defaultType*/ undefined), typeParameterPos); + } + function parseTemplateTagTypeParameters() { + const pos = getNodePos(); const typeParameters = []; - const typeParametersPos = getNodePos(); do { skipWhitespace(); - const typeParameter = createNode(SyntaxKind.TypeParameter); - typeParameter.name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); - finishNode(typeParameter); + typeParameters.push(parseTemplateTagTypeParameter()); skipWhitespaceOrAsterisk(); - typeParameters.push(typeParameter); } while (parseOptionalJsdoc(SyntaxKind.CommaToken)); + return createNodeArray(typeParameters, pos); + } - const result = createNode(SyntaxKind.JSDocTemplateTag, start); - result.tagName = tagName; - result.constraint = constraint; - result.typeParameters = createNodeArray(typeParameters, typeParametersPos); - finishNode(result); - return result; + function parseTemplateTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocTemplateTag { + // The template tag looks like one of the following: + // @template T,U,V + // @template {Constraint} T + // + // According to the [closure docs](https://github.com/google/closure-compiler/wiki/Generic-Types#multiple-bounded-template-types): + // > Multiple bounded generics cannot be declared on the same line. For the sake of clarity, if multiple templates share the same + // > type bound they must be declared on separate lines. + // + // TODO: Determine whether we should enforce this in the checker. + // TODO: Consider moving the `constraint` to the first type parameter as we could then remove `getEffectiveConstraintOfTypeParameter`. + // TODO: Consider only parsing a single type parameter if there is a constraint. + const constraint = token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; + const typeParameters = parseTemplateTagTypeParameters(); + const end = getNodePos(); + return finishNode(factory.createJSDocTemplateTag(tagName, constraint, typeParameters, parseTrailingTagComments(start, end, indent, indentText)), start, end); } function parseOptionalJsdoc(t: JSDocSyntaxKind): boolean { @@ -7751,13 +7816,9 @@ namespace ts { identifierCount++; const pos = scanner.getTokenPos(); const end = scanner.getTextPos(); - const result = createNode(SyntaxKind.Identifier, pos); - if (token() !== SyntaxKind.Identifier) { - result.originalKeywordKind = token(); - } - result.escapedText = escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue())); - finishNode(result, end); - + const originalKeywordKind = token(); + const text = internIdentifier(scanner.getTokenValue()); + const result = finishNode(factory.createIdentifier(text, /*typeArguments*/ undefined, originalKeywordKind), pos, end); nextTokenJSDoc(); return result; } @@ -7925,8 +7986,7 @@ namespace ts { node._children = undefined; } - node.pos += delta; - node.end += delta; + setTextRangePosEnd(node, node.pos + delta, node.end + delta); if (aggressiveChecks && shouldCheckNode(node)) { Debug.assert(text === newText.substring(node.pos, node.end)); @@ -7943,8 +8003,7 @@ namespace ts { function visitArray(array: IncrementalNodeArray) { array._children = undefined; - array.pos += delta; - array.end += delta; + setTextRangePosEnd(array, array.pos + delta, array.end + delta); for (const node of array) { visitNode(node); @@ -7999,7 +8058,7 @@ namespace ts { // // The element will keep its position if possible. Or Move backward to the new-end // if it's in the 'Y' range. - element.pos = Math.min(element.pos, changeRangeNewEnd); + const pos = Math.min(element.pos, changeRangeNewEnd); // If the 'end' is after the change range, then we always adjust it by the delta // amount. However, if the end is in the change range, then how we adjust it @@ -8021,21 +8080,20 @@ namespace ts { // However any element that ended after that will have their pos adjusted to be // at the end of the new range. i.e. any node that ended in the 'Y' range will // be adjusted to have their end at the end of the 'Z' range. - if (element.end >= changeRangeOldEnd) { + const end = element.end >= changeRangeOldEnd ? // Element ends after the change range. Always adjust the end pos. - element.end += delta; - } - else { + element.end + delta : // Element ends in the change range. The element will keep its position if // possible. Or Move backward to the new-end if it's in the 'Y' range. - element.end = Math.min(element.end, changeRangeNewEnd); - } + Math.min(element.end, changeRangeNewEnd); - Debug.assert(element.pos <= element.end); + Debug.assert(pos <= end); if (element.parent) { - Debug.assert(element.pos >= element.parent.pos); - Debug.assert(element.end <= element.parent.end); + Debug.assert(pos >= element.parent.pos); + Debug.assert(end <= element.parent.end); } + + setTextRangePosEnd(element, pos, end); } function checkNodePositions(node: Node, aggressiveChecks: boolean) { @@ -8265,8 +8323,8 @@ namespace ts { } } - interface IncrementalElement extends TextRange { - parent: Node; + interface IncrementalElement extends ReadonlyTextRange { + readonly parent: Node; intersectsChange: boolean; length?: number; _children: Node[] | undefined; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 85ee7535ef3ed..0664b3483b8fa 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2113,11 +2113,11 @@ namespace ts { && (options.isolatedModules || isExternalModuleFile) && !file.isDeclarationFile) { // synthesize 'import "tslib"' declaration - const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText); - const importDecl = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference); + const externalHelpersModuleReference = factory.createStringLiteral(externalHelpersModuleNameText); + const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference); addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); - externalHelpersModuleReference.parent = importDecl; - importDecl.parent = file; + setParent(externalHelpersModuleReference, importDecl); + setParent(importDecl, file); imports = [externalHelpersModuleReference]; } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 27c88e8e13d84..b578db78ae1f5 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -21,10 +21,14 @@ namespace ts { hasUnicodeEscape(): boolean; hasExtendedUnicodeEscape(): boolean; hasPrecedingLineBreak(): boolean; + /* @internal */ + hasPrecedingJSDocComment(): boolean; isIdentifier(): boolean; isReservedWord(): boolean; isUnterminated(): boolean; /* @internal */ + getNumericLiteralFlags(): TokenFlags; + /* @internal */ getCommentDirectives(): CommentDirective[] | undefined; /* @internal */ getTokenFlags(): TokenFlags; @@ -942,10 +946,12 @@ namespace ts { hasUnicodeEscape: () => (tokenFlags & TokenFlags.UnicodeEscape) !== 0, hasExtendedUnicodeEscape: () => (tokenFlags & TokenFlags.ExtendedUnicodeEscape) !== 0, hasPrecedingLineBreak: () => (tokenFlags & TokenFlags.PrecedingLineBreak) !== 0, + hasPrecedingJSDocComment: () => (tokenFlags & TokenFlags.PrecedingJSDocComment) !== 0, isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord, isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord, isUnterminated: () => (tokenFlags & TokenFlags.Unterminated) !== 0, getCommentDirectives: () => commentDirectives, + getNumericLiteralFlags: () => tokenFlags & TokenFlags.NumericLiteralFlags, getTokenFlags: () => tokenFlags, reScanGreaterToken, reScanSlashToken, diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index bd794d88482fb..2ed0e6ad93162 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -109,11 +109,11 @@ namespace ts { /** * Wrap a transformer factory that may return a custom script or declaration transformer object. */ - function wrapCustomTransformerFactory(transformer: TransformerFactory | CustomTransformerFactory, handleDefault: (node: Transformer) => Transformer): TransformerFactory { + function wrapCustomTransformerFactory(transformer: TransformerFactory | CustomTransformerFactory, handleDefault: (context: TransformationContext, tx: Transformer) => Transformer): TransformerFactory { return context => { const customTransformer = transformer(context); return typeof customTransformer === "function" - ? handleDefault(customTransformer) + ? handleDefault(context, customTransformer) : wrapCustomTransformer(customTransformer); }; } @@ -123,7 +123,7 @@ namespace ts { } function wrapDeclarationTransformerFactory(transformer: TransformerFactory | CustomTransformerFactory): TransformerFactory { - return wrapCustomTransformerFactory(transformer, identity); + return wrapCustomTransformerFactory(transformer, (_, node) => node); } export function noEmitSubstitution(_hint: EmitHint, node: Node) { @@ -144,7 +144,7 @@ namespace ts { * @param transforms An array of `TransformerFactory` callbacks. * @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files. */ - export function transformNodes(resolver: EmitResolver | undefined, host: EmitHost | undefined, options: CompilerOptions, nodes: readonly T[], transformers: readonly TransformerFactory[], allowDtsFiles: boolean): TransformationResult { + export function transformNodes(resolver: EmitResolver | undefined, host: EmitHost | undefined, factory: NodeFactory, options: CompilerOptions, nodes: readonly T[], transformers: readonly TransformerFactory[], allowDtsFiles: boolean): TransformationResult { const enabledSyntaxKindFeatures = new Array(SyntaxKind.Count); let lexicalEnvironmentVariableDeclarations: VariableDeclaration[]; let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[]; @@ -165,9 +165,11 @@ namespace ts { // The transformation context is provided to each transformer as part of transformer // initialization. const context: TransformationContext = { + factory, getCompilerOptions: () => options, getEmitResolver: () => resolver!, // TODO: GH#18217 getEmitHost: () => host!, // TODO: GH#18217 + getEmitHelperFactory: memoize(() => createEmitHelperFactory(context)), startLexicalEnvironment, suspendLexicalEnvironment, resumeLexicalEnvironment, @@ -313,7 +315,7 @@ namespace ts { function hoistVariableDeclaration(name: Identifier): void { Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - const decl = setEmitFlags(createVariableDeclaration(name), EmitFlags.NoNestedSourceMaps); + const decl = setEmitFlags(factory.createVariableDeclaration(name), EmitFlags.NoNestedSourceMaps); if (!lexicalEnvironmentVariableDeclarations) { lexicalEnvironmentVariableDeclarations = [decl]; } @@ -413,9 +415,9 @@ namespace ts { } if (lexicalEnvironmentVariableDeclarations) { - const statement = createVariableStatement( + const statement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList(lexicalEnvironmentVariableDeclarations) + factory.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations) ); setEmitFlags(statement, EmitFlags.CustomPrologue); @@ -504,4 +506,30 @@ namespace ts { } } } + + export const nullTransformationContext: TransformationContext = { + get factory() { return factory; }, + enableEmitNotification: noop, + enableSubstitution: noop, + endLexicalEnvironment: returnUndefined, + getCompilerOptions: () => ({}), + getEmitHost: notImplemented, + getEmitResolver: notImplemented, + getEmitHelperFactory: notImplemented, + setLexicalEnvironmentFlags: noop, + getLexicalEnvironmentFlags: () => 0, + hoistFunctionDeclaration: noop, + hoistVariableDeclaration: noop, + addInitializationStatement: noop, + isEmitNotificationEnabled: notImplemented, + isSubstitutionEnabled: notImplemented, + onEmitNode: noop, + onSubstituteNode: notImplemented, + readEmitHelpers: notImplemented, + requestEmitHelper: noop, + resumeLexicalEnvironment: noop, + startLexicalEnvironment: noop, + suspendLexicalEnvironment: noop, + addDiagnostic: noop, + }; } diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 05b7cda9efc3c..774ded70dfef4 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -33,6 +33,7 @@ namespace ts { */ export function transformClassFields(context: TransformationContext) { const { + factory, hoistVariableDeclaration, endLexicalEnvironment, resumeLexicalEnvironment @@ -65,7 +66,7 @@ namespace ts { const privateIdentifierEnvironmentStack: (PrivateIdentifierEnvironment | undefined)[] = []; let currentPrivateIdentifierEnvironment: PrivateIdentifierEnvironment | undefined; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { const options = context.getCompilerOptions(); @@ -131,7 +132,7 @@ namespace ts { if (!shouldTransformPrivateFields) { return node; } - return setOriginalNode(createIdentifier(""), node); + return setOriginalNode(factory.createIdentifier(""), node); } /** @@ -185,9 +186,9 @@ namespace ts { const expressions = pendingExpressions; expressions.push(name.expression); pendingExpressions = []; - node = updateComputedPropertyName( + node = factory.updateComputedPropertyName( node, - inlineExpressions(expressions) + factory.inlineExpressions(expressions) ); } return node; @@ -197,7 +198,7 @@ namespace ts { Debug.assert(!some(node.decorators)); if (!shouldTransformPrivateFields && isPrivateIdentifier(node.name)) { // Initializer is elided as the field is initialized in transformConstructor. - return updateProperty( + return factory.updatePropertyDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), @@ -212,7 +213,7 @@ namespace ts { // the property name to the temporary variable. const expr = getPropertyNameExpressionIfNeeded(node.name, !!node.initializer || !!context.getCompilerOptions().useDefineForClassFields); if (expr && !isSimpleInlineableExpression(expr)) { - (pendingExpressions || (pendingExpressions = [])).push(expr); + getPendingExpressions().push(expr); } return undefined; } @@ -221,9 +222,8 @@ namespace ts { receiver = visitNode(receiver, visitor, isExpression); switch (info.placement) { case PrivateIdentifierPlacement.InstanceField: - return createClassPrivateFieldGetHelper( - context, - nodeIsSynthesized(receiver) ? receiver : getSynthesizedClone(receiver), + return context.getEmitHelperFactory().createClassPrivateFieldGetHelper( + nodeIsSynthesized(receiver) ? receiver : factory.cloneNode(receiver), info.weakMapName ); default: return Debug.fail("Unexpected private identifier placement"); @@ -253,13 +253,13 @@ namespace ts { const receiver = visitNode(node.operand.expression, visitor, isExpression); const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); - const existingValue = createPrefix(SyntaxKind.PlusToken, createPrivateIdentifierAccess(info, readExpression)); + const existingValue = factory.createPrefixUnaryExpression(SyntaxKind.PlusToken, createPrivateIdentifierAccess(info, readExpression)); return setOriginalNode( createPrivateIdentifierAssignment( info, initializeExpression || readExpression, - createBinary(existingValue, operator, createLiteral(1)), + factory.createBinaryExpression(existingValue, operator, factory.createNumericLiteral(1)), SyntaxKind.EqualsToken ), node @@ -279,20 +279,20 @@ namespace ts { const receiver = visitNode(node.operand.expression, visitor, isExpression); const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); - const existingValue = createPrefix(SyntaxKind.PlusToken, createPrivateIdentifierAccess(info, readExpression)); + const existingValue = factory.createPrefixUnaryExpression(SyntaxKind.PlusToken, createPrivateIdentifierAccess(info, readExpression)); // Create a temporary variable to store the value returned by the expression. - const returnValue = valueIsDiscarded ? undefined : createTempVariable(hoistVariableDeclaration); + const returnValue = valueIsDiscarded ? undefined : factory.createTempVariable(hoistVariableDeclaration); return setOriginalNode( - inlineExpressions(compact([ + factory.inlineExpressions(compact([ createPrivateIdentifierAssignment( info, initializeExpression || readExpression, - createBinary( - returnValue ? createAssignment(returnValue, existingValue) : existingValue, + factory.createBinaryExpression( + returnValue ? factory.createAssignment(returnValue, existingValue) : existingValue, operator, - createLiteral(1) + factory.createNumericLiteral(1) ), SyntaxKind.EqualsToken ), @@ -307,7 +307,7 @@ namespace ts { function visitForStatement(node: ForStatement) { if (node.incrementor && isPostfixUnaryExpression(node.incrementor)) { - return updateFor( + return factory.updateForStatement( node, visitNode(node.initializer, visitor, isForInitializer), visitNode(node.condition, visitor, isExpression), @@ -320,28 +320,28 @@ namespace ts { function visitExpressionStatement(node: ExpressionStatement) { if (isPostfixUnaryExpression(node.expression)) { - return updateExpressionStatement(node, visitPostfixUnaryExpression(node.expression, /*valueIsDiscarded*/ true)); + return factory.updateExpressionStatement(node, visitPostfixUnaryExpression(node.expression, /*valueIsDiscarded*/ true)); } return visitEachChild(node, visitor, context); } function createCopiableReceiverExpr(receiver: Expression): { readExpression: Expression; initializeExpression: Expression | undefined } { - const clone = nodeIsSynthesized(receiver) ? receiver : getSynthesizedClone(receiver); + const clone = nodeIsSynthesized(receiver) ? receiver : factory.cloneNode(receiver); if (isSimpleInlineableExpression(receiver)) { return { readExpression: clone, initializeExpression: undefined }; } - const readExpression = createTempVariable(hoistVariableDeclaration); - const initializeExpression = createAssignment(readExpression, clone); + const readExpression = factory.createTempVariable(hoistVariableDeclaration); + const initializeExpression = factory.createAssignment(readExpression, clone); return { readExpression, initializeExpression }; } function visitCallExpression(node: CallExpression) { if (shouldTransformPrivateFields && isPrivateIdentifierPropertyAccessExpression(node.expression)) { // Transform call expressions of private names to properly bind the `this` parameter. - const { thisArg, target } = createCallBinding(node.expression, hoistVariableDeclaration, languageVersion); - return updateCall( + const { thisArg, target } = factory.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion); + return factory.updateCallExpression( node, - createPropertyAccess(visitNode(target, visitor), "call"), + factory.createPropertyAccessExpression(visitNode(target, visitor), "call"), /*typeArguments*/ undefined, [visitNode(thisArg, visitor, isExpression), ...visitNodes(node.arguments, visitor, isExpression)] ); @@ -352,14 +352,15 @@ namespace ts { function visitTaggedTemplateExpression(node: TaggedTemplateExpression) { if (shouldTransformPrivateFields && isPrivateIdentifierPropertyAccessExpression(node.tag)) { // Bind the `this` correctly for tagged template literals when the tag is a private identifier property access. - const { thisArg, target } = createCallBinding(node.tag, hoistVariableDeclaration, languageVersion); - return updateTaggedTemplate( + const { thisArg, target } = factory.createCallBinding(node.tag, hoistVariableDeclaration, languageVersion); + return factory.updateTaggedTemplateExpression( node, - createCall( - createPropertyAccess(visitNode(target, visitor), "bind"), + factory.createCallExpression( + factory.createPropertyAccessExpression(visitNode(target, visitor), "bind"), /*typeArguments*/ undefined, [visitNode(thisArg, visitor, isExpression)] ), + /*typeArguments*/ undefined, visitNode(node.template, visitor, isTemplateLiteral) ); } @@ -371,14 +372,14 @@ namespace ts { if (isDestructuringAssignment(node)) { const savedPendingExpressions = pendingExpressions; pendingExpressions = undefined!; - node = updateBinary( + node = factory.updateBinaryExpression( node, visitNode(node.left, visitorDestructuringTarget), - visitNode(node.right, visitor), - node.operatorToken + node.operatorToken, + visitNode(node.right, visitor) ); const expr = some(pendingExpressions) ? - inlineExpressions(compact([...pendingExpressions!, node])) : + factory.inlineExpressions(compact([...pendingExpressions!, node])) : node; pendingExpressions = savedPendingExpressions; return expr; @@ -410,19 +411,18 @@ namespace ts { right = visitNode(right, visitor, isExpression); if (isCompoundAssignment(operator)) { const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); - return createClassPrivateFieldSetHelper( - context, + return context.getEmitHelperFactory().createClassPrivateFieldSetHelper( initializeExpression || readExpression, info.weakMapName, - createBinary( - createClassPrivateFieldGetHelper(context, readExpression, info.weakMapName), + factory.createBinaryExpression( + context.getEmitHelperFactory().createClassPrivateFieldGetHelper(readExpression, info.weakMapName), getNonAssignmentOperatorForCompoundAssignment(operator), right ) ); } else { - return createClassPrivateFieldSetHelper(context, receiver, info.weakMapName, right); + return context.getEmitHelperFactory().createClassPrivateFieldSetHelper(receiver, info.weakMapName, right); } } @@ -460,7 +460,7 @@ namespace ts { const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword); const statements: Statement[] = [ - updateClassDeclaration( + factory.updateClassDeclaration( node, /*decorators*/ undefined, node.modifiers, @@ -473,7 +473,7 @@ namespace ts { // Write any pending expressions from elided or moved computed property names if (some(pendingExpressions)) { - statements.push(createExpressionStatement(inlineExpressions(pendingExpressions))); + statements.push(factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions))); } // Emit static property assignment. Because classDeclaration is lexically evaluated, @@ -483,7 +483,7 @@ namespace ts { // a lexical declaration such as a LexicalDeclaration or a ClassDeclaration. const staticProperties = getProperties(node, /*requireInitializer*/ true, /*isStatic*/ true); if (some(staticProperties)) { - addPropertyStatements(statements, staticProperties, getInternalName(node)); + addPropertyStatements(statements, staticProperties, factory.getInternalName(node)); } return statements; @@ -507,8 +507,9 @@ namespace ts { const extendsClauseElement = getEffectiveBaseTypeNode(node); const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword); - const classExpression = updateClassExpression( + const classExpression = factory.updateClassExpression( node, + visitNodes(node.decorators, visitor, isDecorator), node.modifiers, node.name, /*typeParameters*/ undefined, @@ -522,22 +523,22 @@ namespace ts { // Write any pending expressions from elided or moved computed property names if (pendingStatements && pendingExpressions && some(pendingExpressions)) { - pendingStatements.push(createExpressionStatement(inlineExpressions(pendingExpressions))); + pendingStatements.push(factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions))); } if (pendingStatements && some(staticProperties)) { - addPropertyStatements(pendingStatements, staticProperties, getInternalName(node)); + addPropertyStatements(pendingStatements, staticProperties, factory.getInternalName(node)); } return classExpression; } else { const expressions: Expression[] = []; const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference; - const temp = createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference); + const temp = factory.createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference); if (isClassWithConstructorReference) { // record an alias as the class name is not in scope for statics. enableSubstitutionForClassAliases(); - const alias = getSynthesizedClone(temp); + const alias = factory.cloneNode(temp) as GeneratedIdentifier; alias.autoGenerateFlags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes; classAliases[getOriginalNodeId(node)] = alias; } @@ -545,13 +546,13 @@ namespace ts { // To preserve the behavior of the old emitter, we explicitly indent // the body of a class with static initializers. setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression)); - expressions.push(startOnNewLine(createAssignment(temp, classExpression))); + expressions.push(startOnNewLine(factory.createAssignment(temp, classExpression))); // Add any pending expressions leftover from elided or relocated computed property names addRange(expressions, map(pendingExpressions, startOnNewLine)); addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp)); expressions.push(startOnNewLine(temp)); - return inlineExpressions(expressions); + return factory.inlineExpressions(expressions); } } @@ -574,7 +575,7 @@ namespace ts { members.push(constructor); } addRange(members, visitNodes(node.members, classElementVisitor, isClassElement)); - return setTextRange(createNodeArray(members), /*location*/ node.members); + return setTextRange(factory.createNodeArray(members), /*location*/ node.members); } function isPropertyDeclarationThatRequiresConstructorStatement(member: ClassElement): member is PropertyDeclaration { @@ -603,7 +604,7 @@ namespace ts { return startOnNewLine( setOriginalNode( setTextRange( - createConstructor( + factory.createConstructorDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, parameters ?? [], @@ -640,18 +641,18 @@ namespace ts { // super(...arguments); // statements.push( - createExpressionStatement( - createCall( - createSuper(), + factory.createExpressionStatement( + factory.createCallExpression( + factory.createSuper(), /*typeArguments*/ undefined, - [createSpread(createIdentifier("arguments"))] + [factory.createSpreadElement(factory.createIdentifier("arguments"))] ) ) ); } if (constructor) { - indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor); + indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(factory, constructor, statements, visitor); } // Add the property initializers. Transforms this: // @@ -675,19 +676,19 @@ namespace ts { indexOfFirstStatement = afterParameterProperties; } } - addPropertyStatements(statements, properties, createThis()); + addPropertyStatements(statements, properties, factory.createThis()); // Add existing statements, skipping the initial super call. if (constructor) { addRange(statements, visitNodes(constructor.body!.statements, visitor, isStatement, indexOfFirstStatement)); } - statements = mergeLexicalEnvironment(statements, endLexicalEnvironment()); + statements = factory.mergeLexicalEnvironment(statements, endLexicalEnvironment()); return setTextRange( - createBlock( + factory.createBlock( setTextRange( - createNodeArray(statements), + factory.createNodeArray(statements), /*location*/ constructor ? constructor.body!.statements : node.members ), /*multiLine*/ true @@ -708,7 +709,7 @@ namespace ts { if (!expression) { continue; } - const statement = createExpressionStatement(expression); + const statement = factory.createExpressionStatement(expression); setSourceMapRange(statement, moveRangePastModifiers(property)); setCommentRange(statement, property); setOriginalNode(statement, property); @@ -749,7 +750,7 @@ namespace ts { // We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name) const emitAssignment = !context.getCompilerOptions().useDefineForClassFields; const propertyName = isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression) - ? updateComputedPropertyName(property.name, getGeneratedNameForNode(property.name)) + ? factory.updateComputedPropertyName(property.name, factory.getGeneratedNameForNode(property.name)) : property.name; if (shouldTransformPrivateFields && isPrivateIdentifier(propertyName)) { @@ -778,20 +779,20 @@ namespace ts { } const propertyOriginalNode = getOriginalNode(property); - const initializer = property.initializer || emitAssignment ? visitNode(property.initializer, visitor, isExpression) + const initializer = property.initializer || emitAssignment ? visitNode(property.initializer, visitor, isExpression) ?? factory.createVoidZero() : isParameterPropertyDeclaration(propertyOriginalNode, propertyOriginalNode.parent) && isIdentifier(propertyName) ? propertyName - : createVoidZero(); + : factory.createVoidZero(); if (emitAssignment || isPrivateIdentifier(propertyName)) { - const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName); - return createAssignment(memberAccess, initializer); + const memberAccess = createMemberAccessForPropertyName(factory, receiver, propertyName, /*location*/ propertyName); + return factory.createAssignment(memberAccess, initializer); } else { const name = isComputedPropertyName(propertyName) ? propertyName.expression - : isIdentifier(propertyName) ? createStringLiteral(unescapeLeadingUnderscores(propertyName.escapedText)) + : isIdentifier(propertyName) ? factory.createStringLiteral(unescapeLeadingUnderscores(propertyName.escapedText)) : propertyName; - const descriptor = createPropertyDescriptor({ value: initializer, configurable: true, writable: true, enumerable: true }); - return createObjectDefinePropertyCall(receiver, name, descriptor); + const descriptor = factory.createPropertyDescriptor({ value: initializer, configurable: true, writable: true, enumerable: true }); + return factory.createObjectDefinePropertyCall(receiver, name, descriptor); } } @@ -846,7 +847,7 @@ namespace ts { if (declaration) { const classAlias = classAliases[declaration.id!]; // TODO: GH#18217 if (classAlias) { - const clone = getSynthesizedClone(classAlias); + const clone = factory.cloneNode(classAlias); setSourceMapRange(clone, node); setCommentRange(clone, node); return clone; @@ -871,9 +872,9 @@ namespace ts { const inlinable = isSimpleInlineableExpression(innerExpression); const alreadyTransformed = isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left); if (!alreadyTransformed && !inlinable && shouldHoist) { - const generatedName = getGeneratedNameForNode(name); + const generatedName = factory.getGeneratedNameForNode(name); hoistVariableDeclaration(generatedName); - return createAssignment(generatedName, expression); + return factory.createAssignment(generatedName, expression); } return (inlinable || isIdentifier(innerExpression)) ? undefined : expression; } @@ -888,18 +889,24 @@ namespace ts { currentPrivateIdentifierEnvironment = privateIdentifierEnvironmentStack.pop(); } + function getPrivateIdentifierEnvironment() { + return currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = createUnderscoreEscapedMap()); + } + + function getPendingExpressions() { + return pendingExpressions || (pendingExpressions = []); + } + function addPrivateIdentifierToEnvironment(name: PrivateIdentifier) { const text = getTextOfPropertyName(name) as string; - const weakMapName = createOptimisticUniqueName("_" + text.substring(1)); - weakMapName.autoGenerateFlags |= GeneratedIdentifierFlags.ReservedInNestedScopes; + const weakMapName = factory.createUniqueName("_" + text.substring(1), GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.ReservedInNestedScopes); hoistVariableDeclaration(weakMapName); - (currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = createUnderscoreEscapedMap())) - .set(name.escapedText, { placement: PrivateIdentifierPlacement.InstanceField, weakMapName }); - (pendingExpressions || (pendingExpressions = [])).push( - createAssignment( + getPrivateIdentifierEnvironment().set(name.escapedText, { placement: PrivateIdentifierPlacement.InstanceField, weakMapName }); + getPendingExpressions().push( + factory.createAssignment( weakMapName, - createNew( - createIdentifier("WeakMap"), + factory.createNewExpression( + factory.createIdentifier("WeakMap"), /*typeArguments*/ undefined, [] ) @@ -929,7 +936,7 @@ namespace ts { function wrapPrivateIdentifierForDestructuringTarget(node: PrivateIdentifierPropertyAccessExpression) { - const parameter = getGeneratedNameForNode(node); + const parameter = factory.getGeneratedNameForNode(node); const info = accessPrivateIdentifier(node.name); if (!info) { return visitEachChild(node, visitor, context); @@ -938,19 +945,18 @@ namespace ts { // We cannot copy `this` or `super` into the function because they will be bound // differently inside the function. if (isThisProperty(node) || isSuperProperty(node) || !isSimpleCopiableExpression(node.expression)) { - receiver = createTempVariable(hoistVariableDeclaration); - (receiver as Identifier).autoGenerateFlags! |= GeneratedIdentifierFlags.ReservedInNestedScopes; - (pendingExpressions || (pendingExpressions = [])).push(createBinary(receiver, SyntaxKind.EqualsToken, node.expression)); + receiver = factory.createTempVariable(hoistVariableDeclaration, /*reservedInNestedScopes*/ true); + getPendingExpressions().push(factory.createBinaryExpression(receiver, SyntaxKind.EqualsToken, node.expression)); } - return createPropertyAccess( + return factory.createPropertyAccessExpression( // Explicit parens required because of v8 regression (https://bugs.chromium.org/p/v8/issues/detail?id=9560) - createParen( - createObjectLiteral([ - createSetAccessor( + factory.createParenthesizedExpression( + factory.createObjectLiteralExpression([ + factory.createSetAccessorDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, "value", - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -959,8 +965,8 @@ namespace ts { /*type*/ undefined, /*initializer*/ undefined )], - createBlock( - [createExpressionStatement( + factory.createBlock( + [factory.createExpressionStatement( createPrivateIdentifierAssignment( info, receiver, @@ -981,15 +987,15 @@ namespace ts { if (target && isPrivateIdentifierPropertyAccessExpression(target)) { const wrapped = wrapPrivateIdentifierForDestructuringTarget(target); if (isAssignmentExpression(node)) { - return updateBinary( + return factory.updateBinaryExpression( node, wrapped, - visitNode(node.right, visitor, isExpression), - node.operatorToken + node.operatorToken, + visitNode(node.right, visitor, isExpression) ); } else if (isSpreadElement(node)) { - return updateSpread(node, wrapped); + return factory.updateSpreadElement(node, wrapped); } else { return wrapped; @@ -1004,13 +1010,13 @@ namespace ts { if (target && isPrivateIdentifierPropertyAccessExpression(target)) { const initializer = getInitializerOfBindingOrAssignmentElement(node); const wrapped = wrapPrivateIdentifierForDestructuringTarget(target); - return updatePropertyAssignment( + return factory.updatePropertyAssignment( node, visitNode(node.name, visitor), - initializer ? createAssignment(wrapped, visitNode(initializer, visitor)) : wrapped, + initializer ? factory.createAssignment(wrapped, visitNode(initializer, visitor)) : wrapped, ); } - return updatePropertyAssignment( + return factory.updatePropertyAssignment( node, visitNode(node.name, visitor), visitNode(node.initializer, visitorDestructuringTarget) @@ -1029,7 +1035,7 @@ namespace ts { // // Transformation: // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ]; - return updateArrayLiteral( + return factory.updateArrayLiteralExpression( node, visitNodes(node.elements, visitArrayAssignmentTarget, isExpression) ); @@ -1042,7 +1048,7 @@ namespace ts { // // Transformation: // ({ stringProperty: { set value(x) { this.#myProp = x; } }.value }) = { stringProperty: "hello" }; - return updateObjectLiteral( + return factory.updateObjectLiteralExpression( node, visitNodes(node.properties, visitObjectAssignmentTarget, isObjectLiteralElementLike) ); @@ -1051,45 +1057,10 @@ namespace ts { } function createPrivateInstanceFieldInitializer(receiver: LeftHandSideExpression, initializer: Expression | undefined, weakMapName: Identifier) { - return createCall( - createPropertyAccess(weakMapName, "set"), + return factory.createCallExpression( + factory.createPropertyAccessExpression(weakMapName, "set"), /*typeArguments*/ undefined, - [receiver, initializer || createVoidZero()] + [receiver, initializer || factory.createVoidZero()] ); } - - export const classPrivateFieldGetHelper: UnscopedEmitHelper = { - name: "typescript:classPrivateFieldGet", - scoped: false, - text: ` - var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { - if (!privateMap.has(receiver)) { - throw new TypeError("attempted to get private field on non-instance"); - } - return privateMap.get(receiver); - };` - }; - - function createClassPrivateFieldGetHelper(context: TransformationContext, receiver: Expression, privateField: Identifier) { - context.requestEmitHelper(classPrivateFieldGetHelper); - return createCall(getUnscopedHelperName("__classPrivateFieldGet"), /* typeArguments */ undefined, [receiver, privateField]); - } - - export const classPrivateFieldSetHelper: UnscopedEmitHelper = { - name: "typescript:classPrivateFieldSet", - scoped: false, - text: ` - var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { - if (!privateMap.has(receiver)) { - throw new TypeError("attempted to set private field on non-instance"); - } - privateMap.set(receiver, value); - return value; - };` - }; - - function createClassPrivateFieldSetHelper(context: TransformationContext, receiver: Expression, privateField: Identifier, value: Expression) { - context.requestEmitHelper(classPrivateFieldSetHelper); - return createCall(getUnscopedHelperName("__classPrivateFieldSet"), /* typeArguments */ undefined, [receiver, privateField, value]); - } } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index a6ed0cf71e8b9..ba4c01beb8ba8 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1,11 +1,8 @@ /*@internal*/ namespace ts { export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined { - if (file && isJsonSourceFile(file)) { - return []; // No declaration diagnostics for json for now - } const compilerOptions = host.getCompilerOptions(); - const result = transformNodes(resolver, host, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJson), [transformDeclarations], /*allowDtsFiles*/ false); + const result = transformNodes(resolver, host, factory, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJson), [transformDeclarations], /*allowDtsFiles*/ false); return result.diagnostics; } @@ -67,6 +64,7 @@ namespace ts { let suppressNewDiagnosticContexts: boolean; let exportedModulesFromDeclarationEmit: Symbol[] | undefined; + const { factory } = context; const host = context.getEmitHost(); const symbolTracker: SymbolTracker = { trackSymbol, @@ -236,7 +234,7 @@ namespace ts { refs = createMap(); libs = createMap(); let hasNoDefaultLib = false; - const bundle = createBundle(map(node.sourceFiles, + const bundle = factory.createBundle(map(node.sourceFiles, sourceFile => { if (sourceFile.isDeclarationFile) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217 hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib; @@ -253,18 +251,18 @@ namespace ts { if (isExternalOrCommonJsModule(sourceFile) || isJsonSourceFile(sourceFile)) { resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules) needsDeclare = false; - const statements = isSourceFileJS(sourceFile) ? createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : visitNodes(sourceFile.statements, visitDeclarationStatements); - const newFile = updateSourceFileNode(sourceFile, [createModuleDeclaration( + const statements = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : visitNodes(sourceFile.statements, visitDeclarationStatements); + const newFile = factory.updateSourceFile(sourceFile, [factory.createModuleDeclaration( [], - [createModifier(SyntaxKind.DeclareKeyword)], - createLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), - createModuleBlock(setTextRange(createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements)) + [factory.createModifier(SyntaxKind.DeclareKeyword)], + factory.createStringLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), + factory.createModuleBlock(setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements)) )], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []); return newFile; } needsDeclare = true; - const updated = isSourceFileJS(sourceFile) ? createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes(sourceFile.statements, visitDeclarationStatements); - return updateSourceFileNode(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []); + const updated = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes(sourceFile.statements, visitDeclarationStatements); + return factory.updateSourceFile(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []); } ), mapDefined(node.prepends, prepend => { if (prepend.kind === SyntaxKind.InputFiles) { @@ -307,20 +305,20 @@ namespace ts { const referenceVisitor = mapReferencesIntoArray(references, outputFilePath); let combinedStatements: NodeArray; if (isSourceFileJS(currentSourceFile)) { - combinedStatements = createNodeArray(transformDeclarationsForJS(node)); + combinedStatements = factory.createNodeArray(transformDeclarationsForJS(node)); refs.forEach(referenceVisitor); emittedImports = filter(combinedStatements, isAnyImportSyntax); } else { const statements = visitNodes(node.statements, visitDeclarationStatements); - combinedStatements = setTextRange(createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements); + combinedStatements = setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements); refs.forEach(referenceVisitor); emittedImports = filter(combinedStatements, isAnyImportSyntax); if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) { - combinedStatements = setTextRange(createNodeArray([...combinedStatements, createEmptyExports()]), combinedStatements); + combinedStatements = setTextRange(factory.createNodeArray([...combinedStatements, createEmptyExports(factory)]), combinedStatements); } } - const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences()); + const updated = factory.updateSourceFile(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences()); updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit; return updated; @@ -431,10 +429,10 @@ namespace ts { } else { if (name.kind === SyntaxKind.ArrayBindingPattern) { - return updateArrayBindingPattern(name, visitNodes(name.elements, visitBindingElement)); + return factory.updateArrayBindingPattern(name, visitNodes(name.elements, visitBindingElement)); } else { - return updateObjectBindingPattern(name, visitNodes(name.elements, visitBindingElement)); + return factory.updateObjectBindingPattern(name, visitNodes(name.elements, visitBindingElement)); } } @@ -443,7 +441,7 @@ namespace ts { if (elem.kind === SyntaxKind.OmittedExpression) { return elem; } - return updateBindingElement(elem, elem.dotDotDotToken, elem.propertyName, filterBindingPatternInitializers(elem.name), shouldPrintWithInitializer(elem) ? elem.initializer : undefined); + return factory.updateBindingElement(elem, elem.dotDotDotToken, elem.propertyName, filterBindingPatternInitializers(elem.name), shouldPrintWithInitializer(elem) ? elem.initializer : undefined); } } @@ -453,13 +451,13 @@ namespace ts { oldDiag = getSymbolAccessibilityDiagnostic; getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p); } - const newParam = updateParameter( + const newParam = factory.updateParameterDeclaration( p, /*decorators*/ undefined, maskModifiers(p, modifierMask), p.dotDotDotToken, filterBindingPatternInitializers(p.name), - resolver.isOptionalParameter(p) ? (p.questionToken || createToken(SyntaxKind.QuestionToken)) : undefined, + resolver.isOptionalParameter(p) ? (p.questionToken || factory.createToken(SyntaxKind.QuestionToken)) : undefined, ensureType(p, type || p.type, /*ignorePrivate*/ true), // Ignore private param props, since this type is going straight back into a param ensureNoInitializer(p) ); @@ -510,12 +508,12 @@ namespace ts { return visitNode(type, visitDeclarationSubtree); } if (!getParseTreeNode(node)) { - return type ? visitNode(type, visitDeclarationSubtree) : createKeywordTypeNode(SyntaxKind.AnyKeyword); + return type ? visitNode(type, visitDeclarationSubtree) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } if (node.kind === SyntaxKind.SetAccessor) { // Set accessors with no associated type node (from it's param or get accessor return) are `any` since they are never contextually typed right now // (The inferred type here will be void, but the old declaration emitter printed `any`, so this replicates that) - return createKeywordTypeNode(SyntaxKind.AnyKeyword); + return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } errorNameNode = node.name; let oldDiag: typeof getSymbolAccessibilityDiagnostic; @@ -539,7 +537,7 @@ namespace ts { if (!suppressNewDiagnosticContexts) { getSymbolAccessibilityDiagnostic = oldDiag; } - return returnValue || createKeywordTypeNode(SyntaxKind.AnyKeyword); + return returnValue || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } } @@ -586,7 +584,7 @@ namespace ts { if (!newParams) { return undefined!; // TODO: GH#18217 } - return createNodeArray(newParams, params.hasTrailingComma); + return factory.createNodeArray(newParams, params.hasTrailingComma); } function updateAccessorParamsList(input: AccessorDeclaration, isPrivate: boolean) { @@ -607,7 +605,7 @@ namespace ts { } } if (!newValueParameter) { - newValueParameter = createParameter( + newValueParameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -616,7 +614,7 @@ namespace ts { } newParams = append(newParams, newValueParameter); } - return createNodeArray(newParams || emptyArray) as NodeArray; + return factory.createNodeArray(newParams || emptyArray); } function ensureTypeParams(node: Node, params: NodeArray | undefined) { @@ -654,7 +652,7 @@ namespace ts { if (isBundledEmit) { const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent); if (newName) { - return createLiteral(newName); + return factory.createStringLiteral(newName); } } else { @@ -672,12 +670,12 @@ namespace ts { if (decl.moduleReference.kind === SyntaxKind.ExternalModuleReference) { // Rewrite external module names if necessary const specifier = getExternalModuleImportEqualsDeclarationExpression(decl); - return updateImportEqualsDeclaration( + return factory.updateImportEqualsDeclaration( decl, /*decorators*/ undefined, decl.modifiers, decl.name, - updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier)) + factory.updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier)) ); } else { @@ -692,7 +690,7 @@ namespace ts { function transformImportDeclaration(decl: ImportDeclaration) { if (!decl.importClause) { // import "mod" - possibly needed for side effects? (global interface patches, module augmentations, etc) - return updateImportDeclaration( + return factory.updateImportDeclaration( decl, /*decorators*/ undefined, decl.modifiers, @@ -704,42 +702,42 @@ namespace ts { const visibleDefaultBinding = decl.importClause && decl.importClause.name && resolver.isDeclarationVisible(decl.importClause) ? decl.importClause.name : undefined; if (!decl.importClause.namedBindings) { // No named bindings (either namespace or list), meaning the import is just default or should be elided - return visibleDefaultBinding && updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, updateImportClause( + return visibleDefaultBinding && factory.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, factory.updateImportClause( decl.importClause, + decl.importClause.isTypeOnly, visibleDefaultBinding, /*namedBindings*/ undefined, - decl.importClause.isTypeOnly, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier)); } if (decl.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { // Namespace import (optionally with visible default) const namedBindings = resolver.isDeclarationVisible(decl.importClause.namedBindings) ? decl.importClause.namedBindings : /*namedBindings*/ undefined; - return visibleDefaultBinding || namedBindings ? updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, updateImportClause( + return visibleDefaultBinding || namedBindings ? factory.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, factory.updateImportClause( decl.importClause, + decl.importClause.isTypeOnly, visibleDefaultBinding, namedBindings, - decl.importClause.isTypeOnly, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier)) : undefined; } // Named imports (optionally with visible default) const bindingList = mapDefined(decl.importClause.namedBindings.elements, b => resolver.isDeclarationVisible(b) ? b : undefined); if ((bindingList && bindingList.length) || visibleDefaultBinding) { - return updateImportDeclaration( + return factory.updateImportDeclaration( decl, /*decorators*/ undefined, decl.modifiers, - updateImportClause( + factory.updateImportClause( decl.importClause, - visibleDefaultBinding, - bindingList && bindingList.length ? updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, decl.importClause.isTypeOnly, + visibleDefaultBinding, + bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier) ); } // Augmentation of export depends on import if (resolver.isImportRequiredByAugmentation(decl)) { - return updateImportDeclaration( + return factory.updateImportDeclaration( decl, /*decorators*/ undefined, decl.modifiers, @@ -835,7 +833,7 @@ namespace ts { if (isMethodDeclaration(input) || isMethodSignature(input)) { if (hasEffectiveModifier(input, ModifierFlags.Private)) { if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input) return; // Elide all but the first overload - return cleanup(createProperty(/*decorators*/undefined, ensureModifiers(input), input.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)); + return cleanup(factory.createPropertyDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)); } } @@ -859,15 +857,15 @@ namespace ts { checkEntityNameVisibility(input.expression, enclosingDeclaration); } const node = visitEachChild(input, visitDeclarationSubtree, context); - return cleanup(updateExpressionWithTypeArguments(node, parenthesizeTypeParameters(node.typeArguments), node.expression)); + return cleanup(factory.updateExpressionWithTypeArguments(node, node.expression, node.typeArguments)); } case SyntaxKind.TypeReference: { checkEntityNameVisibility(input.typeName, enclosingDeclaration); const node = visitEachChild(input, visitDeclarationSubtree, context); - return cleanup(updateTypeReferenceNode(node, node.typeName, parenthesizeTypeParameters(node.typeArguments))); + return cleanup(factory.updateTypeReferenceNode(node, node.typeName, node.typeArguments)); } case SyntaxKind.ConstructSignature: - return cleanup(updateConstructSignature( + return cleanup(factory.updateConstructSignature( input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), @@ -875,28 +873,29 @@ namespace ts { )); case SyntaxKind.Constructor: { // A constructor declaration may not have a type annotation - const ctor = createSignatureDeclaration( - SyntaxKind.Constructor, - ensureTypeParams(input, input.typeParameters), + const ctor = factory.createConstructorDeclaration( + /*decorators*/ undefined, + /*modifiers*/ ensureModifiers(input), updateParamsList(input, input.parameters, ModifierFlags.None), - /*type*/ undefined + /*body*/ undefined ); - ctor.modifiers = createNodeArray(ensureModifiers(input)); return cleanup(ctor); } case SyntaxKind.MethodDeclaration: { if (isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - const sig = createSignatureDeclaration( - SyntaxKind.MethodSignature, + const sig = factory.createMethodDeclaration( + /*decorators*/ undefined, + ensureModifiers(input), + /*asteriskToken*/ undefined, + input.name, + input.questionToken, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), - ensureType(input, input.type) - ) as MethodSignature; - sig.name = input.name; - sig.modifiers = createNodeArray(ensureModifiers(input)); - sig.questionToken = input.questionToken; + ensureType(input, input.type), + /*body*/ undefined + ); return cleanup(sig); } case SyntaxKind.GetAccessor: { @@ -904,7 +903,7 @@ namespace ts { return cleanup(/*returnValue*/ undefined); } const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input)); - return cleanup(updateGetAccessor( + return cleanup(factory.updateGetAccessorDeclaration( input, /*decorators*/ undefined, ensureModifiers(input), @@ -917,7 +916,7 @@ namespace ts { if (isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - return cleanup(updateSetAccessor( + return cleanup(factory.updateSetAccessorDeclaration( input, /*decorators*/ undefined, ensureModifiers(input), @@ -929,7 +928,7 @@ namespace ts { if (isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - return cleanup(updateProperty( + return cleanup(factory.updatePropertyDeclaration( input, /*decorators*/ undefined, ensureModifiers(input), @@ -942,29 +941,29 @@ namespace ts { if (isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - return cleanup(updatePropertySignature( + return cleanup(factory.updatePropertySignature( input, ensureModifiers(input), input.name, input.questionToken, - ensureType(input, input.type), - ensureNoInitializer(input) + ensureType(input, input.type) )); case SyntaxKind.MethodSignature: { if (isPrivateIdentifier(input.name)) { return cleanup(/*returnValue*/ undefined); } - return cleanup(updateMethodSignature( + return cleanup(factory.updateMethodSignature( input, + ensureModifiers(input), + input.name, + input.questionToken, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), - ensureType(input, input.type), - input.name, - input.questionToken + ensureType(input, input.type) )); } case SyntaxKind.CallSignature: { - return cleanup(updateCallSignature( + return cleanup(factory.updateCallSignature( input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), @@ -972,12 +971,12 @@ namespace ts { )); } case SyntaxKind.IndexSignature: { - return cleanup(updateIndexSignature( + return cleanup(factory.updateIndexSignature( input, /*decorators*/ undefined, ensureModifiers(input), updateParamsList(input, input.parameters), - visitNode(input.type, visitDeclarationSubtree) || createKeywordTypeNode(SyntaxKind.AnyKeyword) + visitNode(input.type, visitDeclarationSubtree) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) )); } case SyntaxKind.VariableDeclaration: { @@ -986,11 +985,11 @@ namespace ts { } shouldEnterSuppressNewDiagnosticsContextContext = true; suppressNewDiagnosticContexts = true; // Variable declaration types also suppress new diagnostic contexts, provided the contexts wouldn't be made for binding pattern types - return cleanup(updateTypeScriptVariableDeclaration(input, input.name, /*exclaimationToken*/ undefined, ensureType(input, input.type), ensureNoInitializer(input))); + return cleanup(factory.updateVariableDeclaration(input, input.name, /*exclamationToken*/ undefined, ensureType(input, input.type), ensureNoInitializer(input))); } case SyntaxKind.TypeParameter: { if (isPrivateMethodTypeParameter(input) && (input.default || input.constraint)) { - return cleanup(updateTypeParameterDeclaration(input, input.name, /*constraint*/ undefined, /*defaultType*/ undefined)); + return cleanup(factory.updateTypeParameterDeclaration(input, input.name, /*constraint*/ undefined, /*defaultType*/ undefined)); } return cleanup(visitEachChild(input, visitDeclarationSubtree, context)); } @@ -1004,19 +1003,19 @@ namespace ts { const trueType = visitNode(input.trueType, visitDeclarationSubtree); enclosingDeclaration = oldEnclosingDecl; const falseType = visitNode(input.falseType, visitDeclarationSubtree); - return cleanup(updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType)); + return cleanup(factory.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType)); } case SyntaxKind.FunctionType: { - return cleanup(updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); + return cleanup(factory.updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); } case SyntaxKind.ConstructorType: { - return cleanup(updateConstructorTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); + return cleanup(factory.updateConstructorTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); } case SyntaxKind.ImportType: { if (!isLiteralImportTypeNode(input)) return cleanup(input); - return cleanup(updateImportTypeNode( + return cleanup(factory.updateImportTypeNode( input, - updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)), + factory.updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)), input.qualifier, visitNodes(input.typeArguments, visitDeclarationSubtree, isTypeNode), input.isTypeOf @@ -1071,13 +1070,14 @@ namespace ts { resultHasScopeMarker = true; // Always visible if the parent node isn't dropped for being not visible // Rewrite external module names if necessary - return updateExportDeclaration( + return factory.updateExportDeclaration( input, /*decorators*/ undefined, input.modifiers, + input.isTypeOnly, input.exportClause, rewriteModuleSpecifier(input, input.moduleSpecifier), - input.isTypeOnly); + ); } case SyntaxKind.ExportAssignment: { // Always visible if the parent node isn't dropped for being not visible @@ -1089,14 +1089,14 @@ namespace ts { return input; } else { - const newId = createOptimisticUniqueName("_default"); + const newId = factory.createUniqueName("_default", GeneratedIdentifierFlags.Optimistic); getSymbolAccessibilityDiagnostic = () => ({ diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, errorNode: input }); - const varDecl = createVariableDeclaration(newId, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); - const statement = createVariableStatement(needsDeclare ? [createModifier(SyntaxKind.DeclareKeyword)] : [], createVariableDeclarationList([varDecl], NodeFlags.Const)); - return [statement, updateExportAssignment(input, input.decorators, input.modifiers, newId)]; + const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); + const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const)); + return [statement, factory.updateExportAssignment(input, input.decorators, input.modifiers, newId)]; } } } @@ -1108,15 +1108,14 @@ namespace ts { } function stripExportModifiers(statement: Statement): Statement { - if (isImportEqualsDeclaration(statement) || hasEffectiveModifier(statement, ModifierFlags.Default)) { + if (isImportEqualsDeclaration(statement) || hasEffectiveModifier(statement, ModifierFlags.Default) || !canHaveModifiers(statement)) { // `export import` statements should remain as-is, as imports are _not_ implicitly exported in an ambient namespace // Likewise, `export default` classes and the like and just be `default`, so we preserve their `export` modifiers, too return statement; } - const clone = getMutableClone(statement); - const modifiers = createModifiersFromModifierFlags(getEffectiveModifierFlags(statement) & (ModifierFlags.All ^ ModifierFlags.Export)); - clone.modifiers = modifiers.length ? createNodeArray(modifiers) : undefined; - return clone; + + const modifiers = factory.createModifiersFromModifierFlags(getEffectiveModifierFlags(statement) & (ModifierFlags.All ^ ModifierFlags.Export)); + return factory.updateModifiers(statement, modifiers); } function transformTopLevelDeclaration(input: LateVisibilityPaintedStatement) { @@ -1149,7 +1148,7 @@ namespace ts { const previousNeedsDeclare = needsDeclare; switch (input.kind) { case SyntaxKind.TypeAliasDeclaration: // Type aliases get `declare`d if need be (for legacy support), but that's all - return cleanup(updateTypeAliasDeclaration( + return cleanup(factory.updateTypeAliasDeclaration( input, /*decorators*/ undefined, ensureModifiers(input), @@ -1158,7 +1157,7 @@ namespace ts { visitNode(input.type, visitDeclarationSubtree, isTypeNode) )); case SyntaxKind.InterfaceDeclaration: { - return cleanup(updateInterfaceDeclaration( + return cleanup(factory.updateInterfaceDeclaration( input, /*decorators*/ undefined, ensureModifiers(input), @@ -1170,7 +1169,7 @@ namespace ts { } case SyntaxKind.FunctionDeclaration: { // Generators lose their generator-ness, excepting their return type - const clean = cleanup(updateFunctionDeclaration( + const clean = cleanup(factory.updateFunctionDeclaration( input, /*decorators*/ undefined, ensureModifiers(input), @@ -1183,13 +1182,13 @@ namespace ts { )); if (clean && resolver.isExpandoFunctionDeclaration(input)) { const props = resolver.getPropertiesOfContainerFunction(input); - const fakespace = createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || createIdentifier("_default"), createModuleBlock([]), NodeFlags.Namespace); - fakespace.flags ^= NodeFlags.Synthesized; // unset synthesized so it is usable as an enclosing declaration - fakespace.parent = enclosingDeclaration as SourceFile | NamespaceDeclaration; + // Use parseNodeFactory so it is usable as an enclosing declaration + const fakespace = parseNodeFactory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || factory.createIdentifier("_default"), factory.createModuleBlock([]), NodeFlags.Namespace); + setParent(fakespace, enclosingDeclaration as SourceFile | NamespaceDeclaration); fakespace.locals = createSymbolTable(props); fakespace.symbol = props[0].parent!; const exportMappings: [Identifier, string][] = []; - const declarations: (VariableStatement | ExportDeclaration)[] = mapDefined(props, p => { + let declarations: (VariableStatement | ExportDeclaration)[] = mapDefined(props, p => { if (!isPropertyAccessExpression(p.valueDeclaration)) { return undefined; // TODO GH#33569: Handle element access expressions that created late bound names (rather than silently omitting them) } @@ -1198,32 +1197,33 @@ namespace ts { getSymbolAccessibilityDiagnostic = oldDiag; const nameStr = unescapeLeadingUnderscores(p.escapedName); const isNonContextualKeywordName = isStringANonContextualKeyword(nameStr); - const name = isNonContextualKeywordName ? getGeneratedNameForNode(p.valueDeclaration) : createIdentifier(nameStr); + const name = isNonContextualKeywordName ? factory.getGeneratedNameForNode(p.valueDeclaration) : factory.createIdentifier(nameStr); if (isNonContextualKeywordName) { exportMappings.push([name, nameStr]); } - const varDecl = createVariableDeclaration(name, type, /*initializer*/ undefined); - return createVariableStatement(isNonContextualKeywordName ? undefined : [createToken(SyntaxKind.ExportKeyword)], createVariableDeclarationList([varDecl])); + const varDecl = factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, /*initializer*/ undefined); + return factory.createVariableStatement(isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([varDecl])); }); if (!exportMappings.length) { - forEach(declarations, d => d.modifiers = undefined); + declarations = mapDefined(declarations, declaration => factory.updateModifiers(declaration, ModifierFlags.None)); } else { - declarations.push(createExportDeclaration( + declarations.push(factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports(map(exportMappings, ([gen, exp]) => { - return createExportSpecifier(gen, exp); + /*isTypeOnly*/ false, + factory.createNamedExports(map(exportMappings, ([gen, exp]) => { + return factory.createExportSpecifier(gen, exp); })) )); } - const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name!, createModuleBlock(declarations), NodeFlags.Namespace); + const namespaceDecl = factory.createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name!, factory.createModuleBlock(declarations), NodeFlags.Namespace); if (!hasEffectiveModifier(clean, ModifierFlags.Default)) { return [clean, namespaceDecl]; } - const modifiers = createModifiersFromModifierFlags((getEffectiveModifierFlags(clean) & ~ModifierFlags.ExportDefault) | ModifierFlags.Ambient); - const cleanDeclaration = updateFunctionDeclaration( + const modifiers = factory.createModifiersFromModifierFlags((getEffectiveModifierFlags(clean) & ~ModifierFlags.ExportDefault) | ModifierFlags.Ambient); + const cleanDeclaration = factory.updateFunctionDeclaration( clean, /*decorators*/ undefined, modifiers, @@ -1235,7 +1235,7 @@ namespace ts { /*body*/ undefined ); - const namespaceDeclaration = updateModuleDeclaration( + const namespaceDeclaration = factory.updateModuleDeclaration( namespaceDecl, /*decorators*/ undefined, modifiers, @@ -1243,7 +1243,7 @@ namespace ts { namespaceDecl.body ); - const exportDefaultDeclaration = createExportAssignment( + const exportDefaultDeclaration = factory.createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, @@ -1280,18 +1280,18 @@ namespace ts { // 3. Some things are exported, some are not, and there's no marker - add an empty marker if (!isGlobalScopeAugmentation(input) && !hasScopeMarker(lateStatements) && !resultHasScopeMarker) { if (needsScopeFixMarker) { - lateStatements = createNodeArray([...lateStatements, createEmptyExports()]); + lateStatements = factory.createNodeArray([...lateStatements, createEmptyExports(factory)]); } else { lateStatements = visitNodes(lateStatements, stripExportModifiers); } } - const body = updateModuleBlock(inner, lateStatements); + const body = factory.updateModuleBlock(inner, lateStatements); needsDeclare = previousNeedsDeclare; needsScopeFixMarker = oldNeedsScopeFix; resultHasScopeMarker = oldHasScopeFix; const mods = ensureModifiers(input); - return cleanup(updateModuleDeclaration( + return cleanup(factory.updateModuleDeclaration( input, /*decorators*/ undefined, mods, @@ -1308,7 +1308,7 @@ namespace ts { const id = "" + getOriginalNodeId(inner!); // TODO: GH#18217 const body = lateStatementReplacementMap.get(id); lateStatementReplacementMap.delete(id); - return cleanup(updateModuleDeclaration( + return cleanup(factory.updateModuleDeclaration( input, /*decorators*/ undefined, mods, @@ -1318,7 +1318,7 @@ namespace ts { } } case SyntaxKind.ClassDeclaration: { - const modifiers = createNodeArray(ensureModifiers(input)); + const modifiers = factory.createNodeArray(ensureModifiers(input)); const typeParameters = ensureTypeParams(input, input.typeParameters); const ctor = getFirstConstructorWithBody(input); let parameterProperties: readonly PropertyDeclaration[] | undefined; @@ -1328,7 +1328,7 @@ namespace ts { if (!hasSyntacticModifier(param, ModifierFlags.ParameterPropertyModifier) || shouldStripInternal(param)) return; getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(param); if (param.name.kind === SyntaxKind.Identifier) { - return preserveJsDoc(createProperty( + return preserveJsDoc(factory.createPropertyDeclaration( /*decorators*/ undefined, ensureModifiers(param), param.name, @@ -1349,7 +1349,7 @@ namespace ts { elems = concatenate(elems, walkBindingPattern(elem.name)); } elems = elems || []; - elems.push(createProperty( + elems.push(factory.createPropertyDeclaration( /*decorators*/ undefined, ensureModifiers(param), elem.name as Identifier, @@ -1366,42 +1366,42 @@ namespace ts { const hasPrivateIdentifier = some(input.members, member => !!member.name && isPrivateIdentifier(member.name)); const privateIdentifier = hasPrivateIdentifier ? [ - createProperty( + factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createPrivateIdentifier("#private"), + factory.createPrivateIdentifier("#private"), /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined ) ] : undefined; const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes(input.members, visitDeclarationSubtree)); - const members = createNodeArray(memberNodes); + const members = factory.createNodeArray(memberNodes); const extendsClause = getEffectiveBaseTypeNode(input); if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== SyntaxKind.NullKeyword) { // We must add a temporary declaration for the extends clause expression const oldId = input.name ? unescapeLeadingUnderscores(input.name.escapedText) : "default"; - const newId = createOptimisticUniqueName(`${oldId}_base`); + const newId = factory.createUniqueName(`${oldId}_base`, GeneratedIdentifierFlags.Optimistic); getSymbolAccessibilityDiagnostic = () => ({ diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1, errorNode: extendsClause, typeName: input.name }); - const varDecl = createVariableDeclaration(newId, resolver.createTypeOfExpression(extendsClause.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); - const statement = createVariableStatement(needsDeclare ? [createModifier(SyntaxKind.DeclareKeyword)] : [], createVariableDeclarationList([varDecl], NodeFlags.Const)); - const heritageClauses = createNodeArray(map(input.heritageClauses, clause => { + const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(extendsClause.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined); + const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const)); + const heritageClauses = factory.createNodeArray(map(input.heritageClauses, clause => { if (clause.token === SyntaxKind.ExtendsKeyword) { const oldDiag = getSymbolAccessibilityDiagnostic; getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]); - const newClause = updateHeritageClause(clause, map(clause.types, t => updateExpressionWithTypeArguments(t, visitNodes(t.typeArguments, visitDeclarationSubtree), newId))); + const newClause = factory.updateHeritageClause(clause, map(clause.types, t => factory.updateExpressionWithTypeArguments(t, newId, visitNodes(t.typeArguments, visitDeclarationSubtree)))); getSymbolAccessibilityDiagnostic = oldDiag; return newClause; } - return updateHeritageClause(clause, visitNodes(createNodeArray(filter(clause.types, t => isEntityNameExpression(t.expression) || t.expression.kind === SyntaxKind.NullKeyword)), visitDeclarationSubtree)); + return factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => isEntityNameExpression(t.expression) || t.expression.kind === SyntaxKind.NullKeyword)), visitDeclarationSubtree)); })); - return [statement, cleanup(updateClassDeclaration( + return [statement, cleanup(factory.updateClassDeclaration( input, /*decorators*/ undefined, modifiers, @@ -1413,7 +1413,7 @@ namespace ts { } else { const heritageClauses = transformHeritageClauses(input.heritageClauses); - return cleanup(updateClassDeclaration( + return cleanup(factory.updateClassDeclaration( input, /*decorators*/ undefined, modifiers, @@ -1428,11 +1428,11 @@ namespace ts { return cleanup(transformVariableStatement(input)); } case SyntaxKind.EnumDeclaration: { - return cleanup(updateEnumDeclaration(input, /*decorators*/ undefined, createNodeArray(ensureModifiers(input)), input.name, createNodeArray(mapDefined(input.members, m => { + return cleanup(factory.updateEnumDeclaration(input, /*decorators*/ undefined, factory.createNodeArray(ensureModifiers(input)), input.name, factory.createNodeArray(mapDefined(input.members, m => { if (shouldStripInternal(m)) return; // Rewrite enum values to their constants, if available const constValue = resolver.getConstantValue(m); - return preserveJsDoc(updateEnumMember(m, m.name, constValue !== undefined ? createLiteral(constValue) : undefined), m); + return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m); })))); } } @@ -1460,7 +1460,7 @@ namespace ts { if (!forEach(input.declarationList.declarations, getBindingNameVisible)) return; const nodes = visitNodes(input.declarationList.declarations, visitDeclarationSubtree); if (!length(nodes)) return; - return updateVariableStatement(input, createNodeArray(ensureModifiers(input)), updateVariableDeclarationList(input.declarationList, nodes)); + return factory.updateVariableStatement(input, factory.createNodeArray(ensureModifiers(input)), factory.updateVariableDeclarationList(input.declarationList, nodes)); } function recreateBindingPattern(d: BindingPattern): VariableDeclaration[] { @@ -1477,7 +1477,7 @@ namespace ts { return recreateBindingPattern(e.name); } else { - return createVariableDeclaration(e.name, ensureType(e, /*type*/ undefined), /*initializer*/ undefined); + return factory.createVariableDeclaration(e.name, /*exclamationToken*/ undefined, ensureType(e, /*type*/ undefined), /*initializer*/ undefined); } } } @@ -1517,7 +1517,7 @@ namespace ts { if (currentFlags === newFlags) { return node.modifiers; } - return createModifiersFromModifierFlags(newFlags); + return factory.createModifiersFromModifierFlags(newFlags); } function ensureModifierFlags(node: Node): ModifierFlags { @@ -1547,7 +1547,7 @@ namespace ts { } function transformHeritageClauses(nodes: NodeArray | undefined) { - return createNodeArray(filter(map(nodes, clause => updateHeritageClause(clause, visitNodes(createNodeArray(filter(clause.types, t => { + return factory.createNodeArray(filter(map(nodes, clause => factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => { return isEntityNameExpression(t.expression) || (clause.token === SyntaxKind.ExtendsKeyword && t.expression.kind === SyntaxKind.NullKeyword); })), visitDeclarationSubtree))), clause => clause.types && !!clause.types.length)); } @@ -1562,7 +1562,7 @@ namespace ts { // Elide "public" modifier, as it is the default function maskModifiers(node: Node, modifierMask?: ModifierFlags, modifierAdditions?: ModifierFlags): Modifier[] { - return createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions)); + return factory.createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions)); } function maskModifierFlags(node: Node, modifierMask: ModifierFlags = ModifierFlags.All ^ ModifierFlags.Public, modifierAdditions: ModifierFlags = ModifierFlags.None): ModifierFlags { diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 0c89cd34d5dd1..1dcbc0814750d 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -59,8 +59,8 @@ namespace ts { hoistTempVariables: true, emitExpression, emitBindingOrAssignment, - createArrayBindingOrAssignmentPattern: makeArrayAssignmentPattern, - createObjectBindingOrAssignmentPattern: makeObjectAssignmentPattern, + createArrayBindingOrAssignmentPattern: elements => makeArrayAssignmentPattern(context.factory, elements), + createObjectBindingOrAssignmentPattern: elements => makeObjectAssignmentPattern(context.factory, elements), createArrayBindingOrAssignmentElement: makeAssignmentElement, visitor }; @@ -104,10 +104,9 @@ namespace ts { expressions.push(value); } - return aggregateTransformFlags(inlineExpressions(expressions!)) || createOmittedExpression(); + return context.factory.inlineExpressions(expressions!) || context.factory.createOmittedExpression(); function emitExpression(expression: Expression) { - aggregateTransformFlags(expression); expressions = append(expressions, expression); } @@ -116,7 +115,7 @@ namespace ts { const expression = createAssignmentCallback ? createAssignmentCallback(target, value, location) : setTextRange( - createAssignment(visitNode(target, visitor, isExpression), value), + context.factory.createAssignment(visitNode(target, visitor, isExpression), value), location ); expression.original = original; @@ -187,9 +186,9 @@ namespace ts { hoistTempVariables, emitExpression, emitBindingOrAssignment, - createArrayBindingOrAssignmentPattern: makeArrayBindingPattern, - createObjectBindingOrAssignmentPattern: makeObjectBindingPattern, - createArrayBindingOrAssignmentElement: makeBindingElement, + createArrayBindingOrAssignmentPattern: elements => makeArrayBindingPattern(context.factory, elements), + createObjectBindingOrAssignmentPattern: elements => makeObjectBindingPattern(context.factory, elements), + createArrayBindingOrAssignmentElement: name => makeBindingElement(context.factory, name), visitor }; @@ -200,15 +199,15 @@ namespace ts { // If the right-hand value of the assignment is also an assignment target then // we need to cache the right-hand value. initializer = ensureIdentifier(flattenContext, initializer, /*reuseIdentifierExpressions*/ false, initializer); - node = updateVariableDeclaration(node, node.name, node.type, initializer); + node = context.factory.updateVariableDeclaration(node, node.name, /*exclamationToken*/ undefined, /*type*/ undefined, initializer); } } flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer); if (pendingExpressions) { - const temp = createTempVariable(/*recordTempVariable*/ undefined); + const temp = context.factory.createTempVariable(/*recordTempVariable*/ undefined); if (hoistTempVariables) { - const value = inlineExpressions(pendingExpressions); + const value = context.factory.inlineExpressions(pendingExpressions); pendingExpressions = undefined; emitBindingOrAssignment(temp, value, /*location*/ undefined, /*original*/ undefined); } @@ -217,21 +216,21 @@ namespace ts { const pendingDeclaration = last(pendingDeclarations); pendingDeclaration.pendingExpressions = append( pendingDeclaration.pendingExpressions, - createAssignment(temp, pendingDeclaration.value) + context.factory.createAssignment(temp, pendingDeclaration.value) ); addRange(pendingDeclaration.pendingExpressions, pendingExpressions); pendingDeclaration.value = temp; } } for (const { pendingExpressions, name, value, location, original } of pendingDeclarations) { - const variable = createVariableDeclaration( + const variable = context.factory.createVariableDeclaration( name, + /*exclamationToken*/ undefined, /*type*/ undefined, - pendingExpressions ? inlineExpressions(append(pendingExpressions, value)) : value + pendingExpressions ? context.factory.inlineExpressions(append(pendingExpressions, value)) : value ); variable.original = original; setTextRange(variable, location); - aggregateTransformFlags(variable); declarations.push(variable); } return declarations; @@ -243,7 +242,7 @@ namespace ts { function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange | undefined, original: Node | undefined) { Debug.assertNode(target, isBindingName); if (pendingExpressions) { - value = inlineExpressions(append(pendingExpressions, value)); + value = context.factory.inlineExpressions(append(pendingExpressions, value)); pendingExpressions = undefined; } pendingDeclarations.push({ pendingExpressions, name: target, value, location, original }); @@ -274,7 +273,7 @@ namespace ts { } else if (!value) { // Use 'void 0' in absence of value and initializer - value = createVoidZero(); + value = flattenContext.context.factory.createVoidZero(); } } const bindingTarget = getTargetOfBindingOrAssignmentElement(element)!; // TODO: GH#18217 @@ -338,7 +337,7 @@ namespace ts { flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern); bindingElements = undefined; } - const rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables!, pattern); // TODO: GH#18217 + const rhsValue = flattenContext.context.getEmitHelperFactory().createRestHelper(value, elements, computedTempVariables, pattern); flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element); } } @@ -363,12 +362,13 @@ namespace ts { // Read the elements of the iterable into an array value = ensureIdentifier( flattenContext, - createReadHelper( - flattenContext.context, - value, - numElements > 0 && getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1]) - ? undefined - : numElements, + setTextRange( + flattenContext.context.getEmitHelperFactory().createReadHelper( + value, + numElements > 0 && getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1]) + ? undefined + : numElements + ), location ), /*reuseIdentifierExpressions*/ false, @@ -394,7 +394,7 @@ namespace ts { // If an array pattern contains an ObjectRest, we must cache the result so that we // can perform the ObjectRest destructuring in a different declaration if (element.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { - const temp = createTempVariable(/*recordTempVariable*/ undefined); + const temp = flattenContext.context.factory.createTempVariable(/*recordTempVariable*/ undefined); if (flattenContext.hoistTempVariables) { flattenContext.context.hoistVariableDeclaration(temp); } @@ -410,11 +410,11 @@ namespace ts { continue; } else if (!getRestIndicatorOfBindingOrAssignmentElement(element)) { - const rhsValue = createElementAccess(value, i); + const rhsValue = flattenContext.context.factory.createElementAccessExpression(value, i); flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element); } else if (i === numElements - 1) { - const rhsValue = createArraySlice(value, i); + const rhsValue = flattenContext.context.factory.createArraySliceCall(value, i); flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element); } } @@ -438,7 +438,7 @@ namespace ts { */ function createDefaultValueCheck(flattenContext: FlattenContext, value: Expression, defaultValue: Expression, location: TextRange): Expression { value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location); - return createConditional(createTypeCheck(value, "undefined"), defaultValue, value); + return flattenContext.context.factory.createConditionalExpression(flattenContext.context.factory.createTypeCheck(value, "undefined"), /*questionToken*/ undefined, defaultValue, /*colonToken*/ undefined, value); } /** @@ -454,16 +454,15 @@ namespace ts { function createDestructuringPropertyAccess(flattenContext: FlattenContext, value: Expression, propertyName: PropertyName): LeftHandSideExpression { if (isComputedPropertyName(propertyName)) { const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName); - return createElementAccess(value, argumentExpression); + return flattenContext.context.factory.createElementAccessExpression(value, argumentExpression); } else if (isStringOrNumericLiteralLike(propertyName)) { - const argumentExpression = getSynthesizedClone(propertyName); - argumentExpression.text = argumentExpression.text; - return createElementAccess(value, argumentExpression); + const argumentExpression = factory.cloneNode(propertyName); + return flattenContext.context.factory.createElementAccessExpression(value, argumentExpression); } else { - const name = createIdentifier(idText(propertyName)); - return createPropertyAccess(value, name); + const name = flattenContext.context.factory.createIdentifier(idText(propertyName)); + return flattenContext.context.factory.createPropertyAccessExpression(value, name); } } @@ -483,10 +482,10 @@ namespace ts { return value; } else { - const temp = createTempVariable(/*recordTempVariable*/ undefined); + const temp = flattenContext.context.factory.createTempVariable(/*recordTempVariable*/ undefined); if (flattenContext.hoistTempVariables) { flattenContext.context.hoistVariableDeclaration(temp); - flattenContext.emitExpression(setTextRange(createAssignment(temp, value), location)); + flattenContext.emitExpression(setTextRange(flattenContext.context.factory.createAssignment(temp, value), location)); } else { flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined); @@ -495,86 +494,29 @@ namespace ts { } } - function makeArrayBindingPattern(elements: BindingOrAssignmentElement[]) { + function makeArrayBindingPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { Debug.assertEachNode(elements, isArrayBindingElement); - return createArrayBindingPattern(elements); + return factory.createArrayBindingPattern(elements); } - function makeArrayAssignmentPattern(elements: BindingOrAssignmentElement[]) { - return createArrayLiteral(map(elements, convertToArrayAssignmentElement)); + function makeArrayAssignmentPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { + return factory.createArrayLiteralExpression(map(elements, factory.converters.convertToArrayAssignmentElement)); } - function makeObjectBindingPattern(elements: BindingOrAssignmentElement[]) { + function makeObjectBindingPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { Debug.assertEachNode(elements, isBindingElement); - return createObjectBindingPattern(elements); + return factory.createObjectBindingPattern(elements); } - function makeObjectAssignmentPattern(elements: BindingOrAssignmentElement[]) { - return createObjectLiteral(map(elements, convertToObjectAssignmentElement)); + function makeObjectAssignmentPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { + return factory.createObjectLiteralExpression(map(elements, factory.converters.convertToObjectAssignmentElement)); } - function makeBindingElement(name: Identifier) { - return createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name); + function makeBindingElement(factory: NodeFactory, name: Identifier) { + return factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name); } function makeAssignmentElement(name: Identifier) { return name; } - - export const restHelper: UnscopedEmitHelper = { - name: "typescript:rest", - importName: "__rest", - scoped: false, - text: ` - var __rest = (this && this.__rest) || function (s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; - };` - }; - - /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement - * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);` - */ - function createRestCall(context: TransformationContext, value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[], location: TextRange): Expression { - context.requestEmitHelper(restHelper); - const propertyNames: Expression[] = []; - let computedTempVariableOffset = 0; - for (let i = 0; i < elements.length - 1; i++) { - const propertyName = getPropertyNameOfBindingOrAssignmentElement(elements[i]); - if (propertyName) { - if (isComputedPropertyName(propertyName)) { - const temp = computedTempVariables[computedTempVariableOffset]; - computedTempVariableOffset++; - // typeof _tmp === "symbol" ? _tmp : _tmp + "" - propertyNames.push( - createConditional( - createTypeCheck(temp, "symbol"), - temp, - createAdd(temp, createLiteral("")) - ) - ); - } - else { - propertyNames.push(createLiteral(propertyName)); - } - } - } - return createCall( - getUnscopedHelperName("__rest"), - /*typeArguments*/ undefined, - [ - value, - setTextRange( - createArrayLiteral(propertyNames), - location - ) - ]); - } } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 07c0e2782711e..dc4078caa2433 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -244,6 +244,8 @@ namespace ts { export function transformES2015(context: TransformationContext) { const { + factory, + getEmitHelperFactory: emitHelpers, startLexicalEnvironment, resumeLexicalEnvironment, endLexicalEnvironment, @@ -265,7 +267,7 @@ namespace ts { function recordTaggedTemplateString(temp: Identifier) { taggedTemplateStringDeclarations = append( taggedTemplateStringDeclarations, - createVariableDeclaration(temp)); + factory.createVariableDeclaration(temp)); } /** @@ -280,7 +282,7 @@ namespace ts { */ let enabledSubstitutions: ES2015SubstitutionFlags; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { if (node.isDeclarationFile) { @@ -328,10 +330,26 @@ namespace ts { && !(node).expression; } + function isOrMayContainReturnCompletion(node: Node) { + return node.transformFlags & TransformFlags.ContainsHoistedDeclarationOrCompletion + && (isReturnStatement(node) + || isIfStatement(node) + || isWithStatement(node) + || isSwitchStatement(node) + || isCaseBlock(node) + || isCaseClause(node) + || isDefaultClause(node) + || isTryStatement(node) + || isCatchClause(node) + || isLabeledStatement(node) + || isIterationStatement(node, /*lookInLabeledStatements*/ false) + || isBlock(node)); + } + function shouldVisitNode(node: Node): boolean { return (node.transformFlags & TransformFlags.ContainsES2015) !== 0 || convertedLoopState !== undefined - || (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && (isStatement(node) || (node.kind === SyntaxKind.Block))) + || (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && isOrMayContainReturnCompletion(node)) || (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatement(node)) || (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0; } @@ -499,20 +517,19 @@ namespace ts { const prologue: Statement[] = []; const statements: Statement[] = []; startLexicalEnvironment(); - let statementOffset = addStandardPrologue(prologue, node.statements, /*ensureUseStrict*/ false); - statementOffset = addCustomPrologue(prologue, node.statements, statementOffset, visitor); + const statementOffset = factory.copyPrologue(node.statements, prologue, /*ensureUseStrict*/ false, visitor); addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); if (taggedTemplateStringDeclarations) { statements.push( - createVariableStatement(/*modifiers*/ undefined, - createVariableDeclarationList(taggedTemplateStringDeclarations))); + factory.createVariableStatement(/*modifiers*/ undefined, + factory.createVariableDeclarationList(taggedTemplateStringDeclarations))); } - mergeLexicalEnvironment(prologue, endLexicalEnvironment()); + factory.mergeLexicalEnvironment(prologue, endLexicalEnvironment()); insertCaptureThisForNodeIfNeeded(prologue, node); exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None); - return updateSourceFileNode( + return factory.updateSourceFile( node, - setTextRange(createNodeArray(concatenate(prologue, statements)), node.statements) + setTextRange(factory.createNodeArray(concatenate(prologue, statements)), node.statements) ); } @@ -536,7 +553,7 @@ namespace ts { } function returnCapturedThis(node: Node): ReturnStatement { - return setOriginalNode(createReturn(createFileLevelUniqueName("_this")), node); + return setOriginalNode(factory.createReturnStatement(factory.createUniqueName("_this", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)), node); } function visitReturnStatement(node: ReturnStatement): Statement { @@ -545,14 +562,14 @@ namespace ts { if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) { node = returnCapturedThis(node); } - return createReturn( - createObjectLiteral( + return factory.createReturnStatement( + factory.createObjectLiteralExpression( [ - createPropertyAssignment( - createIdentifier("value"), + factory.createPropertyAssignment( + factory.createIdentifier("value"), node.expression ? visitNode(node.expression, visitor, isExpression) - : createVoidZero() + : factory.createVoidZero() ) ] ) @@ -574,7 +591,7 @@ namespace ts { convertedLoopState.containsLexicalThis = true; return node; } - return convertedLoopState.thisName || (convertedLoopState.thisName = createUniqueName("this")); + return convertedLoopState.thisName || (convertedLoopState.thisName = factory.createUniqueName("this")); } return node; } @@ -584,7 +601,7 @@ namespace ts { return node; } if (resolver.isArgumentsLocalBinding(node)) { - return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments")); + return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = factory.createUniqueName("arguments")); } return node; } @@ -624,7 +641,7 @@ namespace ts { setLabeledJump(convertedLoopState, /*isBreak*/ false, idText(label), labelMarker); } } - let returnExpression: Expression = createLiteral(labelMarker); + let returnExpression: Expression = factory.createStringLiteral(labelMarker); if (convertedLoopState.loopOutParameters.length) { const outParams = convertedLoopState.loopOutParameters; let expr: Expression | undefined; @@ -634,12 +651,12 @@ namespace ts { expr = copyExpr; } else { - expr = createBinary(expr!, SyntaxKind.CommaToken, copyExpr); + expr = factory.createBinaryExpression(expr!, SyntaxKind.CommaToken, copyExpr); } } - returnExpression = createBinary(expr!, SyntaxKind.CommaToken, returnExpression); + returnExpression = factory.createBinaryExpression(expr!, SyntaxKind.CommaToken, returnExpression); } - return createReturn(returnExpression); + return factory.createReturnStatement(returnExpression); } } return visitEachChild(node, visitor, context); @@ -661,8 +678,9 @@ namespace ts { // return C; // }()); - const variable = createVariableDeclaration( - getLocalName(node, /*allowComments*/ true), + const variable = factory.createVariableDeclaration( + factory.getLocalName(node, /*allowComments*/ true), + /*exclamationToken*/ undefined, /*type*/ undefined, transformClassLikeDeclarationToExpression(node) ); @@ -670,7 +688,7 @@ namespace ts { setOriginalNode(variable, node); const statements: Statement[] = []; - const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable])); + const statement = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([variable])); setOriginalNode(statement, node); setTextRange(statement, node); @@ -680,8 +698,8 @@ namespace ts { // Add an `export default` statement for default exports (for `--target es5 --module es6`) if (hasSyntacticModifier(node, ModifierFlags.Export)) { const exportStatement = hasSyntacticModifier(node, ModifierFlags.Default) - ? createExportDefault(getLocalName(node)) - : createExternalModuleExport(getLocalName(node)); + ? factory.createExportDefault(factory.getLocalName(node)) + : factory.createExternalModuleExport(factory.getLocalName(node)); setOriginalNode(exportStatement, statement); statements.push(exportStatement); @@ -690,7 +708,7 @@ namespace ts { const emitFlags = getEmitFlags(node); if ((emitFlags & EmitFlags.HasEndOfDeclarationMarker) === 0) { // Add a DeclarationMarker as a marker for the end of the declaration - statements.push(createEndOfDeclarationMarker(node)); + statements.push(factory.createEndOfDeclarationMarker(node)); setEmitFlags(statement, emitFlags | EmitFlags.HasEndOfDeclarationMarker); } @@ -750,12 +768,12 @@ namespace ts { } const extendsClauseElement = getClassExtendsHeritageElement(node); - const classFunction = createFunctionExpression( + const classFunction = factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - extendsClauseElement ? [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, createFileLevelUniqueName("_super"))] : [], + extendsClauseElement ? [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel))] : [], /*type*/ undefined, transformClassBody(node, extendsClauseElement) ); @@ -767,16 +785,16 @@ namespace ts { // "inner" and "outer" below are added purely to preserve source map locations from // the old emitter - const inner = createPartiallyEmittedExpression(classFunction); - inner.end = node.end; + const inner = factory.createPartiallyEmittedExpression(classFunction); + setTextRangeEnd(inner, node.end); setEmitFlags(inner, EmitFlags.NoComments); - const outer = createPartiallyEmittedExpression(inner); - outer.end = skipTrivia(currentText, node.pos); + const outer = factory.createPartiallyEmittedExpression(inner); + setTextRangeEnd(outer, skipTrivia(currentText, node.pos)); setEmitFlags(outer, EmitFlags.NoComments); - const result = createParen( - createCall( + const result = factory.createParenthesizedExpression( + factory.createCallExpression( outer, /*typeArguments*/ undefined, extendsClauseElement @@ -803,22 +821,22 @@ namespace ts { // Create a synthetic text range for the return statement. const closingBraceLocation = createTokenRange(skipTrivia(currentText, node.members.end), SyntaxKind.CloseBraceToken); - const localName = getInternalName(node); + const localName = factory.getInternalName(node); // The following partially-emitted expression exists purely to align our sourcemap // emit with the original emitter. - const outer = createPartiallyEmittedExpression(localName); - outer.end = closingBraceLocation.end; + const outer = factory.createPartiallyEmittedExpression(localName); + setTextRangeEnd(outer, closingBraceLocation.end); setEmitFlags(outer, EmitFlags.NoComments); - const statement = createReturn(outer); - statement.pos = closingBraceLocation.pos; + const statement = factory.createReturnStatement(outer); + setTextRangePos(statement, closingBraceLocation.pos); setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps); statements.push(statement); insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment()); - const block = createBlock(setTextRange(createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true); + const block = factory.createBlock(setTextRange(factory.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true); setEmitFlags(block, EmitFlags.NoComments); return block; } @@ -834,8 +852,8 @@ namespace ts { if (extendsClauseElement) { statements.push( setTextRange( - createExpressionStatement( - createExtendsHelper(context, getInternalName(node)) + factory.createExpressionStatement( + emitHelpers().createExtendsHelper(factory.getInternalName(node)) ), /*location*/ extendsClauseElement ) @@ -856,11 +874,11 @@ namespace ts { const ancestorFacts = enterSubtree(HierarchyFacts.ConstructorExcludes, HierarchyFacts.ConstructorIncludes); const constructor = getFirstConstructorWithBody(node); const hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined); - const constructorFunction = createFunctionDeclaration( + const constructorFunction = factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, - getInternalName(node), + factory.getInternalName(node), /*typeParameters*/ undefined, transformConstructorParameters(constructor, hasSynthesizedSuper), /*type*/ undefined, @@ -900,17 +918,17 @@ namespace ts { // If that's the case we can just immediately return the result of a 'super()' call. const statements: Statement[] = []; resumeLexicalEnvironment(); - mergeLexicalEnvironment(statements, endLexicalEnvironment()); + factory.mergeLexicalEnvironment(statements, endLexicalEnvironment()); if (isDerivedClass) { // return _super !== null && _super.apply(this, arguments) || this; - statements.push(createReturn(createDefaultSuperCallOrThis())); + statements.push(factory.createReturnStatement(createDefaultSuperCallOrThis())); } - const statementsArray = createNodeArray(statements); + const statementsArray = factory.createNodeArray(statements); setTextRange(statementsArray, node.members); - const block = createBlock(statementsArray, /*multiLine*/ true); + const block = factory.createBlock(statementsArray, /*multiLine*/ true); setTextRange(block, node); setEmitFlags(block, EmitFlags.NoComments); return block; @@ -956,10 +974,10 @@ namespace ts { // we're going to assume that we should just transform everything after that. // The assumption is that no prior step in the pipeline has added any prologue directives. let statementOffset = 0; - if (!hasSynthesizedSuper) statementOffset = addStandardPrologue(prologue, constructor.body.statements, /*ensureUseStrict*/ false); + if (!hasSynthesizedSuper) statementOffset = factory.copyStandardPrologue(constructor.body.statements, prologue, /*ensureUseStrict*/ false); addDefaultValueAssignmentsIfNeeded(statements, constructor); addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper); - if (!hasSynthesizedSuper) statementOffset = addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor); + if (!hasSynthesizedSuper) statementOffset = factory.copyCustomPrologue(constructor.body.statements, statements, statementOffset, visitor); // If the first statement is a call to `super()`, visit the statement directly let superCallExpression: Expression | undefined; @@ -981,7 +999,7 @@ namespace ts { // visit the remaining statements addRange(statements, visitNodes(constructor.body.statements, visitor, isStatement, /*start*/ statementOffset)); - mergeLexicalEnvironment(prologue, endLexicalEnvironment()); + factory.mergeLexicalEnvironment(prologue, endLexicalEnvironment()); insertCaptureNewTargetIfNeeded(prologue, constructor, /*copyOnWrite*/ false); if (isDerivedClass) { @@ -1006,7 +1024,7 @@ namespace ts { // })(Base); // ``` const superCall = cast(cast(superCallExpression, isBinaryExpression).left, isCallExpression); - const returnStatement = createReturn(superCallExpression); + const returnStatement = factory.createReturnStatement(superCallExpression); setCommentRange(returnStatement, getCommentRange(superCall)); setEmitFlags(superCall, EmitFlags.NoComments); statements.push(returnStatement); @@ -1039,7 +1057,7 @@ namespace ts { insertCaptureThisForNode(statements, constructor, superCallExpression || createActualThis()); if (!isSufficientlyCoveredByReturnStatements(constructor.body)) { - statements.push(createReturn(createFileLevelUniqueName("_this"))); + statements.push(factory.createReturnStatement(factory.createUniqueName("_this", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel))); } } } @@ -1061,9 +1079,9 @@ namespace ts { insertCaptureThisForNodeIfNeeded(prologue, constructor); } - const block = createBlock( + const block = factory.createBlock( setTextRange( - createNodeArray( + factory.createNodeArray( concatenate(prologue, statements) ), /*location*/ constructor.body.statements @@ -1106,20 +1124,20 @@ namespace ts { } function createActualThis() { - return setEmitFlags(createThis(), EmitFlags.NoSubstitution); + return setEmitFlags(factory.createThis(), EmitFlags.NoSubstitution); } function createDefaultSuperCallOrThis() { - return createLogicalOr( - createLogicalAnd( - createStrictInequality( - createFileLevelUniqueName("_super"), - createNull() + return factory.createLogicalOr( + factory.createLogicalAnd( + factory.createStrictInequality( + factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), + factory.createNull() ), - createFunctionApply( - createFileLevelUniqueName("_super"), + factory.createFunctionApplyCall( + factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), createActualThis(), - createIdentifier("arguments"), + factory.createIdentifier("arguments"), ) ), createActualThis() @@ -1141,11 +1159,11 @@ namespace ts { // evaluated inside the function body. return setOriginalNode( setTextRange( - createParameter( + factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, - getGeneratedNameForNode(node), + factory.getGeneratedNameForNode(node), /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined @@ -1159,7 +1177,7 @@ namespace ts { // Initializers are elided return setOriginalNode( setTextRange( - createParameter( + factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -1232,15 +1250,15 @@ namespace ts { insertStatementAfterCustomPrologue( statements, setEmitFlags( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( flattenDestructuringBinding( parameter, visitor, context, FlattenLevel.All, - getGeneratedNameForNode(parameter) + factory.getGeneratedNameForNode(parameter) ) ) ), @@ -1253,9 +1271,9 @@ namespace ts { insertStatementAfterCustomPrologue( statements, setEmitFlags( - createExpressionStatement( - createAssignment( - getGeneratedNameForNode(parameter), + factory.createExpressionStatement( + factory.createAssignment( + factory.getGeneratedNameForNode(parameter), visitNode(initializer, visitor, isExpression) ) ), @@ -1277,16 +1295,17 @@ namespace ts { */ function insertDefaultValueAssignmentForInitializer(statements: Statement[], parameter: ParameterDeclaration, name: Identifier, initializer: Expression): void { initializer = visitNode(initializer, visitor, isExpression); - const statement = createIf( - createTypeCheck(getSynthesizedClone(name), "undefined"), + const statement = factory.createIfStatement( + factory.createTypeCheck(factory.cloneNode(name), "undefined"), setEmitFlags( setTextRange( - createBlock([ - createExpressionStatement( + factory.createBlock([ + factory.createExpressionStatement( setEmitFlags( setTextRange( - createAssignment( - setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap), + factory.createAssignment( + // TODO(rbuckton): Does this need to be parented? + setEmitFlags(setParent(setTextRange(factory.cloneNode(name), name), name.parent), EmitFlags.NoSourceMap), setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer) | EmitFlags.NoComments) ), parameter @@ -1336,25 +1355,27 @@ namespace ts { } // `declarationName` is the name of the local declaration for the parameter. - const declarationName = parameter.name.kind === SyntaxKind.Identifier ? getMutableClone(parameter.name) : createTempVariable(/*recordTempVariable*/ undefined); + // TODO(rbuckton): Does this need to be parented? + const declarationName = parameter.name.kind === SyntaxKind.Identifier ? setParent(setTextRange(factory.cloneNode(parameter.name), parameter.name), parameter.name.parent) : factory.createTempVariable(/*recordTempVariable*/ undefined); setEmitFlags(declarationName, EmitFlags.NoSourceMap); // `expressionName` is the name of the parameter used in expressions. - const expressionName = parameter.name.kind === SyntaxKind.Identifier ? getSynthesizedClone(parameter.name) : declarationName; + const expressionName = parameter.name.kind === SyntaxKind.Identifier ? factory.cloneNode(parameter.name) : declarationName; const restIndex = node.parameters.length - 1; - const temp = createLoopVariable(); + const temp = factory.createLoopVariable(); // var param = []; prologueStatements.push( setEmitFlags( setTextRange( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( declarationName, + /*exclamationToken*/ undefined, /*type*/ undefined, - createArrayLiteral([]) + factory.createArrayLiteralExpression([]) ) ]) ), @@ -1367,33 +1388,33 @@ namespace ts { // for (var _i = restIndex; _i < arguments.length; _i++) { // param[_i - restIndex] = arguments[_i]; // } - const forStatement = createFor( + const forStatement = factory.createForStatement( setTextRange( - createVariableDeclarationList([ - createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex)) + factory.createVariableDeclarationList([ + factory.createVariableDeclaration(temp, /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(restIndex)) ]), parameter ), setTextRange( - createLessThan( + factory.createLessThan( temp, - createPropertyAccess(createIdentifier("arguments"), "length") + factory.createPropertyAccessExpression(factory.createIdentifier("arguments"), "length") ), parameter ), - setTextRange(createPostfixIncrement(temp), parameter), - createBlock([ + setTextRange(factory.createPostfixIncrement(temp), parameter), + factory.createBlock([ startOnNewLine( setTextRange( - createExpressionStatement( - createAssignment( - createElementAccess( + factory.createExpressionStatement( + factory.createAssignment( + factory.createElementAccessExpression( expressionName, restIndex === 0 ? temp - : createSubtract(temp, createLiteral(restIndex)) + : factory.createSubtract(temp, factory.createNumericLiteral(restIndex)) ), - createElementAccess(createIdentifier("arguments"), temp) + factory.createElementAccessExpression(factory.createIdentifier("arguments"), temp) ) ), /*location*/ parameter @@ -1411,9 +1432,9 @@ namespace ts { prologueStatements.push( setEmitFlags( setTextRange( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( flattenDestructuringBinding(parameter, visitor, context, FlattenLevel.All, expressionName), ) ), @@ -1437,7 +1458,7 @@ namespace ts { */ function insertCaptureThisForNodeIfNeeded(statements: Statement[], node: Node): boolean { if (hierarchyFacts & HierarchyFacts.CapturedLexicalThis && node.kind !== SyntaxKind.ArrowFunction) { - insertCaptureThisForNode(statements, node, createThis()); + insertCaptureThisForNode(statements, node, factory.createThis()); return true; } return false; @@ -1445,11 +1466,12 @@ namespace ts { function insertCaptureThisForNode(statements: Statement[], node: Node, initializer: Expression | undefined): void { enableSubstitutionsForCapturedThis(); - const captureThisStatement = createVariableStatement( + const captureThisStatement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - createFileLevelUniqueName("_this"), + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + factory.createUniqueName("_this", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), + /*exclamationToken*/ undefined, /*type*/ undefined, initializer ) @@ -1472,14 +1494,14 @@ namespace ts { case SyntaxKind.SetAccessor: // Methods and accessors cannot be constructors, so 'new.target' will // always return 'undefined'. - newTarget = createVoidZero(); + newTarget = factory.createVoidZero(); break; case SyntaxKind.Constructor: // Class constructors can only be called with `new`, so `this.constructor` // should be relatively safe to use. - newTarget = createPropertyAccess( - setEmitFlags(createThis(), EmitFlags.NoSubstitution), + newTarget = factory.createPropertyAccessExpression( + setEmitFlags(factory.createThis(), EmitFlags.NoSubstitution), "constructor" ); break; @@ -1488,20 +1510,22 @@ namespace ts { case SyntaxKind.FunctionExpression: // Functions can be called or constructed, and may have a `this` due to // being a member or when calling an imported function via `other_1.f()`. - newTarget = createConditional( - createLogicalAnd( - setEmitFlags(createThis(), EmitFlags.NoSubstitution), - createBinary( - setEmitFlags(createThis(), EmitFlags.NoSubstitution), + newTarget = factory.createConditionalExpression( + factory.createLogicalAnd( + setEmitFlags(factory.createThis(), EmitFlags.NoSubstitution), + factory.createBinaryExpression( + setEmitFlags(factory.createThis(), EmitFlags.NoSubstitution), SyntaxKind.InstanceOfKeyword, - getLocalName(node) + factory.getLocalName(node) ) ), - createPropertyAccess( - setEmitFlags(createThis(), EmitFlags.NoSubstitution), + /*questionToken*/ undefined, + factory.createPropertyAccessExpression( + setEmitFlags(factory.createThis(), EmitFlags.NoSubstitution), "constructor" ), - createVoidZero() + /*colonToken*/ undefined, + factory.createVoidZero() ); break; @@ -1509,11 +1533,12 @@ namespace ts { return Debug.failBadSyntaxKind(node); } - const captureNewTargetStatement = createVariableStatement( + const captureNewTargetStatement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - createFileLevelUniqueName("_newTarget"), + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + factory.createUniqueName("_newTarget", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), + /*exclamationToken*/ undefined, /*type*/ undefined, newTarget ) @@ -1576,7 +1601,7 @@ namespace ts { * @param member The SemicolonClassElement node. */ function transformSemicolonClassElementToStatement(member: SemicolonClassElement) { - return setTextRange(createEmptyStatement(), member); + return setTextRange(factory.createEmptyStatement(), member); } /** @@ -1593,17 +1618,17 @@ namespace ts { let e: Expression; if (!isPrivateIdentifier(propertyName) && context.getCompilerOptions().useDefineForClassFields) { const name = isComputedPropertyName(propertyName) ? propertyName.expression - : isIdentifier(propertyName) ? createStringLiteral(unescapeLeadingUnderscores(propertyName.escapedText)) + : isIdentifier(propertyName) ? factory.createStringLiteral(unescapeLeadingUnderscores(propertyName.escapedText)) : propertyName; - e = createObjectDefinePropertyCall(receiver, name, createPropertyDescriptor({ value: memberFunction, enumerable: false, writable: true, configurable: true })); + e = factory.createObjectDefinePropertyCall(receiver, name, factory.createPropertyDescriptor({ value: memberFunction, enumerable: false, writable: true, configurable: true })); } else { - const memberName = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ member.name); - e = createAssignment(memberName, memberFunction); + const memberName = createMemberAccessForPropertyName(factory, receiver, propertyName, /*location*/ member.name); + e = factory.createAssignment(memberName, memberFunction); } setEmitFlags(memberFunction, EmitFlags.NoComments); setSourceMapRange(memberFunction, sourceMapRange); - const statement = setTextRange(createExpressionStatement(e), /*location*/ member); + const statement = setTextRange(factory.createExpressionStatement(e), /*location*/ member); setOriginalNode(statement, member); setCommentRange(statement, commentRange); @@ -1622,7 +1647,7 @@ namespace ts { * @param accessors The set of related get/set accessors. */ function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations, container: Node): Statement { - const statement = createExpressionStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false)); + const statement = factory.createExpressionStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false)); // The location for the statement is used to emit source maps only. // No comments should be emitted for this statement to align with the // old emitter. @@ -1640,7 +1665,8 @@ namespace ts { function transformAccessorsToExpression(receiver: LeftHandSideExpression, { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations, container: Node, startsOnNewLine: boolean): Expression { // To align with source maps in the old emitter, the receiver and property name // arguments are both mapped contiguously to the accessor name. - const target = getMutableClone(receiver); + // TODO(rbuckton): Does this need to be parented? + const target = setParent(setTextRange(factory.cloneNode(receiver), receiver), receiver.parent); setEmitFlags(target, EmitFlags.NoComments | EmitFlags.NoTrailingSourceMap); setSourceMapRange(target, firstAccessor.name); @@ -1648,7 +1674,7 @@ namespace ts { if (isPrivateIdentifier(visitedAccessorName)) { return Debug.failBadSyntaxKind(visitedAccessorName, "Encountered unhandled private identifier while transforming ES2015."); } - const propertyName = createExpressionForPropertyName(visitedAccessorName); + const propertyName = createExpressionForPropertyName(factory, visitedAccessorName); setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoLeadingSourceMap); setSourceMapRange(propertyName, firstAccessor.name); @@ -1657,7 +1683,7 @@ namespace ts { const getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined, container); setSourceMapRange(getterFunction, getSourceMapRange(getAccessor)); setEmitFlags(getterFunction, EmitFlags.NoLeadingComments); - const getter = createPropertyAssignment("get", getterFunction); + const getter = factory.createPropertyAssignment("get", getterFunction); setCommentRange(getter, getCommentRange(getAccessor)); properties.push(getter); } @@ -1666,23 +1692,23 @@ namespace ts { const setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined, container); setSourceMapRange(setterFunction, getSourceMapRange(setAccessor)); setEmitFlags(setterFunction, EmitFlags.NoLeadingComments); - const setter = createPropertyAssignment("set", setterFunction); + const setter = factory.createPropertyAssignment("set", setterFunction); setCommentRange(setter, getCommentRange(setAccessor)); properties.push(setter); } properties.push( - createPropertyAssignment("enumerable", getAccessor || setAccessor ? createFalse() : createTrue()), - createPropertyAssignment("configurable", createTrue()) + factory.createPropertyAssignment("enumerable", getAccessor || setAccessor ? factory.createFalse() : factory.createTrue()), + factory.createPropertyAssignment("configurable", factory.createTrue()) ); - const call = createCall( - createPropertyAccess(createIdentifier("Object"), "defineProperty"), + const call = factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ target, propertyName, - createObjectLiteral(properties, /*multiLine*/ true) + factory.createObjectLiteralExpression(properties, /*multiLine*/ true) ] ); if (startsOnNewLine) { @@ -1705,7 +1731,7 @@ namespace ts { const savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; const ancestorFacts = enterSubtree(HierarchyFacts.ArrowFunctionExcludes, HierarchyFacts.ArrowFunctionIncludes); - const func = createFunctionExpression( + const func = factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, @@ -1744,12 +1770,12 @@ namespace ts { const parameters = visitParameterList(node.parameters, visitor, context); const body = transformFunctionBody(node); const name = hierarchyFacts & HierarchyFacts.NewTarget - ? getLocalName(node) + ? factory.getLocalName(node) : node.name; exitSubtree(ancestorFacts, HierarchyFacts.FunctionSubtreeExcludes, HierarchyFacts.None); convertedLoopState = savedConvertedLoopState; - return updateFunctionExpression( + return factory.updateFunctionExpression( node, /*modifiers*/ undefined, node.asteriskToken, @@ -1773,12 +1799,12 @@ namespace ts { const parameters = visitParameterList(node.parameters, visitor, context); const body = transformFunctionBody(node); const name = hierarchyFacts & HierarchyFacts.NewTarget - ? getLocalName(node) + ? factory.getLocalName(node) : node.name; exitSubtree(ancestorFacts, HierarchyFacts.FunctionSubtreeExcludes, HierarchyFacts.None); convertedLoopState = savedConvertedLoopState; - return updateFunctionDeclaration( + return factory.updateFunctionDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), @@ -1807,14 +1833,14 @@ namespace ts { const parameters = visitParameterList(node.parameters, visitor, context); const body = transformFunctionBody(node); if (hierarchyFacts & HierarchyFacts.NewTarget && !name && (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression)) { - name = getGeneratedNameForNode(node); + name = factory.getGeneratedNameForNode(node); } exitSubtree(ancestorFacts, HierarchyFacts.FunctionSubtreeExcludes, HierarchyFacts.None); convertedLoopState = savedConvertedLoopState; return setOriginalNode( setTextRange( - createFunctionExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, node.asteriskToken, name, @@ -1849,9 +1875,9 @@ namespace ts { if (isBlock(body)) { // ensureUseStrict is false because no new prologue-directive should be added. // addStandardPrologue will put already-existing directives at the beginning of the target statement-array - statementOffset = addStandardPrologue(prologue, body.statements, /*ensureUseStrict*/ false); - statementOffset = addCustomPrologue(statements, body.statements, statementOffset, visitor, isHoistedFunction); - statementOffset = addCustomPrologue(statements, body.statements, statementOffset, visitor, isHoistedVariableStatement); + statementOffset = factory.copyStandardPrologue(body.statements, prologue, /*ensureUseStrict*/ false); + statementOffset = factory.copyCustomPrologue(body.statements, statements, statementOffset, visitor, isHoistedFunction); + statementOffset = factory.copyCustomPrologue(body.statements, statements, statementOffset, visitor, isHoistedVariableStatement); } multiLine = addDefaultValueAssignmentsIfNeeded(statements, node) || multiLine; @@ -1859,7 +1885,7 @@ namespace ts { if (isBlock(body)) { // addCustomPrologue puts already-existing directives at the beginning of the target statement-array - statementOffset = addCustomPrologue(statements, body.statements, statementOffset, visitor); + statementOffset = factory.copyCustomPrologue(body.statements, statements, statementOffset, visitor); statementsLocation = body.statements; addRange(statements, visitNodes(body.statements, visitor, isStatement, statementOffset)); @@ -1889,7 +1915,7 @@ namespace ts { } const expression = visitNode(body, visitor, isExpression); - const returnStatement = createReturn(expression); + const returnStatement = factory.createReturnStatement(expression); setTextRange(returnStatement, body); moveSyntheticComments(returnStatement, body); setEmitFlags(returnStatement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTrailingComments); @@ -1900,7 +1926,7 @@ namespace ts { closeBraceLocation = body; } - mergeLexicalEnvironment(prologue, endLexicalEnvironment()); + factory.mergeLexicalEnvironment(prologue, endLexicalEnvironment()); insertCaptureNewTargetIfNeeded(prologue, node, /*copyOnWrite*/ false); insertCaptureThisForNodeIfNeeded(prologue, node); @@ -1915,7 +1941,7 @@ namespace ts { return body; } - const block = createBlock(setTextRange(createNodeArray(statements), statementsLocation), multiLine); + const block = factory.createBlock(setTextRange(factory.createNodeArray(statements), statementsLocation), multiLine); setTextRange(block, node.body); if (!multiLine && singleLine) { setEmitFlags(block, EmitFlags.SingleLine); @@ -1951,9 +1977,9 @@ namespace ts { // If we are here it is most likely because our expression is a destructuring assignment. switch (node.expression.kind) { case SyntaxKind.ParenthesizedExpression: - return updateExpressionStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false)); + return factory.updateExpressionStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false)); case SyntaxKind.BinaryExpression: - return updateExpressionStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false)); + return factory.updateExpressionStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false)); } return visitEachChild(node, visitor, context); } @@ -1973,9 +1999,9 @@ namespace ts { // we pass that information along to the children that care about it. switch (node.expression.kind) { case SyntaxKind.ParenthesizedExpression: - return updateParen(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false)); + return factory.updateParenthesizedExpression(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false)); case SyntaxKind.BinaryExpression: - return updateParen(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false)); + return factory.updateParenthesizedExpression(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false)); } } return visitEachChild(node, visitor, context); @@ -2026,7 +2052,7 @@ namespace ts { ); } else { - assignment = createBinary(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); + assignment = factory.createBinaryExpression(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); setTextRange(assignment, decl); } @@ -2034,7 +2060,7 @@ namespace ts { } } if (assignments) { - updated = setTextRange(createExpressionStatement(inlineExpressions(assignments)), node); + updated = setTextRange(factory.createExpressionStatement(factory.inlineExpressions(assignments)), node); } else { // none of declarations has initializer - the entire variable statement can be deleted @@ -2064,7 +2090,7 @@ namespace ts { ? visitVariableDeclarationInLetDeclarationList : visitVariableDeclaration); - const declarationList = createVariableDeclarationList(declarations); + const declarationList = factory.createVariableDeclarationList(declarations); setOriginalNode(declarationList, node); setTextRange(declarationList, node); setCommentRange(declarationList, node); @@ -2174,9 +2200,7 @@ namespace ts { } if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) { - const clone = getMutableClone(node); - clone.initializer = createVoidZero(); - return clone; + return factory.updateVariableDeclaration(node, node.name, /*exclamationToken*/ undefined, /*type*/ undefined, factory.createVoidZero()); } return visitEachChild(node, visitor, context); @@ -2223,7 +2247,7 @@ namespace ts { const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel); return isIterationStatement(statement, /*lookInLabeledStatements*/ false) ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node) - : restoreEnclosingLabel(visitNode(statement, visitor, isStatement, liftToBlock), node, convertedLoopState && resetLabel); + : factory.restoreEnclosingLabel(visitNode(statement, visitor, isStatement, factory.liftToBlock), node, convertedLoopState && resetLabel); } function visitIterationStatement(node: IterationStatement, outermostLabeledStatement: LabeledStatement) { @@ -2300,7 +2324,7 @@ namespace ts { boundValue ); - const declarationList = setTextRange(createVariableDeclarationList(declarations), node.initializer); + const declarationList = setTextRange(factory.createVariableDeclarationList(declarations), node.initializer); setOriginalNode(declarationList, node.initializer); // Adjust the source map range for the first declaration to align with the old @@ -2308,7 +2332,7 @@ namespace ts { setSourceMapRange(declarationList, createRange(declarations[0].pos, last(declarations).end)); statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, declarationList ) @@ -2319,13 +2343,14 @@ namespace ts { // to emit it separately. statements.push( setTextRange( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, setOriginalNode( setTextRange( - createVariableDeclarationList([ - createVariableDeclaration( - firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined), + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + firstOriginalDeclaration ? firstOriginalDeclaration.name : factory.createTempVariable(/*recordTempVariable*/ undefined), + /*exclamationToken*/ undefined, /*type*/ undefined, boundValue ) @@ -2343,14 +2368,13 @@ namespace ts { else { // Initializer is an expression. Emit the expression in the body, so that it's // evaluated on every iteration. - const assignment = createAssignment(initializer, boundValue); + const assignment = factory.createAssignment(initializer, boundValue); if (isDestructuringAssignment(assignment)) { - aggregateTransformFlags(assignment); - statements.push(createExpressionStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false))); + statements.push(factory.createExpressionStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false))); } else { - assignment.end = initializer.end; - statements.push(setTextRange(createExpressionStatement(visitNode(assignment, visitor, isExpression)), moveRangeEnd(initializer, -1))); + setTextRangeEnd(assignment, initializer.end); + statements.push(setTextRange(factory.createExpressionStatement(visitNode(assignment, visitor, isExpression)), moveRangeEnd(initializer, -1))); } } @@ -2358,9 +2382,9 @@ namespace ts { return createSyntheticBlockForConvertedStatements(addRange(statements, convertedLoopBodyStatements)); } else { - const statement = visitNode(node.statement, visitor, isStatement, liftToBlock); + const statement = visitNode(node.statement, visitor, isStatement, factory.liftToBlock); if (isBlock(statement)) { - return updateBlock(statement, setTextRange(createNodeArray(concatenate(statements, statement.statements)), statement.statements)); + return factory.updateBlock(statement, setTextRange(factory.createNodeArray(concatenate(statements, statement.statements)), statement.statements)); } else { statements.push(statement); @@ -2371,8 +2395,8 @@ namespace ts { function createSyntheticBlockForConvertedStatements(statements: Statement[]) { return setEmitFlags( - createBlock( - createNodeArray(statements), + factory.createBlock( + factory.createNodeArray(statements), /*multiLine*/ true ), EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps @@ -2408,35 +2432,35 @@ namespace ts { // for (let v of arr) { } // // we don't want to emit a temporary variable for the RHS, just use it directly. - const counter = createLoopVariable(); - const rhsReference = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined); + const counter = factory.createLoopVariable(); + const rhsReference = isIdentifier(expression) ? factory.getGeneratedNameForNode(expression) : factory.createTempVariable(/*recordTempVariable*/ undefined); // The old emitter does not emit source maps for the expression setEmitFlags(expression, EmitFlags.NoSourceMap | getEmitFlags(expression)); const forStatement = setTextRange( - createFor( + factory.createForStatement( /*initializer*/ setEmitFlags( setTextRange( - createVariableDeclarationList([ - setTextRange(createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0)), moveRangePos(node.expression, -1)), - setTextRange(createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression) + factory.createVariableDeclarationList([ + setTextRange(factory.createVariableDeclaration(counter, /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(0)), moveRangePos(node.expression, -1)), + setTextRange(factory.createVariableDeclaration(rhsReference, /*exclamationToken*/ undefined, /*type*/ undefined, expression), node.expression) ]), node.expression ), EmitFlags.NoHoisting ), /*condition*/ setTextRange( - createLessThan( + factory.createLessThan( counter, - createPropertyAccess(rhsReference, "length") + factory.createPropertyAccessExpression(rhsReference, "length") ), node.expression ), - /*incrementor*/ setTextRange(createPostfixIncrement(counter), node.expression), + /*incrementor*/ setTextRange(factory.createPostfixIncrement(counter), node.expression), /*statement*/ convertForOfStatementHead( node, - createElementAccess(rhsReference, counter), + factory.createElementAccessExpression(rhsReference, counter), convertedLoopBodyStatements ) ), @@ -2446,45 +2470,45 @@ namespace ts { // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter. setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps); setTextRange(forStatement, node); - return restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel); + return factory.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel); } function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[], ancestorFacts: HierarchyFacts): Statement { const expression = visitNode(node.expression, visitor, isExpression); - const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined); - const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined); - const errorRecord = createUniqueName("e"); - const catchVariable = getGeneratedNameForNode(errorRecord); - const returnMethod = createTempVariable(/*recordTempVariable*/ undefined); - const values = createValuesHelper(context, expression, node.expression); - const next = createCall(createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []); + const iterator = isIdentifier(expression) ? factory.getGeneratedNameForNode(expression) : factory.createTempVariable(/*recordTempVariable*/ undefined); + const result = isIdentifier(expression) ? factory.getGeneratedNameForNode(iterator) : factory.createTempVariable(/*recordTempVariable*/ undefined); + const errorRecord = factory.createUniqueName("e"); + const catchVariable = factory.getGeneratedNameForNode(errorRecord); + const returnMethod = factory.createTempVariable(/*recordTempVariable*/ undefined); + const values = setTextRange(emitHelpers().createValuesHelper(expression), node.expression); + const next = factory.createCallExpression(factory.createPropertyAccessExpression(iterator, "next"), /*typeArguments*/ undefined, []); hoistVariableDeclaration(errorRecord); hoistVariableDeclaration(returnMethod); // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration const initializer = ancestorFacts & HierarchyFacts.IterationContainer - ? inlineExpressions([createAssignment(errorRecord, createVoidZero()), values]) + ? factory.inlineExpressions([factory.createAssignment(errorRecord, factory.createVoidZero()), values]) : values; const forStatement = setEmitFlags( setTextRange( - createFor( + factory.createForStatement( /*initializer*/ setEmitFlags( setTextRange( - createVariableDeclarationList([ - setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression), - createVariableDeclaration(result, /*type*/ undefined, next) + factory.createVariableDeclarationList([ + setTextRange(factory.createVariableDeclaration(iterator, /*exclamationToken*/ undefined, /*type*/ undefined, initializer), node.expression), + factory.createVariableDeclaration(result, /*exclamationToken*/ undefined, /*type*/ undefined, next) ]), node.expression ), EmitFlags.NoHoisting ), - /*condition*/ createLogicalNot(createPropertyAccess(result, "done")), - /*incrementor*/ createAssignment(result, next), + /*condition*/ factory.createLogicalNot(factory.createPropertyAccessExpression(result, "done")), + /*incrementor*/ factory.createAssignment(result, next), /*statement*/ convertForOfStatementHead( node, - createPropertyAccess(result, "value"), + factory.createPropertyAccessExpression(result, "value"), convertedLoopBodyStatements ) ), @@ -2493,22 +2517,22 @@ namespace ts { EmitFlags.NoTokenTrailingSourceMaps ); - return createTry( - createBlock([ - restoreEnclosingLabel( + return factory.createTryStatement( + factory.createBlock([ + factory.restoreEnclosingLabel( forStatement, outermostLabeledStatement, convertedLoopState && resetLabel ) ]), - createCatchClause(createVariableDeclaration(catchVariable), + factory.createCatchClause(factory.createVariableDeclaration(catchVariable), setEmitFlags( - createBlock([ - createExpressionStatement( - createAssignment( + factory.createBlock([ + factory.createExpressionStatement( + factory.createAssignment( errorRecord, - createObjectLiteral([ - createPropertyAssignment("error", catchVariable) + factory.createObjectLiteralExpression([ + factory.createPropertyAssignment("error", catchVariable) ]) ) ) @@ -2516,25 +2540,25 @@ namespace ts { EmitFlags.SingleLine ) ), - createBlock([ - createTry( - /*tryBlock*/ createBlock([ + factory.createBlock([ + factory.createTryStatement( + /*tryBlock*/ factory.createBlock([ setEmitFlags( - createIf( - createLogicalAnd( - createLogicalAnd( + factory.createIfStatement( + factory.createLogicalAnd( + factory.createLogicalAnd( result, - createLogicalNot( - createPropertyAccess(result, "done") + factory.createLogicalNot( + factory.createPropertyAccessExpression(result, "done") ) ), - createAssignment( + factory.createAssignment( returnMethod, - createPropertyAccess(iterator, "return") + factory.createPropertyAccessExpression(iterator, "return") ) ), - createExpressionStatement( - createFunctionCall(returnMethod, iterator, []) + factory.createExpressionStatement( + factory.createFunctionCallCall(returnMethod, iterator, []) ) ), EmitFlags.SingleLine @@ -2542,12 +2566,12 @@ namespace ts { ]), /*catchClause*/ undefined, /*finallyBlock*/ setEmitFlags( - createBlock([ + factory.createBlock([ setEmitFlags( - createIf( + factory.createIfStatement( errorRecord, - createThrow( - createPropertyAccess(errorRecord, "error") + factory.createThrowStatement( + factory.createPropertyAccessExpression(errorRecord, "error") ) ), EmitFlags.SingleLine @@ -2587,14 +2611,14 @@ namespace ts { // For computed properties, we need to create a unique handle to the object // literal so we can modify it without risking internal assignments tainting the object. - const temp = createTempVariable(hoistVariableDeclaration); + const temp = factory.createTempVariable(hoistVariableDeclaration); // Write out the first non-computed properties, then emit the rest through indexing on the temp variable. const expressions: Expression[] = []; - const assignment = createAssignment( + const assignment = factory.createAssignment( temp, setEmitFlags( - createObjectLiteral( + factory.createObjectLiteralExpression( visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties), node.multiLine ), @@ -2612,8 +2636,8 @@ namespace ts { // We need to clone the temporary identifier so that we can write it on a // new line - expressions.push(node.multiLine ? startOnNewLine(getMutableClone(temp)) : temp); - return inlineExpressions(expressions); + expressions.push(node.multiLine ? startOnNewLine(setParent(setTextRange(factory.cloneNode(temp), temp), temp.parent)) : temp); + return factory.inlineExpressions(expressions); } interface ForStatementWithConvertibleInitializer extends ForStatement { @@ -2689,7 +2713,7 @@ namespace ts { const result = convert ? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined, ancestorFacts) - : restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel); + : factory.restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel); if (convertedLoopState) { convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps; @@ -2723,15 +2747,13 @@ namespace ts { loop = convert(node, outermostLabeledStatement, bodyFunction.part, ancestorFacts); } else { - const clone = convertIterationStatementCore(node, initializerFunction, createBlock(bodyFunction.part, /*multiLine*/ true)); - aggregateTransformFlags(clone); - loop = restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel); + const clone = convertIterationStatementCore(node, initializerFunction, factory.createBlock(bodyFunction.part, /*multiLine*/ true)); + loop = factory.restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel); } } else { - const clone = convertIterationStatementCore(node, initializerFunction, visitNode(node.statement, visitor, isStatement, liftToBlock)); - aggregateTransformFlags(clone); - loop = restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel); + const clone = convertIterationStatementCore(node, initializerFunction, visitNode(node.statement, visitor, isStatement, factory.liftToBlock)); + loop = factory.restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel); } statements.push(loop); @@ -2752,7 +2774,7 @@ namespace ts { function convertForStatement(node: ForStatement, initializerFunction: IterationStatementPartFunction | undefined, convertedLoopBody: Statement) { const shouldConvertCondition = node.condition && shouldConvertPartOfIterationStatement(node.condition); const shouldConvertIncrementor = shouldConvertCondition || node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor); - return updateFor( + return factory.updateForStatement( node, visitNode(initializerFunction ? initializerFunction.part : node.initializer, visitor, isForInitializer), visitNode(shouldConvertCondition ? undefined : node.condition, visitor, isExpression), @@ -2762,7 +2784,7 @@ namespace ts { } function convertForOfStatement(node: ForOfStatement, convertedLoopBody: Statement) { - return updateForOf( + return factory.updateForOfStatement( node, /*awaitModifier*/ undefined, visitNode(node.initializer, visitor, isForInitializer), @@ -2771,7 +2793,7 @@ namespace ts { } function convertForInStatement(node: ForInStatement, convertedLoopBody: Statement) { - return updateForIn( + return factory.updateForInStatement( node, visitNode(node.initializer, visitor, isForInitializer), visitNode(node.expression, visitor, isExpression), @@ -2779,14 +2801,14 @@ namespace ts { } function convertDoStatement(node: DoStatement, convertedLoopBody: Statement) { - return updateDo( + return factory.updateDoStatement( node, convertedLoopBody, visitNode(node.expression, visitor, isExpression)); } function convertWhileStatement(node: WhileStatement, convertedLoopBody: Statement) { - return updateWhile( + return factory.updateWhileStatement( node, visitNode(node.expression, visitor, isExpression), convertedLoopBody); @@ -2851,10 +2873,11 @@ namespace ts { else { // this is top level converted loop and we need to create an alias for 'arguments' object (extraVariableDeclarations || (extraVariableDeclarations = [])).push( - createVariableDeclaration( + factory.createVariableDeclaration( state.argumentsName, + /*exclamationToken*/ undefined, /*type*/ undefined, - createIdentifier("arguments") + factory.createIdentifier("arguments") ) ); } @@ -2872,10 +2895,11 @@ namespace ts { // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set. // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'. (extraVariableDeclarations || (extraVariableDeclarations = [])).push( - createVariableDeclaration( + factory.createVariableDeclaration( state.thisName, + /*exclamationToken*/ undefined, /*type*/ undefined, - createIdentifier("this") + factory.createIdentifier("this") ) ); } @@ -2893,7 +2917,7 @@ namespace ts { } // hoist collected variable declarations for (const identifier of state.hoistedLocalVariables) { - extraVariableDeclarations.push(createVariableDeclaration(identifier)); + extraVariableDeclarations.push(factory.createVariableDeclaration(identifier)); } } } @@ -2904,7 +2928,7 @@ namespace ts { extraVariableDeclarations = []; } for (const outParam of state.loopOutParameters) { - extraVariableDeclarations.push(createVariableDeclaration(outParam.outParamName)); + extraVariableDeclarations.push(factory.createVariableDeclaration(outParam.outParamName)); } } @@ -2912,14 +2936,14 @@ namespace ts { if (!extraVariableDeclarations) { extraVariableDeclarations = []; } - extraVariableDeclarations.push(createVariableDeclaration(state.conditionVariable, /*type*/ undefined, createFalse())); + extraVariableDeclarations.push(factory.createVariableDeclaration(state.conditionVariable, /*exclamationToken*/ undefined, /*type*/ undefined, factory.createFalse())); } // create variable statement to hold all introduced variable declarations if (extraVariableDeclarations) { - statements.push(createVariableStatement( + statements.push(factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList(extraVariableDeclarations) + factory.createVariableDeclarationList(extraVariableDeclarations) )); } } @@ -2932,7 +2956,7 @@ namespace ts { } function createOutVariable(p: LoopOutParameter) { - return createVariableDeclaration(p.originalName, /*type*/ undefined, p.outParamName); + return factory.createVariableDeclaration(p.originalName, /*exclamationToken*/ undefined, /*type*/ undefined, p.outParamName); } /** @@ -2942,7 +2966,7 @@ namespace ts { * [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation). */ function createFunctionForInitializerOfForStatement(node: ForStatementWithConvertibleInitializer, currentState: ConvertedLoopState): IterationStatementPartFunction { - const functionName = createUniqueName("_loop_init"); + const functionName = factory.createUniqueName("_loop_init"); const containsYield = (node.initializer.transformFlags & TransformFlags.ContainsYield) !== 0; let emitFlags = EmitFlags.None; @@ -2950,7 +2974,7 @@ namespace ts { if (containsYield && hierarchyFacts & HierarchyFacts.AsyncFunctionBody) emitFlags |= EmitFlags.AsyncFunctionBody; const statements: Statement[] = []; - statements.push(createVariableStatement(/*modifiers*/ undefined, node.initializer)); + statements.push(factory.createVariableStatement(/*modifiers*/ undefined, node.initializer)); copyOutParameters(currentState.loopOutParameters, LoopOutParameterFlags.Initializer, CopyDirection.ToOutParameter, statements); // This transforms the following ES2015 syntax: @@ -2974,23 +2998,24 @@ namespace ts { // Which prevents mutations to `i` in the per-iteration environment of the body // from affecting the initial value for `i` outside of the per-iteration environment. - const functionDeclaration = createVariableStatement( + const functionDeclaration = factory.createVariableStatement( /*modifiers*/ undefined, setEmitFlags( - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( functionName, + /*exclamationToken*/ undefined, /*type*/ undefined, setEmitFlags( - createFunctionExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, - containsYield ? createToken(SyntaxKind.AsteriskToken) : undefined, + containsYield ? factory.createToken(SyntaxKind.AsteriskToken) : undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, visitNode( - createBlock(statements, /*multiLine*/ true), + factory.createBlock(statements, /*multiLine*/ true), visitor, isBlock ) @@ -3003,7 +3028,7 @@ namespace ts { ) ); - const part = createVariableDeclarationList(map(currentState.loopOutParameters, createOutVariable)); + const part = factory.createVariableDeclarationList(map(currentState.loopOutParameters, createOutVariable)); return { functionName, containsYield, functionDeclaration, part }; } @@ -3014,9 +3039,9 @@ namespace ts { * [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation). */ function createFunctionForBodyOfIterationStatement(node: IterationStatement, currentState: ConvertedLoopState, outerState: ConvertedLoopState | undefined): IterationStatementPartFunction { - const functionName = createUniqueName("_loop"); + const functionName = factory.createUniqueName("_loop"); startLexicalEnvironment(); - const statement = visitNode(node.statement, visitor, isStatement, liftToBlock); + const statement = visitNode(node.statement, visitor, isStatement, factory.liftToBlock); const lexicalEnvironment = endLexicalEnvironment(); const statements: Statement[] = []; @@ -3059,17 +3084,25 @@ namespace ts { // we must indicate whether this is the first evaluation of the loop body so that // we only evaluate the incrementor on subsequent evaluations. - currentState.conditionVariable = createUniqueName("inc"); - statements.push(createIf( - currentState.conditionVariable, - createStatement(visitNode(node.incrementor, visitor, isExpression)), - createStatement(createAssignment(currentState.conditionVariable, createTrue())) - )); + currentState.conditionVariable = factory.createUniqueName("inc"); + if (node.incrementor) { + statements.push(factory.createIfStatement( + currentState.conditionVariable, + factory.createExpressionStatement(visitNode(node.incrementor, visitor, isExpression)), + factory.createExpressionStatement(factory.createAssignment(currentState.conditionVariable, factory.createTrue())) + )); + } + else { + statements.push(factory.createIfStatement( + factory.createLogicalNot(currentState.conditionVariable), + factory.createExpressionStatement(factory.createAssignment(currentState.conditionVariable, factory.createTrue())) + )); + } if (shouldConvertConditionOfForStatement(node)) { - statements.push(createIf( - createPrefix(SyntaxKind.ExclamationToken, visitNode(node.condition, visitor, isExpression)), - visitNode(createBreak(), visitor, isStatement) + statements.push(factory.createIfStatement( + factory.createPrefixUnaryExpression(SyntaxKind.ExclamationToken, visitNode(node.condition, visitor, isExpression)), + visitNode(factory.createBreakStatement(), visitor, isStatement) )); } } @@ -3084,7 +3117,7 @@ namespace ts { copyOutParameters(currentState.loopOutParameters, LoopOutParameterFlags.Body, CopyDirection.ToOutParameter, statements); insertStatementsAfterStandardPrologue(statements, lexicalEnvironment); - const loopBody = createBlock(statements, /*multiLine*/ true); + const loopBody = factory.createBlock(statements, /*multiLine*/ true); if (isBlock(statement)) setOriginalNode(loopBody, statement); const containsYield = (node.statement.transformFlags & TransformFlags.ContainsYield) !== 0; @@ -3109,18 +3142,19 @@ namespace ts { // } const functionDeclaration = - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, setEmitFlags( - createVariableDeclarationList( + factory.createVariableDeclarationList( [ - createVariableDeclaration( + factory.createVariableDeclaration( functionName, + /*exclamationToken*/ undefined, /*type*/ undefined, setEmitFlags( - createFunctionExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, - containsYield ? createToken(SyntaxKind.AsteriskToken) : undefined, + containsYield ? factory.createToken(SyntaxKind.AsteriskToken) : undefined, /*name*/ undefined, /*typeParameters*/ undefined, currentState.loopParameters, @@ -3143,26 +3177,26 @@ namespace ts { function copyOutParameter(outParam: LoopOutParameter, copyDirection: CopyDirection): BinaryExpression { const source = copyDirection === CopyDirection.ToOriginal ? outParam.outParamName : outParam.originalName; const target = copyDirection === CopyDirection.ToOriginal ? outParam.originalName : outParam.outParamName; - return createBinary(target, SyntaxKind.EqualsToken, source); + return factory.createBinaryExpression(target, SyntaxKind.EqualsToken, source); } function copyOutParameters(outParams: LoopOutParameter[], partFlags: LoopOutParameterFlags, copyDirection: CopyDirection, statements: Statement[]): void { for (const outParam of outParams) { if (outParam.flags & partFlags) { - statements.push(createExpressionStatement(copyOutParameter(outParam, copyDirection))); + statements.push(factory.createExpressionStatement(copyOutParameter(outParam, copyDirection))); } } } function generateCallToConvertedLoopInitializer(initFunctionExpressionName: Identifier, containsYield: boolean): Statement { - const call = createCall(initFunctionExpressionName, /*typeArguments*/ undefined, []); + const call = factory.createCallExpression(initFunctionExpressionName, /*typeArguments*/ undefined, []); const callResult = containsYield - ? createYield( - createToken(SyntaxKind.AsteriskToken), + ? factory.createYieldExpression( + factory.createToken(SyntaxKind.AsteriskToken), setEmitFlags(call, EmitFlags.Iterator) ) : call; - return createStatement(callResult); + return factory.createExpressionStatement(callResult); } function generateCallToConvertedLoop(loopFunctionExpressionName: Identifier, state: ConvertedLoopState, outerState: ConvertedLoopState | undefined, containsYield: boolean): Statement[] { @@ -3176,23 +3210,23 @@ namespace ts { !state.labeledNonLocalBreaks && !state.labeledNonLocalContinues; - const call = createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(state.loopParameters, p => p.name)); + const call = factory.createCallExpression(loopFunctionExpressionName, /*typeArguments*/ undefined, map(state.loopParameters, p => p.name)); const callResult = containsYield - ? createYield( - createToken(SyntaxKind.AsteriskToken), + ? factory.createYieldExpression( + factory.createToken(SyntaxKind.AsteriskToken), setEmitFlags(call, EmitFlags.Iterator) ) : call; if (isSimpleLoop) { - statements.push(createExpressionStatement(callResult)); + statements.push(factory.createExpressionStatement(callResult)); copyOutParameters(state.loopOutParameters, LoopOutParameterFlags.Body, CopyDirection.ToOriginal, statements); } else { - const loopResultName = createUniqueName("state"); - const stateVariable = createVariableStatement( + const loopResultName = factory.createUniqueName("state"); + const stateVariable = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( - [createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)] + factory.createVariableDeclarationList( + [factory.createVariableDeclaration(loopResultName, /*exclamationToken*/ undefined, /*type*/ undefined, callResult)] ) ); statements.push(stateVariable); @@ -3202,18 +3236,14 @@ namespace ts { let returnStatement: ReturnStatement; if (outerState) { outerState.nonLocalJumps! |= Jump.Return; - returnStatement = createReturn(loopResultName); + returnStatement = factory.createReturnStatement(loopResultName); } else { - returnStatement = createReturn(createPropertyAccess(loopResultName, "value")); + returnStatement = factory.createReturnStatement(factory.createPropertyAccessExpression(loopResultName, "value")); } statements.push( - createIf( - createBinary( - createTypeOf(loopResultName), - SyntaxKind.EqualsEqualsEqualsToken, - createLiteral("object") - ), + factory.createIfStatement( + factory.createTypeCheck(loopResultName, "object"), returnStatement ) ); @@ -3221,13 +3251,12 @@ namespace ts { if (state.nonLocalJumps! & Jump.Break) { statements.push( - createIf( - createBinary( + factory.createIfStatement( + factory.createStrictEquality( loopResultName, - SyntaxKind.EqualsEqualsEqualsToken, - createLiteral("break") + factory.createStringLiteral("break") ), - createBreak() + factory.createBreakStatement() ) ); } @@ -3237,9 +3266,9 @@ namespace ts { processLabeledJumps(state.labeledNonLocalBreaks!, /*isBreak*/ true, loopResultName, outerState, caseClauses); processLabeledJumps(state.labeledNonLocalContinues!, /*isBreak*/ false, loopResultName, outerState, caseClauses); statements.push( - createSwitch( + factory.createSwitchStatement( loopResultName, - createCaseBlock(caseClauses) + factory.createCaseBlock(caseClauses) ) ); } @@ -3272,14 +3301,14 @@ namespace ts { // then emit labeled break\continue // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) { - const label = createIdentifier(labelText); - statements.push(isBreak ? createBreak(label) : createContinue(label)); + const label = factory.createIdentifier(labelText); + statements.push(isBreak ? factory.createBreakStatement(label) : factory.createContinueStatement(label)); } else { setLabeledJump(outerLoop, isBreak, labelText, labelMarker); - statements.push(createReturn(loopResultName)); + statements.push(factory.createReturnStatement(loopResultName)); } - caseClauses.push(createCaseClause(createLiteral(labelMarker), statements)); + caseClauses.push(factory.createCaseClause(factory.createStringLiteral(labelMarker), statements)); }); } @@ -3293,10 +3322,10 @@ namespace ts { } } else { - loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name)); + loopParameters.push(factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name)); const checkFlags = resolver.getNodeCheckFlags(decl); if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter || hasCapturedBindingsInForInitializer) { - const outParamName = createUniqueName("out_" + idText(name)); + const outParamName = factory.createUniqueName("out_" + idText(name)); let flags: LoopOutParameterFlags = 0; if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter) { flags |= LoopOutParameterFlags.Body; @@ -3360,8 +3389,9 @@ namespace ts { * @param receiver The receiver for the assignment. */ function transformPropertyAssignmentToExpression(property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) { - const expression = createAssignment( + const expression = factory.createAssignment( createMemberAccessForPropertyName( + factory, receiver, visitNode(property.name, visitor, isPropertyName) ), @@ -3382,12 +3412,13 @@ namespace ts { * @param receiver The receiver for the assignment. */ function transformShorthandPropertyAssignmentToExpression(property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) { - const expression = createAssignment( + const expression = factory.createAssignment( createMemberAccessForPropertyName( + factory, receiver, visitNode(property.name, visitor, isPropertyName) ), - getSynthesizedClone(property.name) + factory.cloneNode(property.name) ); setTextRange(expression, property); if (startsOnNewLine) { @@ -3404,8 +3435,9 @@ namespace ts { * @param receiver The receiver for the assignment. */ function transformObjectLiteralMethodDeclarationToExpression(method: MethodDeclaration, receiver: Expression, container: Node, startsOnNewLine: boolean) { - const expression = createAssignment( + const expression = factory.createAssignment( createMemberAccessForPropertyName( + factory, receiver, visitNode(method.name, visitor, isPropertyName) ), @@ -3423,8 +3455,8 @@ namespace ts { let updated: CatchClause; Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015."); if (isBindingPattern(node.variableDeclaration.name)) { - const temp = createTempVariable(/*recordTempVariable*/ undefined); - const newVariableDeclaration = createVariableDeclaration(temp); + const temp = factory.createTempVariable(/*recordTempVariable*/ undefined); + const newVariableDeclaration = factory.createVariableDeclaration(temp); setTextRange(newVariableDeclaration, node.variableDeclaration); const vars = flattenDestructuringBinding( node.variableDeclaration, @@ -3433,10 +3465,10 @@ namespace ts { FlattenLevel.All, temp ); - const list = createVariableDeclarationList(vars); + const list = factory.createVariableDeclarationList(vars); setTextRange(list, node.variableDeclaration); - const destructure = createVariableStatement(/*modifiers*/ undefined, list); - updated = updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure)); + const destructure = factory.createVariableStatement(/*modifiers*/ undefined, list); + updated = factory.updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure)); } else { updated = visitEachChild(node, visitor, context); @@ -3448,7 +3480,7 @@ namespace ts { function addStatementToStartOfBlock(block: Block, statement: Statement): Block { const transformedStatements = visitNodes(block.statements, visitor, isStatement); - return updateBlock(block, [statement, ...transformedStatements]); + return factory.updateBlock(block, [statement, ...transformedStatements]); } /** @@ -3465,7 +3497,7 @@ namespace ts { const functionExpression = transformFunctionLikeToExpression(node, /*location*/ moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined); setEmitFlags(functionExpression, EmitFlags.NoLeadingComments | getEmitFlags(functionExpression)); return setTextRange( - createPropertyAssignment( + factory.createPropertyAssignment( node.name, functionExpression ), @@ -3487,10 +3519,10 @@ namespace ts { const parameters = visitParameterList(node.parameters, visitor, context); const body = transformFunctionBody(node); if (node.kind === SyntaxKind.GetAccessor) { - updated = updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body); + updated = factory.updateGetAccessorDeclaration(node, node.decorators, node.modifiers, node.name, parameters, node.type, body); } else { - updated = updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body); + updated = factory.updateSetAccessorDeclaration(node, node.decorators, node.modifiers, node.name, parameters, body); } exitSubtree(ancestorFacts, HierarchyFacts.FunctionSubtreeExcludes, HierarchyFacts.None); convertedLoopState = savedConvertedLoopState; @@ -3504,9 +3536,9 @@ namespace ts { */ function visitShorthandPropertyAssignment(node: ShorthandPropertyAssignment): ObjectLiteralElementLike { return setTextRange( - createPropertyAssignment( + factory.createPropertyAssignment( node.name, - visitIdentifier(getSynthesizedClone(node.name)) + visitIdentifier(factory.cloneNode(node.name)) ), /*location*/ node ); @@ -3556,7 +3588,7 @@ namespace ts { return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true); } - return updateCall( + return factory.updateCallExpression( node, visitNode(node.expression, callExpressionVisitor, isExpression), /*typeArguments*/ undefined, @@ -3660,8 +3692,8 @@ namespace ts { // Add the class alias following the declaration. statements.push( - createExpressionStatement( - createAssignment( + factory.createExpressionStatement( + factory.createAssignment( aliasAssignment.left, cast(variable.name, isIdentifier) ) @@ -3693,12 +3725,12 @@ namespace ts { // Recreate any outer parentheses or partially-emitted expressions to preserve source map // and comment locations. - return recreateOuterExpressions(node.expression, - recreateOuterExpressions(variable.initializer, - recreateOuterExpressions(aliasAssignment && aliasAssignment.right, - updateCall(call, - recreateOuterExpressions(call.expression, - updateFunctionExpression( + return factory.restoreOuterExpressions(node.expression, + factory.restoreOuterExpressions(variable.initializer, + factory.restoreOuterExpressions(aliasAssignment && aliasAssignment.right, + factory.updateCallExpression(call, + factory.restoreOuterExpressions(call.expression, + factory.updateFunctionExpression( func, /*modifiers*/ undefined, /*asteriskToken*/ undefined, @@ -3706,7 +3738,7 @@ namespace ts { /*typeParameters*/ undefined, func.parameters, /*type*/ undefined, - updateBlock( + factory.updateBlock( func.body, statements ) @@ -3731,7 +3763,7 @@ namespace ts { node.expression.kind === SyntaxKind.SuperKeyword || isSuperProperty(skipOuterExpressions(node.expression))) { - const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration); + const { target, thisArg } = factory.createCallBinding(node.expression, hoistVariableDeclaration); if (node.expression.kind === SyntaxKind.SuperKeyword) { setEmitFlags(thisArg, EmitFlags.NoSubstitution); } @@ -3752,7 +3784,7 @@ namespace ts { // _super.m.apply(this, a.concat([b])) // _super.prototype.m.apply(this, a.concat([b])) - resultingCall = createFunctionApply( + resultingCall = factory.createFunctionApplyCall( visitNode(target, callExpressionVisitor, isExpression), node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : visitNode(thisArg, visitor, isExpression), transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false) @@ -3768,22 +3800,24 @@ namespace ts { // _super.call(this, a) // _super.m.call(this, a) // _super.prototype.m.call(this, a) - resultingCall = createFunctionCall( - visitNode(target, callExpressionVisitor, isExpression), - node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : visitNode(thisArg, visitor, isExpression), - visitNodes(node.arguments, visitor, isExpression), - /*location*/ node + resultingCall = setTextRange( + factory.createFunctionCallCall( + visitNode(target, callExpressionVisitor, isExpression), + node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : visitNode(thisArg, visitor, isExpression), + visitNodes(node.arguments, visitor, isExpression) + ), + node ); } if (node.expression.kind === SyntaxKind.SuperKeyword) { const initializer = - createLogicalOr( + factory.createLogicalOr( resultingCall, createActualThis() ); resultingCall = assignToCapturedThis - ? createAssignment(createFileLevelUniqueName("_this"), initializer) + ? factory.createAssignment(factory.createUniqueName("_this", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), initializer) : initializer; } return setOriginalNode(resultingCall, node); @@ -3806,12 +3840,12 @@ namespace ts { // [output] // new ((_a = C).bind.apply(_a, [void 0].concat(a)))() - const { target, thisArg } = createCallBinding(createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration); - return createNew( - createFunctionApply( + const { target, thisArg } = factory.createCallBinding(factory.createPropertyAccessExpression(node.expression, "bind"), hoistVariableDeclaration); + return factory.createNewExpression( + factory.createFunctionApplyCall( visitNode(target, visitor, isExpression), thisArg, - transformAndSpreadElements(createNodeArray([createVoidZero(), ...node.arguments!]), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false) + transformAndSpreadElements(factory.createNodeArray([factory.createVoidZero(), ...node.arguments!]), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false) ), /*typeArguments*/ undefined, [] @@ -3854,7 +3888,7 @@ namespace ts { } } - return createSpreadHelper(context, segments); + return emitHelpers().createSpreadHelper(segments); } else { if (segments.length === 1) { @@ -3866,7 +3900,7 @@ namespace ts { } } - return createSpreadArraysHelper(context, segments); + return emitHelpers().createSpreadArraysHelper(segments); } } @@ -3896,8 +3930,8 @@ namespace ts { } function visitSpanOfNonSpreads(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult { - return createArrayLiteral( - visitNodes(createNodeArray(chunk, hasTrailingComma), visitor, isExpression), + return factory.createArrayLiteralExpression( + visitNodes(factory.createNodeArray(chunk, hasTrailingComma), visitor, isExpression), multiLine ); } @@ -3921,7 +3955,7 @@ namespace ts { * @param node A template literal. */ function visitTemplateLiteral(node: LiteralExpression): LeftHandSideExpression { - return setTextRange(createLiteral(node.text), node); + return setTextRange(factory.createStringLiteral(node.text), node); } /** @@ -3931,7 +3965,7 @@ namespace ts { */ function visitStringLiteral(node: StringLiteral) { if (node.hasExtendedUnicodeEscape) { - return setTextRange(createLiteral(node.text), node); + return setTextRange(factory.createStringLiteral(node.text), node); } return node; } @@ -3943,7 +3977,7 @@ namespace ts { */ function visitNumericLiteral(node: NumericLiteral) { if (node.numericLiteralFlags & TokenFlags.BinaryOrOctalSpecifier) { - return setTextRange(createNumericLiteral(node.text), node); + return setTextRange(factory.createNumericLiteral(node.text), node); } return node; } @@ -3983,10 +4017,9 @@ namespace ts { // ("abc" + 1) << (2 + "") // rather than // "abc" + (1 << 2) + "" - const expression = reduceLeft(expressions, createAdd)!; + const expression = reduceLeft(expressions, factory.createAdd)!; if (nodeIsSynthesized(expression)) { - expression.pos = node.pos; - expression.end = node.end; + setTextRange(expression, node); } return expression; @@ -4030,7 +4063,7 @@ namespace ts { return; } - expressions.push(createLiteral(node.head.text)); + expressions.push(factory.createStringLiteral(node.head.text)); } /** @@ -4048,7 +4081,7 @@ namespace ts { // with the head will force the result up to this point to be a string. // Emitting a '+ ""' has no semantic effect for middles and tails. if (span.literal.text.length !== 0) { - expressions.push(createLiteral(span.literal.text)); + expressions.push(factory.createStringLiteral(span.literal.text)); } } } @@ -4057,14 +4090,16 @@ namespace ts { * Visits the `super` keyword */ function visitSuperKeyword(isExpressionOfCall: boolean): LeftHandSideExpression { - return hierarchyFacts & HierarchyFacts.NonStaticClassElement && !isExpressionOfCall ? createPropertyAccess(createFileLevelUniqueName("_super"), "prototype") : - createFileLevelUniqueName("_super"); + return hierarchyFacts & HierarchyFacts.NonStaticClassElement + && !isExpressionOfCall + ? factory.createPropertyAccessExpression(factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), "prototype") + : factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel); } function visitMetaProperty(node: MetaProperty) { if (node.keywordToken === SyntaxKind.NewKeyword && node.name.escapedText === "target") { hierarchyFacts |= HierarchyFacts.NewTarget; - return createFileLevelUniqueName("_newTarget"); + return factory.createUniqueName("_newTarget", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel); } return node; } @@ -4149,7 +4184,7 @@ namespace ts { if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings && !isInternalName(node)) { const original = getParseTreeNode(node, isIdentifier); if (original && isNameOfDeclarationWithCollidingName(original)) { - return setTextRange(getGeneratedNameForNode(original), node); + return setTextRange(factory.getGeneratedNameForNode(original), node); } } @@ -4201,7 +4236,7 @@ namespace ts { if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings && !isInternalName(node)) { const declaration = resolver.getReferencedDeclarationWithCollidingName(node); if (declaration && !(isClassLike(declaration) && isPartOfClassBody(declaration, node))) { - return setTextRange(getGeneratedNameForNode(getNameOfDeclaration(declaration)), node); + return setTextRange(factory.getGeneratedNameForNode(getNameOfDeclaration(declaration)), node); } } @@ -4240,15 +4275,15 @@ namespace ts { function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression { if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && hierarchyFacts & HierarchyFacts.CapturesThis) { - return setTextRange(createFileLevelUniqueName("_this"), node); + return setTextRange(factory.createUniqueName("_this", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), node); } return node; } function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) { return hasSyntacticModifier(member, ModifierFlags.Static) - ? getInternalName(node) - : createPropertyAccess(getInternalName(node), "prototype"); + ? factory.getInternalName(node) + : factory.createPropertyAccessExpression(factory.getInternalName(node), "prototype"); } function hasSynthesizedDefaultSuperCall(constructor: ConstructorDeclaration | undefined, hasExtendsClause: boolean) { @@ -4284,38 +4319,4 @@ namespace ts { return isIdentifier(expression) && expression.escapedText === "arguments"; } } - - function createExtendsHelper(context: TransformationContext, name: Identifier) { - context.requestEmitHelper(extendsHelper); - return createCall( - getUnscopedHelperName("__extends"), - /*typeArguments*/ undefined, - [ - name, - createFileLevelUniqueName("_super") - ] - ); - } - - export const extendsHelper: UnscopedEmitHelper = { - name: "typescript:extends", - importName: "__extends", - scoped: false, - priority: 0, - text: ` - var __extends = (this && this.__extends) || (function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })();` - }; } diff --git a/src/compiler/transformers/es2016.ts b/src/compiler/transformers/es2016.ts index 93b5d45714ff2..653c66174d4ff 100644 --- a/src/compiler/transformers/es2016.ts +++ b/src/compiler/transformers/es2016.ts @@ -1,9 +1,12 @@ /*@internal*/ namespace ts { export function transformES2016(context: TransformationContext) { - const { hoistVariableDeclaration } = context; + const { + factory, + hoistVariableDeclaration + } = context; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { if (node.isDeclarationFile) { @@ -43,17 +46,17 @@ namespace ts { const right = visitNode(node.right, visitor, isExpression); if (isElementAccessExpression(left)) { // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)` - const expressionTemp = createTempVariable(hoistVariableDeclaration); - const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration); + const expressionTemp = factory.createTempVariable(hoistVariableDeclaration); + const argumentExpressionTemp = factory.createTempVariable(hoistVariableDeclaration); target = setTextRange( - createElementAccess( - setTextRange(createAssignment(expressionTemp, left.expression), left.expression), - setTextRange(createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression) + factory.createElementAccessExpression( + setTextRange(factory.createAssignment(expressionTemp, left.expression), left.expression), + setTextRange(factory.createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression) ), left ); value = setTextRange( - createElementAccess( + factory.createElementAccessExpression( expressionTemp, argumentExpressionTemp ), @@ -62,16 +65,16 @@ namespace ts { } else if (isPropertyAccessExpression(left)) { // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)` - const expressionTemp = createTempVariable(hoistVariableDeclaration); + const expressionTemp = factory.createTempVariable(hoistVariableDeclaration); target = setTextRange( - createPropertyAccess( - setTextRange(createAssignment(expressionTemp, left.expression), left.expression), + factory.createPropertyAccessExpression( + setTextRange(factory.createAssignment(expressionTemp, left.expression), left.expression), left.name ), left ); value = setTextRange( - createPropertyAccess( + factory.createPropertyAccessExpression( expressionTemp, left.name ), @@ -84,9 +87,9 @@ namespace ts { value = left; } return setTextRange( - createAssignment( + factory.createAssignment( target, - createMathPow(value, right, /*location*/ node) + setTextRange(factory.createGlobalMethodCall("Math", "pow", [value, right]), node) ), node ); @@ -96,7 +99,7 @@ namespace ts { // Transforms `a ** b` into `Math.pow(a, b)` const left = visitNode(node.left, visitor, isExpression); const right = visitNode(node.right, visitor, isExpression); - return createMathPow(left, right, /*location*/ node); + return setTextRange(factory.createGlobalMethodCall("Math", "pow", [left, right]), node); } } } diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 594dc0d3e5b6d..64971fffe6369 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -14,6 +14,8 @@ namespace ts { export function transformES2017(context: TransformationContext) { const { + factory, + getEmitHelperFactory: emitHelpers, resumeLexicalEnvironment, endLexicalEnvironment, hoistVariableDeclaration @@ -56,7 +58,7 @@ namespace ts { context.onEmitNode = onEmitNode; context.onSubstituteNode = onSubstituteNode; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { if (node.isDeclarationFile) { @@ -211,44 +213,44 @@ namespace ts { function visitVariableStatementInAsyncBody(node: VariableStatement) { if (isVariableDeclarationListWithCollidingName(node.declarationList)) { const expression = visitVariableDeclarationListWithCollidingNames(node.declarationList, /*hasReceiver*/ false); - return expression ? createExpressionStatement(expression) : undefined; + return expression ? factory.createExpressionStatement(expression) : undefined; } return visitEachChild(node, visitor, context); } function visitForInStatementInAsyncBody(node: ForInStatement) { - return updateForIn( + return factory.updateForInStatement( node, isVariableDeclarationListWithCollidingName(node.initializer) ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)! : visitNode(node.initializer, visitor, isForInitializer), visitNode(node.expression, visitor, isExpression), - visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock) + visitNode(node.statement, asyncBodyVisitor, isStatement, factory.liftToBlock) ); } function visitForOfStatementInAsyncBody(node: ForOfStatement) { - return updateForOf( + return factory.updateForOfStatement( node, visitNode(node.awaitModifier, visitor, isToken), isVariableDeclarationListWithCollidingName(node.initializer) ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)! : visitNode(node.initializer, visitor, isForInitializer), visitNode(node.expression, visitor, isExpression), - visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock) + visitNode(node.statement, asyncBodyVisitor, isStatement, factory.liftToBlock) ); } function visitForStatementInAsyncBody(node: ForStatement) { const initializer = node.initializer!; // TODO: GH#18217 - return updateFor( + return factory.updateForStatement( node, isVariableDeclarationListWithCollidingName(initializer) ? visitVariableDeclarationListWithCollidingNames(initializer, /*hasReceiver*/ false) : visitNode(node.initializer, visitor, isForInitializer), visitNode(node.condition, visitor, isExpression), visitNode(node.incrementor, visitor, isExpression), - visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock) + visitNode(node.statement, asyncBodyVisitor, isStatement, factory.liftToBlock) ); } @@ -266,7 +268,7 @@ namespace ts { } return setOriginalNode( setTextRange( - createYield( + factory.createYieldExpression( /*asteriskToken*/ undefined, visitNode(node.expression, visitor, isExpression) ), @@ -285,7 +287,7 @@ namespace ts { * @param node The node to visit. */ function visitMethodDeclaration(node: MethodDeclaration) { - return updateMethod( + return factory.updateMethodDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), @@ -310,7 +312,7 @@ namespace ts { * @param node The node to visit. */ function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { - return updateFunctionDeclaration( + return factory.updateFunctionDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), @@ -334,7 +336,7 @@ namespace ts { * @param node The node to visit. */ function visitFunctionExpression(node: FunctionExpression): Expression { - return updateFunctionExpression( + return factory.updateFunctionExpression( node, visitNodes(node.modifiers, visitor, isModifier), node.asteriskToken, @@ -357,7 +359,7 @@ namespace ts { * @param node The node to visit. */ function visitArrowFunction(node: ArrowFunction) { - return updateArrowFunction( + return factory.updateArrowFunction( node, visitNodes(node.modifiers, visitor, isModifier), /*typeParameters*/ undefined, @@ -396,12 +398,12 @@ namespace ts { const variables = getInitializedVariables(node); if (variables.length === 0) { if (hasReceiver) { - return visitNode(convertToAssignmentElementTarget(node.declarations[0].name), visitor, isExpression); + return visitNode(factory.converters.convertToAssignmentElementTarget(node.declarations[0].name), visitor, isExpression); } return undefined; } - return inlineExpressions(map(variables, transformInitializedVariable)); + return factory.inlineExpressions(map(variables, transformInitializedVariable)); } function hoistVariableDeclarationList(node: VariableDeclarationList) { @@ -423,8 +425,8 @@ namespace ts { function transformInitializedVariable(node: VariableDeclaration) { const converted = setSourceMapRange( - createAssignment( - convertToAssignmentElementTarget(node.name), + factory.createAssignment( + factory.converters.convertToAssignmentElementTarget(node.name), node.initializer! ), node @@ -479,11 +481,10 @@ namespace ts { let result: ConciseBody; if (!isArrowFunction) { const statements: Statement[] = []; - const statementOffset = addPrologue(statements, (node.body).statements, /*ensureUseStrict*/ false, visitor); + const statementOffset = factory.copyPrologue((node.body).statements, statements, /*ensureUseStrict*/ false, visitor); statements.push( - createReturn( - createAwaiterHelper( - context, + factory.createReturnStatement( + emitHelpers().createAwaiterHelper( inHasLexicalThisContext(), hasLexicalArguments, promiseConstructor, @@ -501,13 +502,13 @@ namespace ts { if (emitSuperHelpers) { enableSubstitutionForAsyncMethodsWithSuper(); if (hasEntries(capturedSuperProperties)) { - const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties); + const variableStatement = createSuperAccessVariableStatement(factory, resolver, node, capturedSuperProperties); substitutedSuperAccessors[getNodeId(variableStatement)] = true; insertStatementsAfterStandardPrologue(statements, [variableStatement]); } } - const block = createBlock(statements, /*multiLine*/ true); + const block = factory.createBlock(statements, /*multiLine*/ true); setTextRange(block, node.body); if (emitSuperHelpers && hasSuperElementAccess) { @@ -523,8 +524,7 @@ namespace ts { result = block; } else { - const expression = createAwaiterHelper( - context, + const expression = emitHelpers().createAwaiterHelper( inHasLexicalThisContext(), hasLexicalArguments, promiseConstructor, @@ -533,8 +533,8 @@ namespace ts { const declarations = endLexicalEnvironment(); if (some(declarations)) { - const block = convertToFunctionBody(expression); - result = updateBlock(block, setTextRange(createNodeArray(concatenate(declarations, block.statements)), block.statements)); + const block = factory.converters.convertToFunctionBlock(expression); + result = factory.updateBlock(block, setTextRange(factory.createNodeArray(concatenate(declarations, block.statements)), block.statements)); } else { result = expression; @@ -551,10 +551,10 @@ namespace ts { function transformAsyncFunctionBodyWorker(body: ConciseBody, start?: number) { if (isBlock(body)) { - return updateBlock(body, visitNodes(body.statements, asyncBodyVisitor, isStatement, start)); + return factory.updateBlock(body, visitNodes(body.statements, asyncBodyVisitor, isStatement, start)); } else { - return convertToFunctionBody(visitNode(body, asyncBodyVisitor, isConciseBody)); + return factory.converters.convertToFunctionBlock(visitNode(body, asyncBodyVisitor, isConciseBody)); } } @@ -653,8 +653,8 @@ namespace ts { function substitutePropertyAccessExpression(node: PropertyAccessExpression) { if (node.expression.kind === SyntaxKind.SuperKeyword) { return setTextRange( - createPropertyAccess( - createFileLevelUniqueName("_super"), + factory.createPropertyAccessExpression( + factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), node.name), node ); @@ -678,11 +678,11 @@ namespace ts { const argumentExpression = isPropertyAccessExpression(expression) ? substitutePropertyAccessExpression(expression) : substituteElementAccessExpression(expression); - return createCall( - createPropertyAccess(argumentExpression, "call"), + return factory.createCallExpression( + factory.createPropertyAccessExpression(argumentExpression, "call"), /*typeArguments*/ undefined, [ - createThis(), + factory.createThis(), ...node.arguments ] ); @@ -702,9 +702,9 @@ namespace ts { function createSuperElementAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression { if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) { return setTextRange( - createPropertyAccess( - createCall( - createFileLevelUniqueName("_superIndex"), + factory.createPropertyAccessExpression( + factory.createCallExpression( + factory.createUniqueName("_superIndex", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), /*typeArguments*/ undefined, [argumentExpression] ), @@ -715,8 +715,8 @@ namespace ts { } else { return setTextRange( - createCall( - createFileLevelUniqueName("_superIndex"), + factory.createCallExpression( + factory.createUniqueName("_superIndex", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), /*typeArguments*/ undefined, [argumentExpression] ), @@ -727,7 +727,7 @@ namespace ts { } /** Creates a variable named `_super` with accessor properties for the given property names. */ - export function createSuperAccessVariableStatement(resolver: EmitResolver, node: FunctionLikeDeclaration, names: UnderscoreEscapedMap) { + export function createSuperAccessVariableStatement(factory: NodeFactory, resolver: EmitResolver, node: FunctionLikeDeclaration, names: UnderscoreEscapedMap) { // Create a variable declaration with a getter/setter (if binding) definition for each name: // const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... }); const hasBinding = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) !== 0; @@ -735,18 +735,18 @@ namespace ts { names.forEach((_, key) => { const name = unescapeLeadingUnderscores(key); const getterAndSetter: PropertyAssignment[] = []; - getterAndSetter.push(createPropertyAssignment( + getterAndSetter.push(factory.createPropertyAssignment( "get", - createArrowFunction( + factory.createArrowFunction( /* modifiers */ undefined, /* typeParameters */ undefined, /* parameters */ [], /* type */ undefined, /* equalsGreaterThanToken */ undefined, setEmitFlags( - createPropertyAccess( + factory.createPropertyAccessExpression( setEmitFlags( - createSuper(), + factory.createSuper(), EmitFlags.NoSubstitution ), name @@ -757,13 +757,13 @@ namespace ts { )); if (hasBinding) { getterAndSetter.push( - createPropertyAssignment( + factory.createPropertyAssignment( "set", - createArrowFunction( + factory.createArrowFunction( /* modifiers */ undefined, /* typeParameters */ undefined, /* parameters */ [ - createParameter( + factory.createParameterDeclaration( /* decorators */ undefined, /* modifiers */ undefined, /* dotDotDotToken */ undefined, @@ -775,112 +775,51 @@ namespace ts { ], /* type */ undefined, /* equalsGreaterThanToken */ undefined, - createAssignment( + factory.createAssignment( setEmitFlags( - createPropertyAccess( + factory.createPropertyAccessExpression( setEmitFlags( - createSuper(), + factory.createSuper(), EmitFlags.NoSubstitution ), name ), EmitFlags.NoSubstitution ), - createIdentifier("v") + factory.createIdentifier("v") ) ) ) ); } accessors.push( - createPropertyAssignment( + factory.createPropertyAssignment( name, - createObjectLiteral(getterAndSetter), + factory.createObjectLiteralExpression(getterAndSetter), ) ); }); - return createVariableStatement( + return factory.createVariableStatement( /* modifiers */ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( [ - createVariableDeclaration( - createFileLevelUniqueName("_super"), + factory.createVariableDeclaration( + factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), + /*exclamationToken*/ undefined, /* type */ undefined, - createCall( - createPropertyAccess( - createIdentifier("Object"), + factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("Object"), "create" ), /* typeArguments */ undefined, [ - createNull(), - createObjectLiteral(accessors, /* multiline */ true) + factory.createNull(), + factory.createObjectLiteralExpression(accessors, /* multiline */ true) ] ) ) ], NodeFlags.Const)); } - - export const awaiterHelper: UnscopedEmitHelper = { - name: "typescript:awaiter", - importName: "__awaiter", - scoped: false, - priority: 5, - text: ` - var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); - };` - }; - - function createAwaiterHelper(context: TransformationContext, hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block) { - context.requestEmitHelper(awaiterHelper); - - const generatorFunc = createFunctionExpression( - /*modifiers*/ undefined, - createToken(SyntaxKind.AsteriskToken), - /*name*/ undefined, - /*typeParameters*/ undefined, - /*parameters*/ [], - /*type*/ undefined, - body - ); - - // Mark this node as originally an async function - (generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; - - return createCall( - getUnscopedHelperName("__awaiter"), - /*typeArguments*/ undefined, - [ - hasLexicalThis ? createThis() : createVoidZero(), - hasLexicalArguments ? createIdentifier("arguments") : createVoidZero(), - promiseConstructor ? createExpressionFromEntityName(promiseConstructor) : createVoidZero(), - generatorFunc - ] - ); - } - - export const asyncSuperHelper: EmitHelper = { - name: "typescript:async-super", - scoped: true, - text: helperString` - const ${"_superIndex"} = name => super[name];` - }; - - export const advancedAsyncSuperHelper: EmitHelper = { - name: "typescript:advanced-async-super", - scoped: true, - text: helperString` - const ${"_superIndex"} = (function (geti, seti) { - const cache = Object.create(null); - return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); - })(name => super[name], (name, value) => super[name] = value);` - }; } diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 585ec59241e7d..143a864edb40b 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -39,6 +39,8 @@ namespace ts { export function transformES2018(context: TransformationContext) { const { + factory, + getEmitHelperFactory: emitHelpers, resumeLexicalEnvironment, endLexicalEnvironment, hoistVariableDeclaration @@ -70,7 +72,7 @@ namespace ts { /** A set of node IDs for generated super accessors. */ const substitutedSuperAccessors: boolean[] = []; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function affectsSubtree(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) { return hierarchyFacts !== (hierarchyFacts & ~excludeFacts | includeFacts); @@ -99,7 +101,7 @@ namespace ts { function recordTaggedTemplateString(temp: Identifier) { taggedTemplateStringDeclarations = append( taggedTemplateStringDeclarations, - createVariableDeclaration(temp)); + factory.createVariableDeclaration(temp)); } function transformSourceFile(node: SourceFile) { @@ -262,7 +264,7 @@ namespace ts { if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) { return setOriginalNode( setTextRange( - createYield(createAwaitHelper(context, visitNode(node.expression, visitor, isExpression))), + factory.createYieldExpression(/*asteriskToken*/ undefined, emitHelpers().createAwaitHelper(visitNode(node.expression, visitor, isExpression))), /*location*/ node ), node @@ -274,18 +276,23 @@ namespace ts { function visitYieldExpression(node: YieldExpression) { if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) { if (node.asteriskToken) { - const expression = visitNode(node.expression, visitor, isExpression); + const expression = visitNode(Debug.assertDefined(node.expression), visitor, isExpression); return setOriginalNode( setTextRange( - createYield( - createAwaitHelper(context, - updateYield( + factory.createYieldExpression( + /*asteriskToken*/ undefined, + emitHelpers().createAwaitHelper( + factory.updateYieldExpression( node, node.asteriskToken, - createAsyncDelegatorHelper( - context, - createAsyncValuesHelper(context, expression, expression), + setTextRange( + emitHelpers().createAsyncDelegatorHelper( + setTextRange( + emitHelpers().createAsyncValuesHelper(expression), + expression + ) + ), expression ) ) @@ -299,11 +306,12 @@ namespace ts { return setOriginalNode( setTextRange( - createYield( + factory.createYieldExpression( + /*asteriskToken*/ undefined, createDownlevelAwait( node.expression ? visitNode(node.expression, visitor, isExpression) - : createVoidZero() + : factory.createVoidZero() ) ), node @@ -317,8 +325,8 @@ namespace ts { function visitReturnStatement(node: ReturnStatement) { if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) { - return updateReturn(node, createDownlevelAwait( - node.expression ? visitNode(node.expression, visitor, isExpression) : createVoidZero() + return factory.updateReturnStatement(node, createDownlevelAwait( + node.expression ? visitNode(node.expression, visitor, isExpression) : factory.createVoidZero() )); } @@ -331,7 +339,7 @@ namespace ts { if (statement.kind === SyntaxKind.ForOfStatement && (statement).awaitModifier) { return visitForOfStatement(statement, node); } - return restoreEnclosingLabel(visitNode(statement, visitor, isStatement, liftToBlock), node); + return factory.restoreEnclosingLabel(visitNode(statement, visitor, isStatement, factory.liftToBlock), node); } return visitEachChild(node, visitor, context); } @@ -342,7 +350,7 @@ namespace ts { for (const e of elements) { if (e.kind === SyntaxKind.SpreadAssignment) { if (chunkObject) { - objects.push(createObjectLiteral(chunkObject)); + objects.push(factory.createObjectLiteralExpression(chunkObject)); chunkObject = undefined; } const target = e.expression; @@ -350,12 +358,12 @@ namespace ts { } else { chunkObject = append(chunkObject, e.kind === SyntaxKind.PropertyAssignment - ? createPropertyAssignment(e.name, visitNode(e.initializer, visitor, isExpression)) + ? factory.createPropertyAssignment(e.name, visitNode(e.initializer, visitor, isExpression)) : visitNode(e, visitor, isObjectLiteralElementLike)); } } if (chunkObject) { - objects.push(createObjectLiteral(chunkObject)); + objects.push(factory.createObjectLiteralExpression(chunkObject)); } return objects; @@ -386,17 +394,17 @@ namespace ts { // end up with `{ a: 1, b: 2, c: 3 }` const objects = chunkObjectLiteralElements(node.properties); if (objects.length && objects[0].kind !== SyntaxKind.ObjectLiteralExpression) { - objects.unshift(createObjectLiteral()); + objects.unshift(factory.createObjectLiteralExpression()); } let expression: Expression = objects[0]; if (objects.length > 1) { for (let i = 1; i < objects.length; i++) { - expression = createAssignHelper(context, [expression, objects[i]]); + expression = emitHelpers().createAssignHelper([expression, objects[i]]); } return expression; } else { - return createAssignHelper(context, objects); + return emitHelpers().createAssignHelper(objects); } } return visitEachChild(node, visitor, context); @@ -419,10 +427,10 @@ namespace ts { exportedVariableStatement = false; const visited = visitEachChild(node, visitor, context); const statement = concatenate(visited.statements, taggedTemplateStringDeclarations && [ - createVariableStatement(/*modifiers*/ undefined, - createVariableDeclarationList(taggedTemplateStringDeclarations)) + factory.createVariableStatement(/*modifiers*/ undefined, + factory.createVariableDeclarationList(taggedTemplateStringDeclarations)) ]); - const result = updateSourceFileNode(visited, setTextRange(createNodeArray(statement), node.statements)); + const result = factory.updateSourceFile(visited, setTextRange(factory.createNodeArray(statement), node.statements)); exitSubtree(ancestorFacts); return result; } @@ -454,9 +462,10 @@ namespace ts { ); } else if (node.operatorToken.kind === SyntaxKind.CommaToken) { - return updateBinary( + return factory.updateBinaryExpression( node, visitNode(node.left, visitorNoDestructuringValue, isExpression), + node.operatorToken, visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, isExpression) ); } @@ -467,19 +476,19 @@ namespace ts { if (node.variableDeclaration && isBindingPattern(node.variableDeclaration.name) && node.variableDeclaration.name.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { - const name = getGeneratedNameForNode(node.variableDeclaration.name); - const updatedDecl = updateVariableDeclaration(node.variableDeclaration, node.variableDeclaration.name, /*type*/ undefined, name); + const name = factory.getGeneratedNameForNode(node.variableDeclaration.name); + const updatedDecl = factory.updateVariableDeclaration(node.variableDeclaration, node.variableDeclaration.name, /*exclamationToken*/ undefined, /*type*/ undefined, name); const visitedBindings = flattenDestructuringBinding(updatedDecl, visitor, context, FlattenLevel.ObjectRest); let block = visitNode(node.block, visitor, isBlock); if (some(visitedBindings)) { - block = updateBlock(block, [ - createVariableStatement(/*modifiers*/ undefined, visitedBindings), + block = factory.updateBlock(block, [ + factory.createVariableStatement(/*modifiers*/ undefined, visitedBindings), ...block.statements, ]); } - return updateCatchClause( + return factory.updateCatchClause( node, - updateVariableDeclaration(node.variableDeclaration, name, /*type*/ undefined, /*initializer*/ undefined), + factory.updateVariableDeclaration(node.variableDeclaration, name, /*exclamationToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined), block); } return visitEachChild(node, visitor, context); @@ -528,7 +537,7 @@ namespace ts { } function visitForStatement(node: ForStatement): VisitResult { - return updateFor( + return factory.updateForStatement( node, visitNode(node.initializer, visitorNoDestructuringValue, isForInitializer), visitNode(node.condition, visitor, isExpression), @@ -553,7 +562,7 @@ namespace ts { } const result = node.awaitModifier ? transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) : - restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement); + factory.restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement); exitSubtree(ancestorFacts); return result; } @@ -563,8 +572,8 @@ namespace ts { if (isVariableDeclarationList(initializerWithoutParens) || isAssignmentPattern(initializerWithoutParens)) { let bodyLocation: TextRange | undefined; let statementsLocation: TextRange | undefined; - const temp = createTempVariable(/*recordTempVariable*/ undefined); - const statements: Statement[] = [createForOfBindingStatement(initializerWithoutParens, temp)]; + const temp = factory.createTempVariable(/*recordTempVariable*/ undefined); + const statements: Statement[] = [createForOfBindingStatement(factory, initializerWithoutParens, temp)]; if (isBlock(node.statement)) { addRange(statements, node.statement.statements); bodyLocation = node.statement; @@ -575,13 +584,13 @@ namespace ts { bodyLocation = node.statement; statementsLocation = node.statement; } - return updateForOf( + return factory.updateForOfStatement( node, node.awaitModifier, setTextRange( - createVariableDeclarationList( + factory.createVariableDeclarationList( [ - setTextRange(createVariableDeclaration(temp), node.initializer) + setTextRange(factory.createVariableDeclaration(temp), node.initializer) ], NodeFlags.Let ), @@ -589,8 +598,8 @@ namespace ts { ), node.expression, setTextRange( - createBlock( - setTextRange(createNodeArray(statements), statementsLocation), + factory.createBlock( + setTextRange(factory.createNodeArray(statements), statementsLocation), /*multiLine*/ true ), bodyLocation @@ -601,7 +610,7 @@ namespace ts { } function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression) { - const binding = createForOfBindingStatement(node.initializer, boundValue); + const binding = createForOfBindingStatement(factory, node.initializer, boundValue); let bodyLocation: TextRange | undefined; let statementsLocation: TextRange | undefined; @@ -618,8 +627,8 @@ namespace ts { return setEmitFlags( setTextRange( - createBlock( - setTextRange(createNodeArray(statements), statementsLocation), + factory.createBlock( + setTextRange(factory.createNodeArray(statements), statementsLocation), /*multiLine*/ true ), bodyLocation @@ -630,47 +639,47 @@ namespace ts { function createDownlevelAwait(expression: Expression) { return enclosingFunctionFlags & FunctionFlags.Generator - ? createYield(/*asteriskToken*/ undefined, createAwaitHelper(context, expression)) - : createAwait(expression); + ? factory.createYieldExpression(/*asteriskToken*/ undefined, emitHelpers().createAwaitHelper(expression)) + : factory.createAwaitExpression(expression); } function transformForAwaitOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, ancestorFacts: HierarchyFacts) { const expression = visitNode(node.expression, visitor, isExpression); - const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined); - const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined); - const errorRecord = createUniqueName("e"); - const catchVariable = getGeneratedNameForNode(errorRecord); - const returnMethod = createTempVariable(/*recordTempVariable*/ undefined); - const callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression); - const callNext = createCall(createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []); - const getDone = createPropertyAccess(result, "done"); - const getValue = createPropertyAccess(result, "value"); - const callReturn = createFunctionCall(returnMethod, iterator, []); + const iterator = isIdentifier(expression) ? factory.getGeneratedNameForNode(expression) : factory.createTempVariable(/*recordTempVariable*/ undefined); + const result = isIdentifier(expression) ? factory.getGeneratedNameForNode(iterator) : factory.createTempVariable(/*recordTempVariable*/ undefined); + const errorRecord = factory.createUniqueName("e"); + const catchVariable = factory.getGeneratedNameForNode(errorRecord); + const returnMethod = factory.createTempVariable(/*recordTempVariable*/ undefined); + const callValues = setTextRange(emitHelpers().createAsyncValuesHelper(expression), node.expression); + const callNext = factory.createCallExpression(factory.createPropertyAccessExpression(iterator, "next"), /*typeArguments*/ undefined, []); + const getDone = factory.createPropertyAccessExpression(result, "done"); + const getValue = factory.createPropertyAccessExpression(result, "value"); + const callReturn = factory.createFunctionCallCall(returnMethod, iterator, []); hoistVariableDeclaration(errorRecord); hoistVariableDeclaration(returnMethod); // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration const initializer = ancestorFacts & HierarchyFacts.IterationContainer ? - inlineExpressions([createAssignment(errorRecord, createVoidZero()), callValues]) : + factory.inlineExpressions([factory.createAssignment(errorRecord, factory.createVoidZero()), callValues]) : callValues; const forStatement = setEmitFlags( setTextRange( - createFor( + factory.createForStatement( /*initializer*/ setEmitFlags( setTextRange( - createVariableDeclarationList([ - setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression), - createVariableDeclaration(result) + factory.createVariableDeclarationList([ + setTextRange(factory.createVariableDeclaration(iterator, /*exclamationToken*/ undefined, /*type*/ undefined, initializer), node.expression), + factory.createVariableDeclaration(result) ]), node.expression ), EmitFlags.NoHoisting ), - /*condition*/ createComma( - createAssignment(result, createDownlevelAwait(callNext)), - createLogicalNot(getDone) + /*condition*/ factory.createComma( + factory.createAssignment(result, createDownlevelAwait(callNext)), + factory.createLogicalNot(getDone) ), /*incrementor*/ undefined, /*statement*/ convertForOfStatementHead(node, getValue) @@ -680,22 +689,22 @@ namespace ts { EmitFlags.NoTokenTrailingSourceMaps ); - return createTry( - createBlock([ - restoreEnclosingLabel( + return factory.createTryStatement( + factory.createBlock([ + factory.restoreEnclosingLabel( forStatement, outermostLabeledStatement ) ]), - createCatchClause( - createVariableDeclaration(catchVariable), + factory.createCatchClause( + factory.createVariableDeclaration(catchVariable), setEmitFlags( - createBlock([ - createExpressionStatement( - createAssignment( + factory.createBlock([ + factory.createExpressionStatement( + factory.createAssignment( errorRecord, - createObjectLiteral([ - createPropertyAssignment("error", catchVariable) + factory.createObjectLiteralExpression([ + factory.createPropertyAssignment("error", catchVariable) ]) ) ) @@ -703,34 +712,34 @@ namespace ts { EmitFlags.SingleLine ) ), - createBlock([ - createTry( - /*tryBlock*/ createBlock([ + factory.createBlock([ + factory.createTryStatement( + /*tryBlock*/ factory.createBlock([ setEmitFlags( - createIf( - createLogicalAnd( - createLogicalAnd( + factory.createIfStatement( + factory.createLogicalAnd( + factory.createLogicalAnd( result, - createLogicalNot(getDone) + factory.createLogicalNot(getDone) ), - createAssignment( + factory.createAssignment( returnMethod, - createPropertyAccess(iterator, "return") + factory.createPropertyAccessExpression(iterator, "return") ) ), - createExpressionStatement(createDownlevelAwait(callReturn)) + factory.createExpressionStatement(createDownlevelAwait(callReturn)) ), EmitFlags.SingleLine ) ]), /*catchClause*/ undefined, /*finallyBlock*/ setEmitFlags( - createBlock([ + factory.createBlock([ setEmitFlags( - createIf( + factory.createIfStatement( errorRecord, - createThrow( - createPropertyAccess(errorRecord, "error") + factory.createThrowStatement( + factory.createPropertyAccessExpression(errorRecord, "error") ) ), EmitFlags.SingleLine @@ -747,12 +756,12 @@ namespace ts { if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { // Binding patterns are converted into a generated name and are // evaluated inside the function body. - return updateParameter( + return factory.updateParameterDeclaration( node, /*decorators*/ undefined, /*modifiers*/ undefined, node.dotDotDotToken, - getGeneratedNameForNode(node), + factory.getGeneratedNameForNode(node), /*questionToken*/ undefined, /*type*/ undefined, visitNode(node.initializer, visitor, isExpression) @@ -764,7 +773,7 @@ namespace ts { function visitConstructorDeclaration(node: ConstructorDeclaration) { const savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = FunctionFlags.Normal; - const updated = updateConstructor( + const updated = factory.updateConstructorDeclaration( node, /*decorators*/ undefined, node.modifiers, @@ -778,7 +787,7 @@ namespace ts { function visitGetAccessorDeclaration(node: GetAccessorDeclaration) { const savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = FunctionFlags.Normal; - const updated = updateGetAccessor( + const updated = factory.updateGetAccessorDeclaration( node, /*decorators*/ undefined, node.modifiers, @@ -794,7 +803,7 @@ namespace ts { function visitSetAccessorDeclaration(node: SetAccessorDeclaration) { const savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = FunctionFlags.Normal; - const updated = updateSetAccessor( + const updated = factory.updateSetAccessorDeclaration( node, /*decorators*/ undefined, node.modifiers, @@ -809,7 +818,7 @@ namespace ts { function visitMethodDeclaration(node: MethodDeclaration) { const savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = getFunctionFlags(node); - const updated = updateMethod( + const updated = factory.updateMethodDeclaration( node, /*decorators*/ undefined, enclosingFunctionFlags & FunctionFlags.Generator @@ -834,7 +843,7 @@ namespace ts { function visitFunctionDeclaration(node: FunctionDeclaration) { const savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = getFunctionFlags(node); - const updated = updateFunctionDeclaration( + const updated = factory.updateFunctionDeclaration( node, /*decorators*/ undefined, enclosingFunctionFlags & FunctionFlags.Generator @@ -858,7 +867,7 @@ namespace ts { function visitArrowFunction(node: ArrowFunction) { const savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = getFunctionFlags(node); - const updated = updateArrowFunction( + const updated = factory.updateArrowFunction( node, node.modifiers, /*typeParameters*/ undefined, @@ -874,7 +883,7 @@ namespace ts { function visitFunctionExpression(node: FunctionExpression) { const savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = getFunctionFlags(node); - const updated = updateFunctionExpression( + const updated = factory.updateFunctionExpression( node, enclosingFunctionFlags & FunctionFlags.Generator ? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier) @@ -897,7 +906,7 @@ namespace ts { function transformAsyncGeneratorFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody { resumeLexicalEnvironment(); const statements: Statement[] = []; - const statementOffset = addPrologue(statements, node.body!.statements, /*ensureUseStrict*/ false, visitor); + const statementOffset = factory.copyPrologue(node.body!.statements, statements, /*ensureUseStrict*/ false, visitor); appendObjectRestAssignmentsIfNeeded(statements, node); const savedCapturedSuperProperties = capturedSuperProperties; @@ -905,17 +914,16 @@ namespace ts { capturedSuperProperties = createUnderscoreEscapedMap(); hasSuperElementAccess = false; - const returnStatement = createReturn( - createAsyncGeneratorHelper( - context, - createFunctionExpression( + const returnStatement = factory.createReturnStatement( + emitHelpers().createAsyncGeneratorHelper( + factory.createFunctionExpression( /*modifiers*/ undefined, - createToken(SyntaxKind.AsteriskToken), - node.name && getGeneratedNameForNode(node.name), + factory.createToken(SyntaxKind.AsteriskToken), + node.name && factory.getGeneratedNameForNode(node.name), /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, - updateBlock( + factory.updateBlock( node.body!, visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset) ) @@ -930,7 +938,7 @@ namespace ts { if (emitSuperHelpers) { enableSubstitutionForAsyncMethodsWithSuper(); - const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties); + const variableStatement = createSuperAccessVariableStatement(factory, resolver, node, capturedSuperProperties); substitutedSuperAccessors[getNodeId(variableStatement)] = true; insertStatementsAfterStandardPrologue(statements, [variableStatement]); } @@ -938,7 +946,7 @@ namespace ts { statements.push(returnStatement); insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment()); - const block = updateBlock(node.body!, statements); + const block = factory.updateBlock(node.body!, statements); if (emitSuperHelpers && hasSuperElementAccess) { if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) { @@ -961,17 +969,17 @@ namespace ts { resumeLexicalEnvironment(); let statementOffset = 0; const statements: Statement[] = []; - const body = visitNode(node.body, visitor, isConciseBody); + const body = visitNode(node.body, visitor, isConciseBody) ?? factory.createBlock([]); if (isBlock(body)) { - statementOffset = addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor); + statementOffset = factory.copyPrologue(body.statements, statements, /*ensureUseStrict*/ false, visitor); } addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node)); const leadingStatements = endLexicalEnvironment(); if (statementOffset > 0 || some(statements) || some(leadingStatements)) { - const block = convertToFunctionBody(body, /*multiLine*/ true); + const block = factory.converters.convertToFunctionBlock(body, /*multiLine*/ true); insertStatementsAfterStandardPrologue(statements, leadingStatements); addRange(statements, block.statements.slice(statementOffset)); - return updateBlock(block, setTextRange(createNodeArray(statements), block.statements)); + return factory.updateBlock(block, setTextRange(factory.createNodeArray(statements), block.statements)); } return body; } @@ -979,7 +987,7 @@ namespace ts { function appendObjectRestAssignmentsIfNeeded(statements: Statement[] | undefined, node: FunctionLikeDeclaration): Statement[] | undefined { for (const parameter of node.parameters) { if (parameter.transformFlags & TransformFlags.ContainsObjectRestOrSpread) { - const temp = getGeneratedNameForNode(parameter); + const temp = factory.getGeneratedNameForNode(parameter); const declarations = flattenDestructuringBinding( parameter, visitor, @@ -990,9 +998,9 @@ namespace ts { /*skipInitializer*/ true, ); if (some(declarations)) { - const statement = createVariableStatement( + const statement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( declarations ) ); @@ -1086,8 +1094,8 @@ namespace ts { function substitutePropertyAccessExpression(node: PropertyAccessExpression) { if (node.expression.kind === SyntaxKind.SuperKeyword) { return setTextRange( - createPropertyAccess( - createFileLevelUniqueName("_super"), + factory.createPropertyAccessExpression( + factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel), node.name), node ); @@ -1111,11 +1119,11 @@ namespace ts { const argumentExpression = isPropertyAccessExpression(expression) ? substitutePropertyAccessExpression(expression) : substituteElementAccessExpression(expression); - return createCall( - createPropertyAccess(argumentExpression, "call"), + return factory.createCallExpression( + factory.createPropertyAccessExpression(argumentExpression, "call"), /*typeArguments*/ undefined, [ - createThis(), + factory.createThis(), ...node.arguments ] ); @@ -1135,9 +1143,9 @@ namespace ts { function createSuperElementAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression { if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) { return setTextRange( - createPropertyAccess( - createCall( - createIdentifier("_superIndex"), + factory.createPropertyAccessExpression( + factory.createCallExpression( + factory.createIdentifier("_superIndex"), /*typeArguments*/ undefined, [argumentExpression] ), @@ -1148,8 +1156,8 @@ namespace ts { } else { return setTextRange( - createCall( - createIdentifier("_superIndex"), + factory.createCallExpression( + factory.createIdentifier("_superIndex"), /*typeArguments*/ undefined, [argumentExpression] ), @@ -1158,135 +1166,4 @@ namespace ts { } } } - - export const assignHelper: UnscopedEmitHelper = { - name: "typescript:assign", - importName: "__assign", - scoped: false, - priority: 1, - text: ` - var __assign = (this && this.__assign) || function () { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); - };` - }; - - export function createAssignHelper(context: TransformationContext, attributesSegments: Expression[]) { - if (context.getCompilerOptions().target! >= ScriptTarget.ES2015) { - return createCall(createPropertyAccess(createIdentifier("Object"), "assign"), /*typeArguments*/ undefined, attributesSegments); - } - context.requestEmitHelper(assignHelper); - return createCall( - getUnscopedHelperName("__assign"), - /*typeArguments*/ undefined, - attributesSegments - ); - } - - export const awaitHelper: UnscopedEmitHelper = { - name: "typescript:await", - importName: "__await", - scoped: false, - text: ` - var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }` - }; - - function createAwaitHelper(context: TransformationContext, expression: Expression) { - context.requestEmitHelper(awaitHelper); - return createCall(getUnscopedHelperName("__await"), /*typeArguments*/ undefined, [expression]); - } - - export const asyncGeneratorHelper: UnscopedEmitHelper = { - name: "typescript:asyncGenerator", - importName: "__asyncGenerator", - scoped: false, - dependencies: [awaitHelper], - text: ` - var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), i, q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; - function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } - function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } - function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } - function fulfill(value) { resume("next", value); } - function reject(value) { resume("throw", value); } - function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } - };` - }; - - function createAsyncGeneratorHelper(context: TransformationContext, generatorFunc: FunctionExpression, hasLexicalThis: boolean) { - context.requestEmitHelper(asyncGeneratorHelper); - - // Mark this node as originally an async function - (generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; - - return createCall( - getUnscopedHelperName("__asyncGenerator"), - /*typeArguments*/ undefined, - [ - hasLexicalThis ? createThis() : createVoidZero(), - createIdentifier("arguments"), - generatorFunc - ] - ); - } - - export const asyncDelegator: UnscopedEmitHelper = { - name: "typescript:asyncDelegator", - importName: "__asyncDelegator", - scoped: false, - dependencies: [awaitHelper], - text: ` - var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { - var i, p; - return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; - function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } - };` - }; - - function createAsyncDelegatorHelper(context: TransformationContext, expression: Expression, location?: TextRange) { - context.requestEmitHelper(asyncDelegator); - return setTextRange( - createCall( - getUnscopedHelperName("__asyncDelegator"), - /*typeArguments*/ undefined, - [expression] - ), - location - ); - } - - export const asyncValues: UnscopedEmitHelper = { - name: "typescript:asyncValues", - importName: "__asyncValues", - scoped: false, - text: ` - var __asyncValues = (this && this.__asyncValues) || function (o) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); - function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } - function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } - };` - }; - - function createAsyncValuesHelper(context: TransformationContext, expression: Expression, location?: TextRange) { - context.requestEmitHelper(asyncValues); - return setTextRange( - createCall( - getUnscopedHelperName("__asyncValues"), - /*typeArguments*/ undefined, - [expression] - ), - location - ); - } } diff --git a/src/compiler/transformers/es2019.ts b/src/compiler/transformers/es2019.ts index 7dfd17481ebe7..0d696b4f5ca01 100644 --- a/src/compiler/transformers/es2019.ts +++ b/src/compiler/transformers/es2019.ts @@ -1,7 +1,8 @@ /*@internal*/ namespace ts { export function transformES2019(context: TransformationContext) { - return chainBundle(transformSourceFile); + const factory = context.factory; + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { if (node.isDeclarationFile) { @@ -25,9 +26,9 @@ namespace ts { function visitCatchClause(node: CatchClause): CatchClause { if (!node.variableDeclaration) { - return updateCatchClause( + return factory.updateCatchClause( node, - createVariableDeclaration(createTempVariable(/*recordTempVariable*/ undefined)), + factory.createVariableDeclaration(factory.createTempVariable(/*recordTempVariable*/ undefined)), visitNode(node.block, visitor, isBlock) ); } diff --git a/src/compiler/transformers/es2020.ts b/src/compiler/transformers/es2020.ts index 8e45fb38f60c8..a3a87df91ed33 100644 --- a/src/compiler/transformers/es2020.ts +++ b/src/compiler/transformers/es2020.ts @@ -2,10 +2,11 @@ namespace ts { export function transformES2020(context: TransformationContext) { const { + factory, hoistVariableDeclaration, } = context; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { if (node.isDeclarationFile) { @@ -57,9 +58,9 @@ namespace ts { if (isSyntheticReference(expression)) { // `(a.b)` -> { expression `((_a = a).b)`, thisArg: `_a` } // `(a[b])` -> { expression `((_a = a)[b])`, thisArg: `_a` } - return createSyntheticReferenceExpression(updateParen(node, expression.expression), expression.thisArg); + return factory.createSyntheticReferenceExpression(factory.updateParenthesizedExpression(node, expression.expression), expression.thisArg); } - return updateParen(node, expression); + return factory.updateParenthesizedExpression(node, expression); } function visitNonOptionalPropertyOrElementAccessExpression(node: AccessExpression, captureThisArg: boolean, isDelete: boolean): Expression { @@ -74,8 +75,8 @@ namespace ts { let thisArg: Expression | undefined; if (captureThisArg) { if (!isSimpleCopiableExpression(expression)) { - thisArg = createTempVariable(hoistVariableDeclaration); - expression = createAssignment(thisArg, expression); + thisArg = factory.createTempVariable(hoistVariableDeclaration); + expression = factory.createAssignment(thisArg, expression); // if (inParameterInitializer) tempVariableInParameter = true; } else { @@ -84,9 +85,9 @@ namespace ts { } expression = node.kind === SyntaxKind.PropertyAccessExpression - ? updatePropertyAccess(node, expression, visitNode(node.name, visitor, isIdentifier)) - : updateElementAccess(node, expression, visitNode(node.argumentExpression, visitor, isExpression)); - return thisArg ? createSyntheticReferenceExpression(expression, thisArg) : expression; + ? factory.updatePropertyAccessExpression(node, expression, visitNode(node.name, visitor, isIdentifier)) + : factory.updateElementAccessExpression(node, expression, visitNode(node.argumentExpression, visitor, isExpression)); + return thisArg ? factory.createSyntheticReferenceExpression(expression, thisArg) : expression; } function visitNonOptionalCallExpression(node: CallExpression, captureThisArg: boolean): Expression { @@ -114,8 +115,8 @@ namespace ts { let leftExpression = isSyntheticReference(left) ? left.expression : left; let capturedLeft: Expression = leftExpression; if (!isSimpleCopiableExpression(leftExpression)) { - capturedLeft = createTempVariable(hoistVariableDeclaration); - leftExpression = createAssignment(capturedLeft, leftExpression); + capturedLeft = factory.createTempVariable(hoistVariableDeclaration); + leftExpression = factory.createAssignment(capturedLeft, leftExpression); // if (inParameterInitializer) tempVariableInParameter = true; } let rightExpression = capturedLeft; @@ -127,8 +128,8 @@ namespace ts { case SyntaxKind.ElementAccessExpression: if (i === chain.length - 1 && captureThisArg) { if (!isSimpleCopiableExpression(rightExpression)) { - thisArg = createTempVariable(hoistVariableDeclaration); - rightExpression = createAssignment(thisArg, rightExpression); + thisArg = factory.createTempVariable(hoistVariableDeclaration); + rightExpression = factory.createAssignment(thisArg, rightExpression); // if (inParameterInitializer) tempVariableInParameter = true; } else { @@ -136,19 +137,19 @@ namespace ts { } } rightExpression = segment.kind === SyntaxKind.PropertyAccessExpression - ? createPropertyAccess(rightExpression, visitNode(segment.name, visitor, isIdentifier)) - : createElementAccess(rightExpression, visitNode(segment.argumentExpression, visitor, isExpression)); + ? factory.createPropertyAccessExpression(rightExpression, visitNode(segment.name, visitor, isIdentifier)) + : factory.createElementAccessExpression(rightExpression, visitNode(segment.argumentExpression, visitor, isExpression)); break; case SyntaxKind.CallExpression: if (i === 0 && leftThisArg) { - rightExpression = createFunctionCall( + rightExpression = factory.createFunctionCallCall( rightExpression, - leftThisArg.kind === SyntaxKind.SuperKeyword ? createThis() : leftThisArg, + leftThisArg.kind === SyntaxKind.SuperKeyword ? factory.createThis() : leftThisArg, visitNodes(segment.arguments, visitor, isExpression) ); } else { - rightExpression = createCall( + rightExpression = factory.createCallExpression( rightExpression, /*typeArguments*/ undefined, visitNodes(segment.arguments, visitor, isExpression) @@ -160,23 +161,23 @@ namespace ts { } const target = isDelete - ? createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), createTrue(), createDelete(rightExpression)) - : createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), createVoidZero(), rightExpression); - return thisArg ? createSyntheticReferenceExpression(target, thisArg) : target; + ? factory.createConditionalExpression(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), /*questionToken*/ undefined, factory.createTrue(), /*colonToken*/ undefined, factory.createDeleteExpression(rightExpression)) + : factory.createConditionalExpression(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), /*questionToken*/ undefined, factory.createVoidZero(), /*colonToken*/ undefined, rightExpression); + return thisArg ? factory.createSyntheticReferenceExpression(target, thisArg) : target; } function createNotNullCondition(left: Expression, right: Expression, invert?: boolean) { - return createBinary( - createBinary( + return factory.createBinaryExpression( + factory.createBinaryExpression( left, - createToken(invert ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken), - createNull() + factory.createToken(invert ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken), + factory.createNull() ), - createToken(invert ? SyntaxKind.BarBarToken : SyntaxKind.AmpersandAmpersandToken), - createBinary( + factory.createToken(invert ? SyntaxKind.BarBarToken : SyntaxKind.AmpersandAmpersandToken), + factory.createBinaryExpression( right, - createToken(invert ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken), - createVoidZero() + factory.createToken(invert ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken), + factory.createVoidZero() ) ); } @@ -185,13 +186,15 @@ namespace ts { let left = visitNode(node.left, visitor, isExpression); let right = left; if (!isSimpleCopiableExpression(left)) { - right = createTempVariable(hoistVariableDeclaration); - left = createAssignment(right, left); + right = factory.createTempVariable(hoistVariableDeclaration); + left = factory.createAssignment(right, left); // if (inParameterInitializer) tempVariableInParameter = true; } - return createConditional( + return factory.createConditionalExpression( createNotNullCondition(left, right), + /*questionToken*/ undefined, right, + /*colonToken*/ undefined, visitNode(node.right, visitor, isExpression), ); } @@ -199,7 +202,7 @@ namespace ts { function visitDeleteExpression(node: DeleteExpression) { return isOptionalChain(skipParentheses(node.expression)) ? setOriginalNode(visitNonOptionalExpression(node.expression, /*captureThisArg*/ false, /*isDelete*/ true), node) - : updateDelete(node, visitNode(node.expression, visitor, isExpression)); + : factory.updateDeleteExpression(node, visitNode(node.expression, visitor, isExpression)); } } } diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index a0a171cc86399..74fff32a2644e 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -6,6 +6,7 @@ namespace ts { * @param context Context and state information for the transformation. */ export function transformES5(context: TransformationContext) { + const { factory } = context; const compilerOptions = context.getCompilerOptions(); // enable emit notification only if using --jsx preserve or react-native @@ -24,7 +25,7 @@ namespace ts { context.onSubstituteNode = onSubstituteNode; context.enableSubstitution(SyntaxKind.PropertyAccessExpression); context.enableSubstitution(SyntaxKind.PropertyAssignment); - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); /** * Transforms an ES5 source file to ES3. @@ -87,7 +88,7 @@ namespace ts { } const literalName = trySubstituteReservedName(node.name); if (literalName) { - return setTextRange(createElementAccess(node.expression, literalName), node); + return setTextRange(factory.createElementAccessExpression(node.expression, literalName), node); } return node; } @@ -100,7 +101,7 @@ namespace ts { function substitutePropertyAssignment(node: PropertyAssignment): PropertyAssignment { const literalName = isIdentifier(node.name) && trySubstituteReservedName(node.name); if (literalName) { - return updatePropertyAssignment(node, literalName, node.initializer); + return factory.updatePropertyAssignment(node, literalName, node.initializer); } return node; } @@ -113,7 +114,7 @@ namespace ts { function trySubstituteReservedName(name: Identifier) { const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(idText(name)) : undefined); if (token !== undefined && token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) { - return setTextRange(createLiteral(name), name); + return setTextRange(factory.createStringLiteralFromNode(name), name); } return undefined; } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 65bb1c1713743..f38d0b7262d60 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -2,9 +2,10 @@ namespace ts { export function transformESNext(context: TransformationContext) { const { - hoistVariableDeclaration + hoistVariableDeclaration, + factory } = context; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { if (node.isDeclarationFile) { @@ -37,14 +38,14 @@ namespace ts { let assignmentTarget = left; const right = skipParentheses(visitNode(binaryExpression.right, visitor, isExpression)); if (isAccessExpression(left)) { - const tempVariable = createTempVariable(hoistVariableDeclaration); + const tempVariable = factory.createTempVariable(hoistVariableDeclaration); if (isPropertyAccessExpression(left)) { - assignmentTarget = createPropertyAccess( + assignmentTarget = factory.createPropertyAccessExpression( tempVariable, left.name ); - left = createPropertyAccess( - createAssignment( + left = factory.createPropertyAccessExpression( + factory.createAssignment( tempVariable, left.expression ), @@ -52,12 +53,12 @@ namespace ts { ); } else { - assignmentTarget = createElementAccess( + assignmentTarget = factory.createElementAccessExpression( tempVariable, left.argumentExpression ); - left = createElementAccess( - createAssignment( + left = factory.createElementAccessExpression( + factory.createAssignment( tempVariable, left.expression ), @@ -66,11 +67,11 @@ namespace ts { } } - return createBinary( + return factory.createBinaryExpression( left, nonAssignmentOperator, - createParen( - createAssignment( + factory.createParenthesizedExpression( + factory.createAssignment( assignmentTarget, right ) diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index cb8619712c4dc..c73037656a77c 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -230,6 +230,8 @@ namespace ts { export function transformGenerators(context: TransformationContext) { const { + factory, + getEmitHelperFactory: emitHelpers, resumeLexicalEnvironment, endLexicalEnvironment, hoistFunctionDeclaration, @@ -263,7 +265,7 @@ namespace ts { // allocating objects to store the same information to avoid GC overhead. // let labelOffsets: number[] | undefined; // The operation offset at which the label is defined. - let labelExpressions: LiteralExpression[][] | undefined; // The NumericLiteral nodes bound to each label. + let labelExpressions: Mutable[][] | undefined; // The NumericLiteral nodes bound to each label. let nextLabelId = 1; // The next label id to use. // Operations store information about generated code for the function body. This @@ -290,7 +292,7 @@ namespace ts { let currentExceptionBlock: ExceptionBlock | undefined; // The current exception block. let withBlockStack: WithBlock[] | undefined; // A stack containing `with` blocks. - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { if (node.isDeclarationFile || (node.transformFlags & TransformFlags.ContainsGenerator) === 0) { @@ -446,7 +448,7 @@ namespace ts { if (node.asteriskToken) { node = setOriginalNode( setTextRange( - createFunctionDeclaration( + factory.createFunctionDeclaration( /*decorators*/ undefined, node.modifiers, /*asteriskToken*/ undefined, @@ -496,7 +498,7 @@ namespace ts { if (node.asteriskToken) { node = setOriginalNode( setTextRange( - createFunctionExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, node.name, @@ -577,18 +579,18 @@ namespace ts { operations = undefined; operationArguments = undefined; operationLocations = undefined; - state = createTempVariable(/*recordTempVariable*/ undefined); + state = factory.createTempVariable(/*recordTempVariable*/ undefined); // Build the generator resumeLexicalEnvironment(); - const statementOffset = addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor); + const statementOffset = factory.copyPrologue(body.statements, statements, /*ensureUseStrict*/ false, visitor); transformAndEmitStatements(body.statements, statementOffset); const buildResult = build(); insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment()); - statements.push(createReturn(buildResult)); + statements.push(factory.createReturnStatement(buildResult)); // Restore previous generator state inGeneratorFunctionBody = savedInGeneratorFunctionBody; @@ -605,7 +607,7 @@ namespace ts { operationLocations = savedOperationLocations; state = savedState; - return setTextRange(createBlock(statements, body.multiLine), body); + return setTextRange(factory.createBlock(statements, body.multiLine), body); } /** @@ -637,8 +639,8 @@ namespace ts { } return setSourceMapRange( - createExpressionStatement( - inlineExpressions( + factory.createExpressionStatement( + factory.inlineExpressions( map(variables, transformInitializedVariable) ) ), @@ -688,7 +690,7 @@ namespace ts { // .mark resumeLabel // _a.b = %sent%; - target = updatePropertyAccess( + target = factory.updatePropertyAccessExpression( left, cacheExpression(visitNode((left).expression, visitor, isLeftHandSideExpression)), (left).name @@ -707,7 +709,7 @@ namespace ts { // .mark resumeLabel // _a[_b] = %sent%; - target = updateElementAccess(left, + target = factory.updateElementAccessExpression(left, cacheExpression(visitNode((left).expression, visitor, isLeftHandSideExpression)), cacheExpression(visitNode((left).argumentExpression, visitor, isExpression)) ); @@ -721,10 +723,10 @@ namespace ts { const operator = node.operatorToken.kind; if (isCompoundAssignment(operator)) { return setTextRange( - createAssignment( + factory.createAssignment( target, setTextRange( - createBinary( + factory.createBinaryExpression( cacheExpression(target), getNonAssignmentOperatorForCompoundAssignment(operator), visitNode(right, visitor, isExpression) @@ -736,7 +738,7 @@ namespace ts { ); } else { - return updateBinary(node, target, visitNode(right, visitor, isExpression)); + return factory.updateBinaryExpression(node, target, node.operatorToken, visitNode(right, visitor, isExpression)); } } @@ -761,10 +763,10 @@ namespace ts { // .yield resumeLabel // _a + %sent% + c() - const clone = getMutableClone(node); - clone.left = cacheExpression(visitNode(node.left, visitor, isExpression)); - clone.right = visitNode(node.right, visitor, isExpression); - return clone; + return factory.updateBinaryExpression(node, + cacheExpression(visitNode(node.left, visitor, isExpression)), + node.operatorToken, + visitNode(node.right, visitor, isExpression)); } return visitEachChild(node, visitor, context); @@ -841,7 +843,7 @@ namespace ts { let pendingExpressions: Expression[] = []; visit(node.left); visit(node.right); - return inlineExpressions(pendingExpressions); + return factory.inlineExpressions(pendingExpressions); function visit(node: Expression) { if (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.CommaToken) { @@ -850,7 +852,7 @@ namespace ts { } else { if (containsYield(node) && pendingExpressions.length > 0) { - emitWorker(OpCode.Statement, [createExpressionStatement(inlineExpressions(pendingExpressions))]); + emitWorker(OpCode.Statement, [factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions))]); pendingExpressions = []; } @@ -916,8 +918,9 @@ namespace ts { const resumeLabel = defineLabel(); const expression = visitNode(node.expression, visitor, isExpression); if (node.asteriskToken) { + // NOTE: `expression` must be defined for `yield*`. const iterator = (getEmitFlags(node.expression!) & EmitFlags.Iterator) === 0 - ? createValuesHelper(context, expression, /*location*/ node) + ? setTextRange(emitHelpers().createValuesHelper(expression!), node) : expression; emitYieldStar(iterator, /*location*/ node); } @@ -963,7 +966,7 @@ namespace ts { temp = declareLocal(); const initialElements = visitNodes(elements, visitor, isExpression, 0, numInitialElements); emitAssignment(temp, - createArrayLiteral( + factory.createArrayLiteralExpression( leadingElement ? [leadingElement, ...initialElements] : initialElements @@ -974,9 +977,9 @@ namespace ts { const expressions = reduceLeft(elements, reduceElement, [], numInitialElements); return temp - ? createArrayConcat(temp, [createArrayLiteral(expressions, multiLine)]) + ? factory.createArrayConcatCall(temp, [factory.createArrayLiteralExpression(expressions, multiLine)]) : setTextRange( - createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, multiLine), + factory.createArrayLiteralExpression(leadingElement ? [leadingElement, ...expressions] : expressions, multiLine), location ); @@ -990,11 +993,11 @@ namespace ts { emitAssignment( temp, hasAssignedTemp - ? createArrayConcat( + ? factory.createArrayConcatCall( temp, - [createArrayLiteral(expressions, multiLine)] + [factory.createArrayLiteralExpression(expressions, multiLine)] ) - : createArrayLiteral( + : factory.createArrayLiteralExpression( leadingElement ? [leadingElement, ...expressions] : expressions, multiLine ) @@ -1033,23 +1036,24 @@ namespace ts { const temp = declareLocal(); emitAssignment(temp, - createObjectLiteral( + factory.createObjectLiteralExpression( visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties), multiLine ) ); const expressions = reduceLeft(properties, reduceProperty, [], numInitialProperties); - expressions.push(multiLine ? startOnNewLine(getMutableClone(temp)) : temp); - return inlineExpressions(expressions); + // TODO(rbuckton): Does this need to be parented? + expressions.push(multiLine ? startOnNewLine(setParent(setTextRange(factory.cloneNode(temp), temp), temp.parent)) : temp); + return factory.inlineExpressions(expressions); function reduceProperty(expressions: Expression[], property: ObjectLiteralElementLike) { if (containsYield(property) && expressions.length > 0) { - emitStatement(createExpressionStatement(inlineExpressions(expressions))); + emitStatement(factory.createExpressionStatement(factory.inlineExpressions(expressions))); expressions = []; } - const expression = createExpressionForObjectLiteralElementLike(node, property, temp); + const expression = createExpressionForObjectLiteralElementLike(factory, node, property, temp); const visited = visitNode(expression, visitor, isExpression); if (visited) { if (multiLine) { @@ -1078,10 +1082,9 @@ namespace ts { // .mark resumeLabel // a = _a[%sent%] - const clone = getMutableClone(node); - clone.expression = cacheExpression(visitNode(node.expression, visitor, isLeftHandSideExpression)); - clone.argumentExpression = visitNode(node.argumentExpression, visitor, isExpression); - return clone; + return factory.updateElementAccessExpression(node, + cacheExpression(visitNode(node.expression, visitor, isLeftHandSideExpression)), + visitNode(node.argumentExpression, visitor, isExpression)); } return visitEachChild(node, visitor, context); @@ -1099,13 +1102,15 @@ namespace ts { // .yield resumeLabel // .mark resumeLabel // _b.apply(_a, _c.concat([%sent%, 2])); - const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true); + const { target, thisArg } = factory.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true); return setOriginalNode( - createFunctionApply( - cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)), - thisArg, - visitElements(node.arguments), - /*location*/ node + setTextRange( + factory.createFunctionApplyCall( + cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)), + thisArg, + visitElements(node.arguments) + ), + node ), node ); @@ -1127,16 +1132,16 @@ namespace ts { // .mark resumeLabel // new (_b.apply(_a, _c.concat([%sent%, 2]))); - const { target, thisArg } = createCallBinding(createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration); + const { target, thisArg } = factory.createCallBinding(factory.createPropertyAccessExpression(node.expression, "bind"), hoistVariableDeclaration); return setOriginalNode( setTextRange( - createNew( - createFunctionApply( + factory.createNewExpression( + factory.createFunctionApplyCall( cacheExpression(visitNode(target, visitor, isExpression)), thisArg, visitElements( node.arguments!, - /*leadingElement*/ createVoidZero() + /*leadingElement*/ factory.createVoidZero() ) ), /*typeArguments*/ undefined, @@ -1228,7 +1233,7 @@ namespace ts { function transformAndEmitVariableDeclarationList(node: VariableDeclarationList): VariableDeclarationList | undefined { for (const variable of node.declarations) { - const name = getSynthesizedClone(variable.name); + const name = factory.cloneNode(variable.name); setCommentRange(name, variable.name); hoistVariableDeclaration(name); } @@ -1248,7 +1253,7 @@ namespace ts { } if (pendingExpressions.length) { - emitStatement(createExpressionStatement(inlineExpressions(pendingExpressions))); + emitStatement(factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions))); variablesWritten += pendingExpressions.length; pendingExpressions = []; } @@ -1257,10 +1262,10 @@ namespace ts { return undefined; } - function transformInitializedVariable(node: VariableDeclaration) { + function transformInitializedVariable(node: InitializedVariableDeclaration) { return setSourceMapRange( - createAssignment( - setSourceMapRange(getSynthesizedClone(node.name), node.name), + factory.createAssignment( + setSourceMapRange(factory.cloneNode(node.name), node.name), visitNode(node.initializer, visitor, isExpression) ), node @@ -1419,7 +1424,7 @@ namespace ts { else { emitStatement( setTextRange( - createExpressionStatement( + factory.createExpressionStatement( visitNode(initializer, visitor, isExpression) ), initializer @@ -1439,7 +1444,7 @@ namespace ts { if (node.incrementor) { emitStatement( setTextRange( - createExpressionStatement( + factory.createExpressionStatement( visitNode(node.incrementor, visitor, isExpression) ), node.incrementor @@ -1466,13 +1471,13 @@ namespace ts { } const variables = getInitializedVariables(initializer); - node = updateFor(node, + node = factory.updateForStatement(node, variables.length > 0 - ? inlineExpressions(map(variables, transformInitializedVariable)) + ? factory.inlineExpressions(map(variables, transformInitializedVariable)) : undefined, visitNode(node.condition, visitor, isExpression), visitNode(node.incrementor, visitor, isExpression), - visitNode(node.statement, visitor, isStatement, liftToBlock) + visitNode(node.statement, visitor, isStatement, factory.liftToBlock) ); } else { @@ -1512,18 +1517,18 @@ namespace ts { const keysArray = declareLocal(); // _a const key = declareLocal(); // _b - const keysIndex = createLoopVariable(); // _i + const keysIndex = factory.createLoopVariable(); // _i const initializer = node.initializer; hoistVariableDeclaration(keysIndex); - emitAssignment(keysArray, createArrayLiteral()); + emitAssignment(keysArray, factory.createArrayLiteralExpression()); emitStatement( - createForIn( + factory.createForInStatement( key, visitNode(node.expression, visitor, isExpression), - createExpressionStatement( - createCall( - createPropertyAccess(keysArray, "push"), + factory.createExpressionStatement( + factory.createCallExpression( + factory.createPropertyAccessExpression(keysArray, "push"), /*typeArguments*/ undefined, [key] ) @@ -1531,14 +1536,14 @@ namespace ts { ) ); - emitAssignment(keysIndex, createLiteral(0)); + emitAssignment(keysIndex, factory.createNumericLiteral(0)); const conditionLabel = defineLabel(); const incrementLabel = defineLabel(); const endLabel = beginLoopBlock(incrementLabel); markLabel(conditionLabel); - emitBreakWhenFalse(endLabel, createLessThan(keysIndex, createPropertyAccess(keysArray, "length"))); + emitBreakWhenFalse(endLabel, factory.createLessThan(keysIndex, factory.createPropertyAccessExpression(keysArray, "length"))); let variable: Expression; if (isVariableDeclarationList(initializer)) { @@ -1546,18 +1551,18 @@ namespace ts { hoistVariableDeclaration(variable.name); } - variable = getSynthesizedClone(initializer.declarations[0].name); + variable = factory.cloneNode(initializer.declarations[0].name); } else { variable = visitNode(initializer, visitor, isExpression); Debug.assert(isLeftHandSideExpression(variable)); } - emitAssignment(variable, createElementAccess(keysArray, keysIndex)); + emitAssignment(variable, factory.createElementAccessExpression(keysArray, keysIndex)); transformAndEmitEmbeddedStatement(node.statement); markLabel(incrementLabel); - emitStatement(createExpressionStatement(createPostfixIncrement(keysIndex))); + emitStatement(factory.createExpressionStatement(factory.createPostfixIncrement(keysIndex))); emitBreak(conditionLabel); endLoopBlock(); @@ -1591,10 +1596,10 @@ namespace ts { hoistVariableDeclaration(variable.name); } - node = updateForIn(node, + node = factory.updateForInStatement(node, initializer.declarations[0].name, visitNode(node.expression, visitor, isExpression), - visitNode(node.statement, visitor, isStatement, liftToBlock) + visitNode(node.statement, visitor, isStatement, factory.liftToBlock) ); } else { @@ -1752,7 +1757,7 @@ namespace ts { } pendingClauses.push( - createCaseClause( + factory.createCaseClause( visitNode(clause.expression, visitor, isExpression), [ createInlineBreak(clauseLabels[i], /*location*/ clause.expression) @@ -1766,7 +1771,7 @@ namespace ts { } if (pendingClauses.length) { - emitStatement(createSwitch(expression, createCaseBlock(pendingClauses))); + emitStatement(factory.createSwitchStatement(expression, factory.createCaseBlock(pendingClauses))); clausesWritten += pendingClauses.length; pendingClauses = []; } @@ -1845,8 +1850,9 @@ namespace ts { } function transformAndEmitThrowStatement(node: ThrowStatement): void { + // TODO(rbuckton): `expression` should be required on `throw`. emitThrow( - visitNode(node.expression, visitor, isExpression), + visitNode(node.expression ?? factory.createVoidZero(), visitor, isExpression), /*location*/ node ); } @@ -1940,7 +1946,8 @@ namespace ts { if (declaration) { const name = renamedCatchVariableDeclarations[getOriginalNodeId(declaration)]; if (name) { - const clone = getMutableClone(name); + // TODO(rbuckton): Does this need to be parented? + const clone = setParent(setTextRange(factory.cloneNode(name), name), name.parent); setSourceMapRange(clone, node); setCommentRange(clone, node); return clone; @@ -1957,15 +1964,15 @@ namespace ts { return node; } - const temp = createTempVariable(hoistVariableDeclaration); + const temp = factory.createTempVariable(hoistVariableDeclaration); emitAssignment(temp, node, /*location*/ node); return temp; } function declareLocal(name?: string): Identifier { const temp = name - ? createUniqueName(name) - : createTempVariable(/*recordTempVariable*/ undefined); + ? factory.createUniqueName(name) + : factory.createTempVariable(/*recordTempVariable*/ undefined); hoistVariableDeclaration(temp); return temp; } @@ -2125,7 +2132,7 @@ namespace ts { exception.catchVariable = name; exception.catchLabel = catchLabel; - emitAssignment(name, createCall(createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [])); + emitAssignment(name, factory.createCallExpression(factory.createPropertyAccessExpression(state, "sent"), /*typeArguments*/ undefined, [])); emitNop(); } @@ -2392,7 +2399,7 @@ namespace ts { labelExpressions = []; } - const expression = createLiteral(-1); + const expression = factory.createNumericLiteral(-1); if (labelExpressions[label] === undefined) { labelExpressions[label] = [expression]; } @@ -2403,14 +2410,14 @@ namespace ts { return expression; } - return createOmittedExpression(); + return factory.createOmittedExpression(); } /** * Creates a numeric literal for the provided instruction. */ function createInstruction(instruction: Instruction): NumericLiteral { - const literal = createLiteral(instruction); + const literal = factory.createNumericLiteral(instruction); addSyntheticTrailingComment(literal, SyntaxKind.MultiLineCommentTrivia, getInstructionName(instruction)); return literal; } @@ -2424,8 +2431,8 @@ namespace ts { function createInlineBreak(label: Label, location?: TextRange): ReturnStatement { Debug.assertLessThan(0, label, "Invalid label"); return setTextRange( - createReturn( - createArrayLiteral([ + factory.createReturnStatement( + factory.createArrayLiteralExpression([ createInstruction(Instruction.Break), createLabel(label) ]) @@ -2442,8 +2449,8 @@ namespace ts { */ function createInlineReturn(expression?: Expression, location?: TextRange): ReturnStatement { return setTextRange( - createReturn( - createArrayLiteral(expression + factory.createReturnStatement( + factory.createArrayLiteralExpression(expression ? [createInstruction(Instruction.Return), expression] : [createInstruction(Instruction.Return)] ) @@ -2457,8 +2464,8 @@ namespace ts { */ function createGeneratorResume(location?: TextRange): LeftHandSideExpression { return setTextRange( - createCall( - createPropertyAccess(state, "sent"), + factory.createCallExpression( + factory.createPropertyAccessExpression(state, "sent"), /*typeArguments*/ undefined, [] ), @@ -2619,17 +2626,16 @@ namespace ts { withBlockStack = undefined; const buildResult = buildStatements(); - return createGeneratorHelper( - context, + return emitHelpers().createGeneratorHelper( setEmitFlags( - createFunctionExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)], + [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)], /*type*/ undefined, - createBlock( + factory.createBlock( buildResult, /*multiLine*/ buildResult.length > 0 ) @@ -2655,8 +2661,8 @@ namespace ts { } if (clauses) { - const labelExpression = createPropertyAccess(state, "label"); - const switchStatement = createSwitch(labelExpression, createCaseBlock(clauses)); + const labelExpression = factory.createPropertyAccessExpression(state, "label"); + const switchStatement = factory.createSwitchStatement(labelExpression, factory.createCaseBlock(clauses)); return [startOnNewLine(switchStatement)]; } @@ -2745,7 +2751,7 @@ namespace ts { // surround the statements in generated `with` blocks to create the same environment. for (let i = withBlockStack.length - 1; i >= 0; i--) { const withBlock = withBlockStack[i]; - statements = [createWith(withBlock.expression, createBlock(statements))]; + statements = [factory.createWithStatement(withBlock.expression, factory.createBlock(statements))]; } } @@ -2755,12 +2761,12 @@ namespace ts { // for each block in the protected region. const { startLabel, catchLabel, finallyLabel, endLabel } = currentExceptionBlock; statements.unshift( - createExpressionStatement( - createCall( - createPropertyAccess(createPropertyAccess(state, "trys"), "push"), + factory.createExpressionStatement( + factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(state, "trys"), "push"), /*typeArguments*/ undefined, [ - createArrayLiteral([ + factory.createArrayLiteralExpression([ createLabel(startLabel), createLabel(catchLabel), createLabel(finallyLabel), @@ -2778,10 +2784,10 @@ namespace ts { // The case clause for the last label falls through to this label, so we // add an assignment statement to reflect the change in labels. statements.push( - createExpressionStatement( - createAssignment( - createPropertyAccess(state, "label"), - createLiteral(labelNumber + 1) + factory.createExpressionStatement( + factory.createAssignment( + factory.createPropertyAccessExpression(state, "label"), + factory.createNumericLiteral(labelNumber + 1) ) ) ); @@ -2789,8 +2795,8 @@ namespace ts { } clauses.push( - createCaseClause( - createLiteral(labelNumber), + factory.createCaseClause( + factory.createNumericLiteral(labelNumber), statements || [] ) ); @@ -2962,7 +2968,7 @@ namespace ts { * @param operationLocation The source map location for the operation. */ function writeAssign(left: Expression, right: Expression, operationLocation: TextRange | undefined): void { - writeStatement(setTextRange(createExpressionStatement(createAssignment(left, right)), operationLocation)); + writeStatement(setTextRange(factory.createExpressionStatement(factory.createAssignment(left, right)), operationLocation)); } /** @@ -2974,7 +2980,7 @@ namespace ts { function writeThrow(expression: Expression, operationLocation: TextRange | undefined): void { lastOperationWasAbrupt = true; lastOperationWasCompletion = true; - writeStatement(setTextRange(createThrow(expression), operationLocation)); + writeStatement(setTextRange(factory.createThrowStatement(expression), operationLocation)); } /** @@ -2989,8 +2995,8 @@ namespace ts { writeStatement( setEmitFlags( setTextRange( - createReturn( - createArrayLiteral(expression + factory.createReturnStatement( + factory.createArrayLiteralExpression(expression ? [createInstruction(Instruction.Return), expression] : [createInstruction(Instruction.Return)] ) @@ -3013,8 +3019,8 @@ namespace ts { writeStatement( setEmitFlags( setTextRange( - createReturn( - createArrayLiteral([ + factory.createReturnStatement( + factory.createArrayLiteralExpression([ createInstruction(Instruction.Break), createLabel(label) ]) @@ -3036,12 +3042,12 @@ namespace ts { function writeBreakWhenTrue(label: Label, condition: Expression, operationLocation: TextRange | undefined): void { writeStatement( setEmitFlags( - createIf( + factory.createIfStatement( condition, setEmitFlags( setTextRange( - createReturn( - createArrayLiteral([ + factory.createReturnStatement( + factory.createArrayLiteralExpression([ createInstruction(Instruction.Break), createLabel(label) ]) @@ -3066,12 +3072,12 @@ namespace ts { function writeBreakWhenFalse(label: Label, condition: Expression, operationLocation: TextRange | undefined): void { writeStatement( setEmitFlags( - createIf( - createLogicalNot(condition), + factory.createIfStatement( + factory.createLogicalNot(condition), setEmitFlags( setTextRange( - createReturn( - createArrayLiteral([ + factory.createReturnStatement( + factory.createArrayLiteralExpression([ createInstruction(Instruction.Break), createLabel(label) ]) @@ -3097,8 +3103,8 @@ namespace ts { writeStatement( setEmitFlags( setTextRange( - createReturn( - createArrayLiteral( + factory.createReturnStatement( + factory.createArrayLiteralExpression( expression ? [createInstruction(Instruction.Yield), expression] : [createInstruction(Instruction.Yield)] @@ -3122,8 +3128,8 @@ namespace ts { writeStatement( setEmitFlags( setTextRange( - createReturn( - createArrayLiteral([ + factory.createReturnStatement( + factory.createArrayLiteralExpression([ createInstruction(Instruction.YieldStar), expression ]) @@ -3141,114 +3147,12 @@ namespace ts { function writeEndfinally(): void { lastOperationWasAbrupt = true; writeStatement( - createReturn( - createArrayLiteral([ + factory.createReturnStatement( + factory.createArrayLiteralExpression([ createInstruction(Instruction.Endfinally) ]) ) ); } } - - function createGeneratorHelper(context: TransformationContext, body: FunctionExpression) { - context.requestEmitHelper(generatorHelper); - return createCall( - getUnscopedHelperName("__generator"), - /*typeArguments*/ undefined, - [createThis(), body]); - } - - // The __generator helper is used by down-level transformations to emulate the runtime - // semantics of an ES2015 generator function. When called, this helper returns an - // object that implements the Iterator protocol, in that it has `next`, `return`, and - // `throw` methods that step through the generator when invoked. - // - // parameters: - // @param thisArg The value to use as the `this` binding for the transformed generator body. - // @param body A function that acts as the transformed generator body. - // - // variables: - // _ Persistent state for the generator that is shared between the helper and the - // generator body. The state object has the following members: - // sent() - A method that returns or throws the current completion value. - // label - The next point at which to resume evaluation of the generator body. - // trys - A stack of protected regions (try/catch/finally blocks). - // ops - A stack of pending instructions when inside of a finally block. - // f A value indicating whether the generator is executing. - // y An iterator to delegate for a yield*. - // t A temporary variable that holds one of the following values (note that these - // cases do not overlap): - // - The completion value when resuming from a `yield` or `yield*`. - // - The error value for a catch block. - // - The current protected region (array of try/catch/finally/end labels). - // - The verb (`next`, `throw`, or `return` method) to delegate to the expression - // of a `yield*`. - // - The result of evaluating the verb delegated to the expression of a `yield*`. - // - // functions: - // verb(n) Creates a bound callback to the `step` function for opcode `n`. - // step(op) Evaluates opcodes in a generator body until execution is suspended or - // completed. - // - // The __generator helper understands a limited set of instructions: - // 0: next(value?) - Start or resume the generator with the specified value. - // 1: throw(error) - Resume the generator with an exception. If the generator is - // suspended inside of one or more protected regions, evaluates - // any intervening finally blocks between the current label and - // the nearest catch block or function boundary. If uncaught, the - // exception is thrown to the caller. - // 2: return(value?) - Resume the generator as if with a return. If the generator is - // suspended inside of one or more protected regions, evaluates any - // intervening finally blocks. - // 3: break(label) - Jump to the specified label. If the label is outside of the - // current protected region, evaluates any intervening finally - // blocks. - // 4: yield(value?) - Yield execution to the caller with an optional value. When - // resumed, the generator will continue at the next label. - // 5: yield*(value) - Delegates evaluation to the supplied iterator. When - // delegation completes, the generator will continue at the next - // label. - // 6: catch(error) - Handles an exception thrown from within the generator body. If - // the current label is inside of one or more protected regions, - // evaluates any intervening finally blocks between the current - // label and the nearest catch block or function boundary. If - // uncaught, the exception is thrown to the caller. - // 7: endfinally - Ends a finally block, resuming the last instruction prior to - // entering a finally block. - // - // For examples of how these are used, see the comments in ./transformers/generators.ts - export const generatorHelper: UnscopedEmitHelper = { - name: "typescript:generator", - importName: "__generator", - scoped: false, - priority: 6, - text: ` - var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } - };` - }; } diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 308bfc18664e4..37ed4eb901fa5 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -1,10 +1,14 @@ /*@internal*/ namespace ts { export function transformJsx(context: TransformationContext) { + const { + factory, + getEmitHelperFactory: emitHelpers, + } = context; const compilerOptions = context.getCompilerOptions(); let currentSourceFile: SourceFile; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); /** * Transform JSX-specific syntax in a SourceFile. @@ -89,8 +93,8 @@ namespace ts { let objectProperties: Expression | undefined; const attrs = node.attributes.properties; if (attrs.length === 0) { + objectProperties = factory.createNull(); // When there are no attributes, React wants "null" - objectProperties = createNull(); } else { // Map spans of JsxAttribute nodes into object literals and spans @@ -98,25 +102,26 @@ namespace ts { const segments = flatten( spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread ? map(attrs, transformJsxSpreadAttributeToExpression) - : createObjectLiteral(map(attrs, transformJsxAttributeToObjectLiteralElement)) + : factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement)) ) ); if (isJsxSpreadAttribute(attrs[0])) { // We must always emit at least one object literal before a spread - // argument. - segments.unshift(createObjectLiteral()); + // argument.factory.createObjectLiteral + segments.unshift(factory.createObjectLiteralExpression()); } // Either emit one big object literal (no spread attribs), or // a call to the __assign helper. objectProperties = singleOrUndefined(segments); if (!objectProperties) { - objectProperties = createAssignHelper(context, segments); + objectProperties = emitHelpers().createAssignHelper(segments); } } const element = createExpressionForJsxElement( + factory, context.getEmitResolver().getJsxFactoryEntity(currentSourceFile), compilerOptions.reactNamespace!, // TODO: GH#18217 tagName, @@ -135,6 +140,7 @@ namespace ts { function visitJsxOpeningFragment(node: JsxOpeningFragment, children: readonly JsxChild[], isChild: boolean, location: TextRange) { const element = createExpressionForJsxFragment( + factory, context.getEmitResolver().getJsxFactoryEntity(currentSourceFile), compilerOptions.reactNamespace!, // TODO: GH#18217 mapDefined(children, transformJsxChildToExpression), @@ -156,25 +162,25 @@ namespace ts { function transformJsxAttributeToObjectLiteralElement(node: JsxAttribute) { const name = getAttributeName(node); const expression = transformJsxAttributeInitializer(node.initializer); - return createPropertyAssignment(name, expression); + return factory.createPropertyAssignment(name, expression); } function transformJsxAttributeInitializer(node: StringLiteral | JsxExpression | undefined): Expression { if (node === undefined) { - return createTrue(); + return factory.createTrue(); } else if (node.kind === SyntaxKind.StringLiteral) { // Always recreate the literal to escape any escape sequences or newlines which may be in the original jsx string and which // Need to be escaped to be handled correctly in a normal string - const literal = createLiteral(tryDecodeEntities(node.text) || node.text); - literal.singleQuote = node.singleQuote !== undefined ? node.singleQuote : !isStringDoubleQuoted(node, currentSourceFile); + const singleQuote = node.singleQuote !== undefined ? node.singleQuote : !isStringDoubleQuoted(node, currentSourceFile); + const literal = factory.createStringLiteral(tryDecodeEntities(node.text) || node.text, singleQuote); return setTextRange(literal, node); } else if (node.kind === SyntaxKind.JsxExpression) { if (node.expression === undefined) { - return createTrue(); + return factory.createTrue(); } - return visitJsxExpression(node); + return visitNode(node.expression, visitor, isExpression); } else { return Debug.failBadSyntaxKind(node); @@ -183,7 +189,7 @@ namespace ts { function visitJsxText(node: JsxText): StringLiteral | undefined { const fixed = fixupWhitespaceAndDecodeEntities(node.text); - return fixed === undefined ? undefined : createLiteral(fixed); + return fixed === undefined ? undefined : factory.createStringLiteral(fixed); } /** @@ -279,10 +285,10 @@ namespace ts { else { const name = node.tagName; if (isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) { - return createLiteral(idText(name)); + return factory.createStringLiteral(idText(name)); } else { - return createExpressionFromEntityName(name); + return createExpressionFromEntityName(factory, name); } } } @@ -299,7 +305,7 @@ namespace ts { return name; } else { - return createLiteral(text); + return factory.createStringLiteral(text); } } diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index f208d7a8d46c1..242143fb33968 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -1,6 +1,10 @@ /*@internal*/ namespace ts { export function transformECMAScriptModule(context: TransformationContext) { + const { + factory, + getEmitHelperFactory: emitHelpers, + } = context; const compilerOptions = context.getCompilerOptions(); const previousOnEmitNode = context.onEmitNode; const previousOnSubstituteNode = context.onSubstituteNode; @@ -10,7 +14,7 @@ namespace ts { context.enableSubstitution(SyntaxKind.Identifier); let helperNameSubstitutions: Map | undefined; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { if (node.isDeclarationFile) { @@ -22,9 +26,9 @@ namespace ts { if (!isExternalModule(node) || some(result.statements, isExternalModuleIndicator)) { return result; } - return updateSourceFileNode( + return factory.updateSourceFile( result, - setTextRange(createNodeArray([...result.statements, createEmptyExports()]), result.statements), + setTextRange(factory.createNodeArray([...result.statements, createEmptyExports(factory)]), result.statements), ); } @@ -32,16 +36,16 @@ namespace ts { } function updateExternalModule(node: SourceFile) { - const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(node, compilerOptions); + const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(factory, emitHelpers(), node, compilerOptions); if (externalHelpersImportDeclaration) { const statements: Statement[] = []; - const statementOffset = addPrologue(statements, node.statements); + const statementOffset = factory.copyPrologue(node.statements, statements); append(statements, externalHelpersImportDeclaration); addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); - return updateSourceFileNode( + return factory.updateSourceFile( node, - setTextRange(createNodeArray(statements), node.statements)); + setTextRange(factory.createNodeArray(statements), node.statements)); } else { return visitEachChild(node, visitor, context); @@ -80,12 +84,14 @@ namespace ts { } const oldIdentifier = node.exportClause.name; - const synthName = getGeneratedNameForNode(oldIdentifier); - const importDecl = createImportDeclaration( + const synthName = factory.getGeneratedNameForNode(oldIdentifier); + const importDecl = factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause(/*name*/ undefined, - createNamespaceImport( + factory.createImportClause( + /*isTypeOnly*/ false, + /*name*/ undefined, + factory.createNamespaceImport( synthName ) ), @@ -93,10 +99,11 @@ namespace ts { ); setOriginalNode(importDecl, node.exportClause); - const exportDecl = createExportDeclaration( + const exportDecl = factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports([createExportSpecifier(synthName, oldIdentifier)]), + /*isTypeOnly*/ false, + factory.createNamedExports([factory.createExportSpecifier(synthName, oldIdentifier)]), ); setOriginalNode(exportDecl, node); @@ -150,7 +157,7 @@ namespace ts { const name = idText(node); let substitution = helperNameSubstitutions!.get(name); if (!substitution) { - helperNameSubstitutions!.set(name, substitution = createFileLevelUniqueName(name)); + helperNameSubstitutions!.set(name, substitution = factory.createUniqueName(name, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)); } return substitution; } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index b0b0fc17da99e..90422838e5739 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -16,6 +16,8 @@ namespace ts { } const { + factory, + getEmitHelperFactory: emitHelpers, startLexicalEnvironment, endLexicalEnvironment, hoistVariableDeclaration @@ -45,7 +47,7 @@ namespace ts { let noSubstitution: boolean[]; // Set of nodes for which substitution rules should be ignored. let needUMDDynamicImportHelper: boolean; - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); /** * Transforms the module aspects of a SourceFile. @@ -61,7 +63,7 @@ namespace ts { } currentSourceFile = node; - currentModuleInfo = collectExternalModuleInfo(node, resolver, compilerOptions); + currentModuleInfo = collectExternalModuleInfo(context, node, resolver, compilerOptions); moduleInfoMap[getOriginalNodeId(node)] = currentModuleInfo; // Perform the transformation. @@ -70,7 +72,7 @@ namespace ts { currentSourceFile = undefined!; currentModuleInfo = undefined!; needUMDDynamicImportHelper = false; - return aggregateTransformFlags(updated); + return updated; } @@ -91,13 +93,13 @@ namespace ts { const statements: Statement[] = []; const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile)); - const statementOffset = addPrologue(statements, node.statements, ensureUseStrict && !isJsonSourceFile(node), sourceElementVisitor); + const statementOffset = factory.copyPrologue(node.statements, statements, ensureUseStrict && !isJsonSourceFile(node), sourceElementVisitor); if (shouldEmitUnderscoreUnderscoreESModule()) { append(statements, createUnderscoreUnderscoreESModule()); } if (length(currentModuleInfo.exportedNames)) { - append(statements, createExpressionStatement(reduceLeft(currentModuleInfo.exportedNames, (prev, nextId) => createAssignment(createPropertyAccess(createIdentifier("exports"), createIdentifier(idText(nextId))), prev), createVoidZero() as Expression))); + append(statements, factory.createExpressionStatement(reduceLeft(currentModuleInfo.exportedNames, (prev, nextId) => factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier("exports"), factory.createIdentifier(idText(nextId))), prev), factory.createVoidZero() as Expression))); } append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement)); @@ -105,7 +107,7 @@ namespace ts { addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false); insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment()); - const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements)); + const updated = factory.updateSourceFile(node, setTextRange(factory.createNodeArray(statements), node.statements)); addEmitHelpers(updated, context.readEmitHelpers()); return updated; } @@ -116,8 +118,8 @@ namespace ts { * @param node The SourceFile node. */ function transformAMDModule(node: SourceFile) { - const define = createIdentifier("define"); - const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions); + const define = factory.createIdentifier("define"); + const moduleName = tryGetModuleNameFromFile(factory, node, host, compilerOptions); const jsonSourceFile = isJsonSourceFile(node) && node; // An AMD define function has the following shape: @@ -145,12 +147,12 @@ namespace ts { // Create an updated SourceFile: // - // define(moduleName?, ["module1", "module2"], function ... - const updated = updateSourceFileNode(node, + // define(mofactory.updateSourceFile", "module2"], function ... + const updated = factory.updateSourceFile(node, setTextRange( - createNodeArray([ - createExpressionStatement( - createCall( + factory.createNodeArray([ + factory.createExpressionStatement( + factory.createCallExpression( define, /*typeArguments*/ undefined, [ @@ -160,9 +162,9 @@ namespace ts { // Add the dependency array argument: // // ["require", "exports", module1", "module2", ...] - createArrayLiteral(jsonSourceFile ? emptyArray : [ - createLiteral("require"), - createLiteral("exports"), + factory.createArrayLiteralExpression(jsonSourceFile ? emptyArray : [ + factory.createStringLiteral("require"), + factory.createStringLiteral("exports"), ...aliasedModuleNames, ...unaliasedModuleNames ]), @@ -171,15 +173,15 @@ namespace ts { // // function (require, exports, module1, module2) ... jsonSourceFile ? - jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : createObjectLiteral() : - createFunctionExpression( + jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : factory.createObjectLiteralExpression() : + factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ - createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"), - createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"), + factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"), + factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"), ...importAliasNames ], /*type*/ undefined, @@ -204,76 +206,77 @@ namespace ts { */ function transformUMDModule(node: SourceFile) { const { aliasedModuleNames, unaliasedModuleNames, importAliasNames } = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ false); - const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions); - const umdHeader = createFunctionExpression( + const moduleName = tryGetModuleNameFromFile(factory, node, host, compilerOptions); + const umdHeader = factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], + [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], /*type*/ undefined, setTextRange( - createBlock( + factory.createBlock( [ - createIf( - createLogicalAnd( - createTypeCheck(createIdentifier("module"), "object"), - createTypeCheck(createPropertyAccess(createIdentifier("module"), "exports"), "object") + factory.createIfStatement( + factory.createLogicalAnd( + factory.createTypeCheck(factory.createIdentifier("module"), "object"), + factory.createTypeCheck(factory.createPropertyAccessExpression(factory.createIdentifier("module"), "exports"), "object") ), - createBlock([ - createVariableStatement( + factory.createBlock([ + factory.createVariableStatement( /*modifiers*/ undefined, [ - createVariableDeclaration( + factory.createVariableDeclaration( "v", + /*exclamationToken*/ undefined, /*type*/ undefined, - createCall( - createIdentifier("factory"), + factory.createCallExpression( + factory.createIdentifier("factory"), /*typeArguments*/ undefined, [ - createIdentifier("require"), - createIdentifier("exports") + factory.createIdentifier("require"), + factory.createIdentifier("exports") ] ) ) ] ), setEmitFlags( - createIf( - createStrictInequality( - createIdentifier("v"), - createIdentifier("undefined") + factory.createIfStatement( + factory.createStrictInequality( + factory.createIdentifier("v"), + factory.createIdentifier("undefined") ), - createExpressionStatement( - createAssignment( - createPropertyAccess(createIdentifier("module"), "exports"), - createIdentifier("v") + factory.createExpressionStatement( + factory.createAssignment( + factory.createPropertyAccessExpression(factory.createIdentifier("module"), "exports"), + factory.createIdentifier("v") ) ) ), EmitFlags.SingleLine ) ]), - createIf( - createLogicalAnd( - createTypeCheck(createIdentifier("define"), "function"), - createPropertyAccess(createIdentifier("define"), "amd") + factory.createIfStatement( + factory.createLogicalAnd( + factory.createTypeCheck(factory.createIdentifier("define"), "function"), + factory.createPropertyAccessExpression(factory.createIdentifier("define"), "amd") ), - createBlock([ - createExpressionStatement( - createCall( - createIdentifier("define"), + factory.createBlock([ + factory.createExpressionStatement( + factory.createCallExpression( + factory.createIdentifier("define"), /*typeArguments*/ undefined, [ // Add the module name (if provided). ...(moduleName ? [moduleName] : []), - createArrayLiteral([ - createLiteral("require"), - createLiteral("exports"), + factory.createArrayLiteralExpression([ + factory.createStringLiteral("require"), + factory.createStringLiteral("exports"), ...aliasedModuleNames, ...unaliasedModuleNames ]), - createIdentifier("factory") + factory.createIdentifier("factory") ] ) ) @@ -299,26 +302,26 @@ namespace ts { // } // })(function ...) - const updated = updateSourceFileNode( + const updated = factory.updateSourceFile( node, setTextRange( - createNodeArray([ - createExpressionStatement( - createCall( + factory.createNodeArray([ + factory.createExpressionStatement( + factory.createCallExpression( umdHeader, /*typeArguments*/ undefined, [ // Add the module body function argument: // // function (require, exports) ... - createFunctionExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ - createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"), - createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"), + factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"), + factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"), ...importAliasNames ], /*type*/ undefined, @@ -357,20 +360,20 @@ namespace ts { // Fill in amd-dependency tags for (const amdDependency of node.amdDependencies) { if (amdDependency.name) { - aliasedModuleNames.push(createLiteral(amdDependency.path)); - importAliasNames.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, amdDependency.name)); + aliasedModuleNames.push(factory.createStringLiteral(amdDependency.path)); + importAliasNames.push(factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, amdDependency.name)); } else { - unaliasedModuleNames.push(createLiteral(amdDependency.path)); + unaliasedModuleNames.push(factory.createStringLiteral(amdDependency.path)); } } for (const importNode of currentModuleInfo.externalImports) { // Find the name of the external module - const externalModuleName = getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions); + const externalModuleName = getExternalModuleNameLiteral(factory, importNode, currentSourceFile, host, resolver, compilerOptions); // Find the name of the module alias, if there is one - const importAliasName = getLocalNameForExternalImport(importNode, currentSourceFile); + const importAliasName = getLocalNameForExternalImport(factory, importNode, currentSourceFile); // It is possible that externalModuleName is undefined if it is not string literal. // This can happen in the invalid import syntax. // E.g : "import * from alias from 'someLib';" @@ -380,7 +383,7 @@ namespace ts { // This is so that when printer will not substitute the identifier setEmitFlags(importAliasName, EmitFlags.NoSubstitution); aliasedModuleNames.push(externalModuleName); - importAliasNames.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName)); + importAliasNames.push(factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName)); } else { unaliasedModuleNames.push(externalModuleName); @@ -392,15 +395,15 @@ namespace ts { } function getAMDImportExpressionForImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration) { - if (isImportEqualsDeclaration(node) || isExportDeclaration(node) || !getExternalModuleNameLiteral(node, currentSourceFile, host, resolver, compilerOptions)) { + if (isImportEqualsDeclaration(node) || isExportDeclaration(node) || !getExternalModuleNameLiteral(factory, node, currentSourceFile, host, resolver, compilerOptions)) { return undefined; } - const name = getLocalNameForExternalImport(node, currentSourceFile)!; // TODO: GH#18217 + const name = getLocalNameForExternalImport(factory, node, currentSourceFile)!; // TODO: GH#18217 const expr = getHelperExpressionForImport(node, name); if (expr === name) { return undefined; } - return createExpressionStatement(createAssignment(name, expr)); + return factory.createExpressionStatement(factory.createAssignment(name, expr)); } /** @@ -412,13 +415,13 @@ namespace ts { startLexicalEnvironment(); const statements: Statement[] = []; - const statementOffset = addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor); + const statementOffset = factory.copyPrologue(node.statements, statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor); if (shouldEmitUnderscoreUnderscoreESModule()) { append(statements, createUnderscoreUnderscoreESModule()); } if (length(currentModuleInfo.exportedNames)) { - append(statements, createExpressionStatement(reduceLeft(currentModuleInfo.exportedNames, (prev, nextId) => createAssignment(createPropertyAccess(createIdentifier("exports"), createIdentifier(idText(nextId))), prev), createVoidZero() as Expression))); + append(statements, factory.createExpressionStatement(reduceLeft(currentModuleInfo.exportedNames, (prev, nextId) => factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier("exports"), factory.createIdentifier(idText(nextId))), prev), factory.createVoidZero() as Expression))); } // Visit each statement of the module body. @@ -435,7 +438,7 @@ namespace ts { // and merge any new lexical declarations. insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment()); - const body = createBlock(statements, /*multiLine*/ true); + const body = factory.createBlock(statements, /*multiLine*/ true); if (needUMDDynamicImportHelper) { addEmitHelper(body, dynamicImportUMDHelper); } @@ -456,16 +459,16 @@ namespace ts { const expressionResult = visitNode(currentModuleInfo.exportEquals.expression, moduleExpressionElementVisitor); if (expressionResult) { if (emitAsReturn) { - const statement = createReturn(expressionResult); + const statement = factory.createReturnStatement(expressionResult); setTextRange(statement, currentModuleInfo.exportEquals); setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments); statements.push(statement); } else { - const statement = createExpressionStatement( - createAssignment( - createPropertyAccess( - createIdentifier("module"), + const statement = factory.createExpressionStatement( + factory.createAssignment( + factory.createPropertyAccessExpression( + factory.createIdentifier("module"), "exports" ), expressionResult @@ -600,7 +603,7 @@ namespace ts { case ModuleKind.AMD: return createImportCallExpressionAMD(argument, containsLexicalThis); case ModuleKind.UMD: - return createImportCallExpressionUMD(argument, containsLexicalThis); + return createImportCallExpressionUMD(argument ?? factory.createVoidZero(), containsLexicalThis); case ModuleKind.CommonJS: default: return createImportCallExpressionCommonJS(argument, containsLexicalThis); @@ -623,18 +626,22 @@ namespace ts { // }); needUMDDynamicImportHelper = true; if (isSimpleCopiableExpression(arg)) { - const argClone = isGeneratedIdentifier(arg) ? arg : isStringLiteral(arg) ? createLiteral(arg) : setEmitFlags(setTextRange(getSynthesizedClone(arg), arg), EmitFlags.NoComments); - return createConditional( - /*condition*/ createIdentifier("__syncRequire"), + const argClone = isGeneratedIdentifier(arg) ? arg : isStringLiteral(arg) ? factory.createStringLiteralFromNode(arg) : setEmitFlags(setTextRange(factory.cloneNode(arg), arg), EmitFlags.NoComments); + return factory.createConditionalExpression( + /*condition*/ factory.createIdentifier("__syncRequire"), + /*questionToken*/ undefined, /*whenTrue*/ createImportCallExpressionCommonJS(arg, containsLexicalThis), + /*colonToken*/ undefined, /*whenFalse*/ createImportCallExpressionAMD(argClone, containsLexicalThis) ); } else { - const temp = createTempVariable(hoistVariableDeclaration); - return createComma(createAssignment(temp, arg), createConditional( - /*condition*/ createIdentifier("__syncRequire"), + const temp = factory.createTempVariable(hoistVariableDeclaration); + return factory.createComma(factory.createAssignment(temp, arg), factory.createConditionalExpression( + /*condition*/ factory.createIdentifier("__syncRequire"), + /*questionToken*/ undefined, /*whenTrue*/ createImportCallExpressionCommonJS(temp, containsLexicalThis), + /*colonToken*/ undefined, /*whenFalse*/ createImportCallExpressionAMD(temp, containsLexicalThis) )); } @@ -647,25 +654,25 @@ namespace ts { // ... // new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/ // }); - const resolve = createUniqueName("resolve"); - const reject = createUniqueName("reject"); + const resolve = factory.createUniqueName("resolve"); + const reject = factory.createUniqueName("reject"); const parameters = [ - createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve), - createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject) + factory.createParameterDeclaration(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve), + factory.createParameterDeclaration(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject) ]; - const body = createBlock([ - createExpressionStatement( - createCall( - createIdentifier("require"), + const body = factory.createBlock([ + factory.createExpressionStatement( + factory.createCallExpression( + factory.createIdentifier("require"), /*typeArguments*/ undefined, - [createArrayLiteral([arg || createOmittedExpression()]), resolve, reject] + [factory.createArrayLiteralExpression([arg || factory.createOmittedExpression()]), resolve, reject] ) ) ]); let func: FunctionExpression | ArrowFunction; if (languageVersion >= ScriptTarget.ES2015) { - func = createArrowFunction( + func = factory.createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, parameters, @@ -674,7 +681,7 @@ namespace ts { body); } else { - func = createFunctionExpression( + func = factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, @@ -691,10 +698,10 @@ namespace ts { } } - const promise = createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); + const promise = factory.createNewExpression(factory.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); if (compilerOptions.esModuleInterop) { context.requestEmitHelper(importStarHelper); - return createCall(createPropertyAccess(promise, createIdentifier("then")), /*typeArguments*/ undefined, [getUnscopedHelperName("__importStar")]); + return factory.createCallExpression(factory.createPropertyAccessExpression(promise, factory.createIdentifier("then")), /*typeArguments*/ undefined, [emitHelpers().createImportStarCallbackHelper()]); } return promise; } @@ -705,16 +712,16 @@ namespace ts { // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/ // We have to wrap require in then callback so that require is done in asynchronously // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately - const promiseResolveCall = createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []); - let requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); + const promiseResolveCall = factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []); + let requireCall: Expression = factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); if (compilerOptions.esModuleInterop) { context.requestEmitHelper(importStarHelper); - requireCall = createCall(getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]); + requireCall = emitHelpers().createImportStarHelper(requireCall); } let func: FunctionExpression | ArrowFunction; if (languageVersion >= ScriptTarget.ES2015) { - func = createArrowFunction( + func = factory.createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], @@ -723,14 +730,14 @@ namespace ts { requireCall); } else { - func = createFunctionExpression( + func = factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, - createBlock([createReturn(requireCall)])); + factory.createBlock([factory.createReturnStatement(requireCall)])); // if there is a lexical 'this' in the import call arguments, ensure we indicate // that this new function expression indicates it captures 'this' so that the @@ -740,7 +747,7 @@ namespace ts { } } - return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]); + return factory.createCallExpression(factory.createPropertyAccessExpression(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]); } function getHelperExpressionForExport(node: ExportDeclaration, innerExpr: Expression) { @@ -749,7 +756,7 @@ namespace ts { } if (getExportNeedsImportStarHelper(node)) { context.requestEmitHelper(importStarHelper); - return createCall(getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]); + return factory.createCallExpression(context.getEmitHelperFactory().getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]); } return innerExpr; } @@ -760,11 +767,11 @@ namespace ts { } if (getImportNeedsImportStarHelper(node)) { context.requestEmitHelper(importStarHelper); - return createCall(getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]); + return emitHelpers().createImportStarHelper(innerExpr); } if (getImportNeedsImportDefaultHelper(node)) { context.requestEmitHelper(importDefaultHelper); - return createCall(getUnscopedHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]); + return emitHelpers().createImportDefaultHelper(innerExpr); } return innerExpr; } @@ -780,15 +787,16 @@ namespace ts { if (moduleKind !== ModuleKind.AMD) { if (!node.importClause) { // import "mod"; - return setOriginalNode(setTextRange(createExpressionStatement(createRequireCall(node)), node), node); + return setOriginalNode(setTextRange(factory.createExpressionStatement(createRequireCall(node)), node), node); } else { const variables: VariableDeclaration[] = []; if (namespaceDeclaration && !isDefaultImport(node)) { // import * as n from "mod"; variables.push( - createVariableDeclaration( - getSynthesizedClone(namespaceDeclaration.name), + factory.createVariableDeclaration( + factory.cloneNode(namespaceDeclaration.name), + /*exclamationToken*/ undefined, /*type*/ undefined, getHelperExpressionForImport(node, createRequireCall(node)) ) @@ -800,8 +808,9 @@ namespace ts { // import d, { x, y } from "mod"; // import d, * as n from "mod"; variables.push( - createVariableDeclaration( - getGeneratedNameForNode(node), + factory.createVariableDeclaration( + factory.getGeneratedNameForNode(node), + /*exclamationToken*/ undefined, /*type*/ undefined, getHelperExpressionForImport(node, createRequireCall(node)) ) @@ -809,10 +818,11 @@ namespace ts { if (namespaceDeclaration && isDefaultImport(node)) { variables.push( - createVariableDeclaration( - getSynthesizedClone(namespaceDeclaration.name), + factory.createVariableDeclaration( + factory.cloneNode(namespaceDeclaration.name), + /*exclamationToken*/ undefined, /*type*/ undefined, - getGeneratedNameForNode(node) + factory.getGeneratedNameForNode(node) ) ); } @@ -821,9 +831,9 @@ namespace ts { statements = append(statements, setOriginalNode( setTextRange( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( variables, languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None ) @@ -837,16 +847,17 @@ namespace ts { else if (namespaceDeclaration && isDefaultImport(node)) { // import d, * as n from "mod"; statements = append(statements, - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( [ setOriginalNode( setTextRange( - createVariableDeclaration( - getSynthesizedClone(namespaceDeclaration.name), + factory.createVariableDeclaration( + factory.cloneNode(namespaceDeclaration.name), + /*exclamationToken*/ undefined, /*type*/ undefined, - getGeneratedNameForNode(node) + factory.getGeneratedNameForNode(node) ), /*location*/ node), /*original*/ node @@ -876,13 +887,13 @@ namespace ts { * @param importNode The declararation to import. */ function createRequireCall(importNode: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) { - const moduleName = getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions); + const moduleName = getExternalModuleNameLiteral(factory, importNode, currentSourceFile, host, resolver, compilerOptions); const args: Expression[] = []; if (moduleName) { args.push(moduleName); } - return createCall(createIdentifier("require"), /*typeArguments*/ undefined, args); + return factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, args); } /** @@ -899,7 +910,7 @@ namespace ts { statements = append(statements, setOriginalNode( setTextRange( - createExpressionStatement( + factory.createExpressionStatement( createExportExpression( node.name, createRequireCall(node) @@ -914,12 +925,13 @@ namespace ts { statements = append(statements, setOriginalNode( setTextRange( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( + factory.createVariableDeclarationList( [ - createVariableDeclaration( - getSynthesizedClone(node.name), + factory.createVariableDeclaration( + factory.cloneNode(node.name), + /*exclamationToken*/ undefined, /*type*/ undefined, createRequireCall(node) ) @@ -938,8 +950,8 @@ namespace ts { statements = append(statements, setOriginalNode( setTextRange( - createExpressionStatement( - createExportExpression(getExportName(node), getLocalName(node)) + factory.createExpressionStatement( + createExportExpression(factory.getExportName(node), factory.getLocalName(node)) ), node), node @@ -972,7 +984,7 @@ namespace ts { return undefined; } - const generatedName = getGeneratedNameForNode(node); + const generatedName = factory.getGeneratedNameForNode(node); if (node.exportClause && isNamedExports(node.exportClause)) { const statements: Statement[] = []; @@ -981,11 +993,12 @@ namespace ts { statements.push( setOriginalNode( setTextRange( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( generatedName, + /*exclamationToken*/ undefined, /*type*/ undefined, createRequireCall(node) ) @@ -1001,8 +1014,8 @@ namespace ts { statements.push( setOriginalNode( setTextRange( - createExpressionStatement( - createCreateBindingHelper(context, generatedName, createLiteral(specifier.propertyName || specifier.name), specifier.propertyName ? createLiteral(specifier.name) : undefined) + factory.createExpressionStatement( + context.getEmitHelperFactory().createCreateBindingHelper(generatedName, factory.createStringLiteralFromNode(specifier.propertyName || specifier.name), specifier.propertyName ? factory.createStringLiteralFromNode(specifier.name) : undefined) ), specifier), specifier @@ -1010,15 +1023,15 @@ namespace ts { ); } else { - const exportedValue = createPropertyAccess( + const exportedValue = factory.createPropertyAccessExpression( generatedName, specifier.propertyName || specifier.name ); statements.push( setOriginalNode( setTextRange( - createExpressionStatement( - createExportExpression(getExportName(specifier), exportedValue, /* location */ undefined, /* liveBinding */ true) + factory.createExpressionStatement( + createExportExpression(factory.getExportName(specifier), exportedValue, /* location */ undefined, /* liveBinding */ true) ), specifier), specifier @@ -1035,12 +1048,12 @@ namespace ts { statements.push( setOriginalNode( setTextRange( - createExpressionStatement( + factory.createExpressionStatement( createExportExpression( - getSynthesizedClone(node.exportClause.name), + factory.cloneNode(node.exportClause.name), moduleKind !== ModuleKind.AMD ? getHelperExpressionForExport(node, createRequireCall(node)) : - createIdentifier(idText(node.exportClause.name)) + factory.createIdentifier(idText(node.exportClause.name)) ) ), node @@ -1055,7 +1068,7 @@ namespace ts { // export * from "mod"; return setOriginalNode( setTextRange( - createExpressionStatement( + factory.createExpressionStatement( createExportStarHelper(context, moduleKind !== ModuleKind.AMD ? createRequireCall(node) : generatedName) ), node), @@ -1079,10 +1092,10 @@ namespace ts { if (original && hasAssociatedEndOfDeclarationMarker(original)) { // Defer exports until we encounter an EndOfDeclarationMarker node const id = getOriginalNodeId(node); - deferredExports[id] = appendExportStatement(deferredExports[id], createIdentifier("default"), visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true); + deferredExports[id] = appendExportStatement(deferredExports[id], factory.createIdentifier("default"), visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true); } else { - statements = appendExportStatement(statements, createIdentifier("default"), visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true); + statements = appendExportStatement(statements, factory.createIdentifier("default"), visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true); } return singleOrMany(statements); @@ -1099,11 +1112,11 @@ namespace ts { statements = append(statements, setOriginalNode( setTextRange( - createFunctionDeclaration( + factory.createFunctionDeclaration( /*decorators*/ undefined, visitNodes(node.modifiers, modifierVisitor, isModifier), node.asteriskToken, - getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), + factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, visitNodes(node.parameters, moduleExpressionElementVisitor), /*type*/ undefined, @@ -1142,10 +1155,10 @@ namespace ts { statements = append(statements, setOriginalNode( setTextRange( - createClassDeclaration( + factory.createClassDeclaration( /*decorators*/ undefined, visitNodes(node.modifiers, modifierVisitor, isModifier), - getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), + factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, visitNodes(node.heritageClauses, moduleExpressionElementVisitor), visitNodes(node.members, moduleExpressionElementVisitor) @@ -1195,16 +1208,16 @@ namespace ts { variables = append(variables, variable); } else if (variable.initializer) { - expressions = append(expressions, transformInitializedVariable(variable)); + expressions = append(expressions, transformInitializedVariable(variable as InitializedVariableDeclaration)); } } if (variables) { - statements = append(statements, updateVariableStatement(node, modifiers, updateVariableDeclarationList(node.declarationList, variables))); + statements = append(statements, factory.updateVariableStatement(node, modifiers, factory.updateVariableDeclarationList(node.declarationList, variables))); } if (expressions) { - statements = append(statements, setOriginalNode(setTextRange(createExpressionStatement(inlineExpressions(expressions)), node), node)); + statements = append(statements, setOriginalNode(setTextRange(factory.createExpressionStatement(factory.inlineExpressions(expressions)), node), node)); } } else { @@ -1227,7 +1240,7 @@ namespace ts { const exportedNames = getExports(name); if (exportedNames) { // For each additional export of the declaration, apply an export assignment. - let expression: Expression = isExportName(name) ? value : createAssignment(name, value); + let expression: Expression = isExportName(name) ? value : factory.createAssignment(name, value); for (const exportName of exportedNames) { // Mark the node to prevent triggering substitution. setEmitFlags(expression, EmitFlags.NoSubstitution); @@ -1236,7 +1249,7 @@ namespace ts { return expression; } - return createAssignment(name, value); + return factory.createAssignment(name, value); } /** @@ -1244,7 +1257,7 @@ namespace ts { * * @param node The node to transform. */ - function transformInitializedVariable(node: VariableDeclaration): Expression { + function transformInitializedVariable(node: InitializedVariableDeclaration): Expression { if (isBindingPattern(node.name)) { return flattenDestructuringAssignment( visitNode(node, moduleExpressionElementVisitor), @@ -1256,15 +1269,15 @@ namespace ts { ); } else { - return createAssignment( + return factory.createAssignment( setTextRange( - createPropertyAccess( - createIdentifier("exports"), + factory.createPropertyAccessExpression( + factory.createIdentifier("exports"), node.name ), /*location*/ node.name ), - node.initializer ? visitNode(node.initializer, moduleExpressionElementVisitor) : createVoidZero() + node.initializer ? visitNode(node.initializer, moduleExpressionElementVisitor) : factory.createVoidZero() ); } } @@ -1443,8 +1456,8 @@ namespace ts { } if (hasSyntacticModifier(decl, ModifierFlags.Export)) { - const exportName = hasSyntacticModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : getDeclarationName(decl); - statements = appendExportStatement(statements, exportName, getLocalName(decl), /*location*/ decl); + const exportName = hasSyntacticModifier(decl, ModifierFlags.Default) ? factory.createIdentifier("default") : factory.getDeclarationName(decl); + statements = appendExportStatement(statements, exportName, factory.getLocalName(decl), /*location*/ decl); } if (decl.name) { @@ -1463,7 +1476,7 @@ namespace ts { * @param decl The declaration to export. */ function appendExportsOfDeclaration(statements: Statement[] | undefined, decl: Declaration, liveBinding?: boolean): Statement[] | undefined { - const name = getDeclarationName(decl); + const name = factory.getDeclarationName(decl); const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(idText(name)); if (exportSpecifiers) { for (const exportSpecifier of exportSpecifiers) { @@ -1493,23 +1506,23 @@ namespace ts { function createUnderscoreUnderscoreESModule() { let statement: Statement; if (languageVersion === ScriptTarget.ES3) { - statement = createExpressionStatement( + statement = factory.createExpressionStatement( createExportExpression( - createIdentifier("__esModule"), - createLiteral(/*value*/ true) + factory.createIdentifier("__esModule"), + factory.createTrue() ) ); } else { - statement = createExpressionStatement( - createCall( - createPropertyAccess(createIdentifier("Object"), "defineProperty"), + statement = factory.createExpressionStatement( + factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ - createIdentifier("exports"), - createLiteral("__esModule"), - createObjectLiteral([ - createPropertyAssignment("value", createLiteral(/*value*/ true)) + factory.createIdentifier("exports"), + factory.createStringLiteral("__esModule"), + factory.createObjectLiteralExpression([ + factory.createPropertyAssignment("value", factory.createTrue()) ]) ] ) @@ -1528,7 +1541,7 @@ namespace ts { * @param allowComments An optional value indicating whether to emit comments for the statement. */ function createExportStatement(name: Identifier, value: Expression, location?: TextRange, allowComments?: boolean, liveBinding?: boolean) { - const statement = setTextRange(createExpressionStatement(createExportExpression(name, value, /* location */ undefined, liveBinding)), location); + const statement = setTextRange(factory.createExpressionStatement(createExportExpression(name, value, /* location */ undefined, liveBinding)), location); startOnNewLine(statement); if (!allowComments) { setEmitFlags(statement, EmitFlags.NoComments); @@ -1546,32 +1559,32 @@ namespace ts { */ function createExportExpression(name: Identifier, value: Expression, location?: TextRange, liveBinding?: boolean) { return setTextRange( - liveBinding && languageVersion !== ScriptTarget.ES3 ? createCall( - createPropertyAccess( - createIdentifier("Object"), + liveBinding && languageVersion !== ScriptTarget.ES3 ? factory.createCallExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier("Object"), "defineProperty" ), /*typeArguments*/ undefined, [ - createIdentifier("exports"), - createLiteral(name), - createObjectLiteral([ - createPropertyAssignment("enumerable", createLiteral(/*value*/ true)), - createPropertyAssignment("get", createFunctionExpression( + factory.createIdentifier("exports"), + factory.createStringLiteralFromNode(name), + factory.createObjectLiteralExpression([ + factory.createPropertyAssignment("enumerable", factory.createTrue()), + factory.createPropertyAssignment("get", factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, - createBlock([createReturn(value)]) + factory.createBlock([factory.createReturnStatement(value)]) )) ]) ] - ) : createAssignment( - createPropertyAccess( - createIdentifier("exports"), - getSynthesizedClone(name) + ) : factory.createAssignment( + factory.createPropertyAccessExpression( + factory.createIdentifier("exports"), + factory.cloneNode(name) ), value ), @@ -1666,10 +1679,10 @@ namespace ts { // A shorthand property with an assignment initializer is probably part of a // destructuring assignment if (node.objectAssignmentInitializer) { - const initializer = createAssignment(exportedOrImportedName, node.objectAssignmentInitializer); - return setTextRange(createPropertyAssignment(name, initializer), node); + const initializer = factory.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer); + return setTextRange(factory.createPropertyAssignment(name, initializer), node); } - return setTextRange(createPropertyAssignment(name, exportedOrImportedName), node); + return setTextRange(factory.createPropertyAssignment(name, exportedOrImportedName), node); } return node; } @@ -1703,7 +1716,7 @@ namespace ts { if (getEmitFlags(node) & EmitFlags.HelperName) { const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile); if (externalHelpersModuleName) { - return createPropertyAccess(externalHelpersModuleName, node); + return factory.createPropertyAccessExpression(externalHelpersModuleName, node); } return node; @@ -1713,9 +1726,9 @@ namespace ts { const exportContainer = resolver.getReferencedExportContainer(node, isExportName(node)); if (exportContainer && exportContainer.kind === SyntaxKind.SourceFile) { return setTextRange( - createPropertyAccess( - createIdentifier("exports"), - getSynthesizedClone(node) + factory.createPropertyAccessExpression( + factory.createIdentifier("exports"), + factory.cloneNode(node) ), /*location*/ node ); @@ -1725,9 +1738,9 @@ namespace ts { if (importDeclaration) { if (isImportClause(importDeclaration)) { return setTextRange( - createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent), - createIdentifier("default") + factory.createPropertyAccessExpression( + factory.getGeneratedNameForNode(importDeclaration.parent), + factory.createIdentifier("default") ), /*location*/ node ); @@ -1735,9 +1748,9 @@ namespace ts { else if (isImportSpecifier(importDeclaration)) { const name = importDeclaration.propertyName || importDeclaration.name; return setTextRange( - createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent.parent.parent), - getSynthesizedClone(name) + factory.createPropertyAccessExpression( + factory.getGeneratedNameForNode(importDeclaration.parent.parent.parent), + factory.cloneNode(name) ), /*location*/ node ); @@ -1807,10 +1820,10 @@ namespace ts { if (exportedNames) { let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression ? setTextRange( - createBinary( + factory.createBinaryExpression( node.operand, - createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken), - createLiteral(1) + factory.createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken), + factory.createNumericLiteral(1) ), /*location*/ node) : node; @@ -1844,39 +1857,6 @@ namespace ts { } } - export const createBindingHelper: UnscopedEmitHelper = { - name: "typescript:commonjscreatebinding", - importName: "__createBinding", - scoped: false, - priority: 1, - text: ` -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -}));` - }; - - function createCreateBindingHelper(context: TransformationContext, module: Expression, inputName: Expression, outputName: Expression | undefined) { - context.requestEmitHelper(createBindingHelper); - return createCall(getUnscopedHelperName("__createBinding"), /*typeArguments*/ undefined, [createIdentifier("exports"), module, inputName, ...(outputName ? [outputName] : [])]); - } - - export const setModuleDefaultHelper: UnscopedEmitHelper = { - name: "typescript:commonjscreatevalue", - importName: "__setModuleDefault", - scoped: false, - priority: 1, - text: ` -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -});` - }; - // emit output for the __export helper function const exportStarHelper: UnscopedEmitHelper = { name: "typescript:export-star", @@ -1892,7 +1872,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( function createExportStarHelper(context: TransformationContext, module: Expression) { context.requestEmitHelper(exportStarHelper); - return createCall(getUnscopedHelperName("__exportStar"), /*typeArguments*/ undefined, [module, createIdentifier("exports")]); + return context.factory.createCallExpression(context.getEmitHelperFactory().getUnscopedHelperName("__exportStar"), /*typeArguments*/ undefined, [module, context.factory.createIdentifier("exports")]); } // emit helper for dynamic import @@ -1902,32 +1882,4 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( text: ` var __syncRequire = typeof module === "object" && typeof module.exports === "object";` }; - - // emit helper for `import * as Name from "foo"` - export const importStarHelper: UnscopedEmitHelper = { - name: "typescript:commonjsimportstar", - importName: "__importStar", - scoped: false, - dependencies: [createBindingHelper, setModuleDefaultHelper], - priority: 2, - text: ` -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -};` - }; - - // emit helper for `import Name from "foo"` - export const importDefaultHelper: UnscopedEmitHelper = { - name: "typescript:commonjsimportdefault", - importName: "__importDefault", - scoped: false, - text: ` -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -};` - }; } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 07da91f04c35f..26590fbb5d9d1 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -7,6 +7,7 @@ namespace ts { } const { + factory, startLexicalEnvironment, endLexicalEnvironment, hoistVariableDeclaration @@ -41,7 +42,7 @@ namespace ts { let enclosingBlockScopedContainer: Node; let noSubstitution: boolean[] | undefined; // Set of nodes for which substitution rules should be ignored. - return chainBundle(transformSourceFile); + return chainBundle(context, transformSourceFile); /** * Transforms the module aspects of a SourceFile. @@ -71,25 +72,25 @@ namespace ts { // see comment to 'substitutePostfixUnaryExpression' for more details // Collect information about the external module and dependency groups. - moduleInfo = moduleInfoMap[id] = collectExternalModuleInfo(node, resolver, compilerOptions); + moduleInfo = moduleInfoMap[id] = collectExternalModuleInfo(context, node, resolver, compilerOptions); // Make sure that the name of the 'exports' function does not conflict with // existing identifiers. - exportFunction = createUniqueName("exports"); + exportFunction = factory.createUniqueName("exports"); exportFunctionsMap[id] = exportFunction; - contextObject = contextObjectMap[id] = createUniqueName("context"); + contextObject = contextObjectMap[id] = factory.createUniqueName("context"); // Add the body of the module. const dependencyGroups = collectDependencyGroups(moduleInfo.externalImports); const moduleBodyBlock = createSystemModuleBody(node, dependencyGroups); - const moduleBodyFunction = createFunctionExpression( + const moduleBodyFunction = factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ - createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, exportFunction), - createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject) + factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, exportFunction), + factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject) ], /*type*/ undefined, moduleBodyBlock @@ -98,16 +99,16 @@ namespace ts { // Write the call to `System.register` // Clear the emit-helpers flag for later passes since we'll have already used it in the module body // So the helper will be emit at the correct position instead of at the top of the source-file - const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions); - const dependencies = createArrayLiteral(map(dependencyGroups, dependencyGroup => dependencyGroup.name)); + const moduleName = tryGetModuleNameFromFile(factory, node, host, compilerOptions); + const dependencies = factory.createArrayLiteralExpression(map(dependencyGroups, dependencyGroup => dependencyGroup.name)); const updated = setEmitFlags( - updateSourceFileNode( + factory.updateSourceFile( node, setTextRange( - createNodeArray([ - createExpressionStatement( - createCall( - createPropertyAccess(createIdentifier("System"), "register"), + factory.createNodeArray([ + factory.createExpressionStatement( + factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier("System"), "register"), /*typeArguments*/ undefined, moduleName ? [moduleName, dependencies, moduleBodyFunction] @@ -134,7 +135,7 @@ namespace ts { contextObject = undefined!; hoistedStatements = undefined!; enclosingBlockScopedContainer = undefined!; - return aggregateTransformFlags(updated); + return updated; } /** @@ -146,7 +147,7 @@ namespace ts { const groupIndices = createMap(); const dependencyGroups: DependencyGroup[] = []; for (const externalImport of externalImports) { - const externalModuleName = getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions); + const externalModuleName = getExternalModuleNameLiteral(factory, externalImport, currentSourceFile, host, resolver, compilerOptions); if (externalModuleName) { const text = externalModuleName.text; const groupIndex = groupIndices.get(text); @@ -224,19 +225,20 @@ namespace ts { // Add any prologue directives. const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile)); - const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor); + const statementOffset = factory.copyPrologue(node.statements, statements, ensureUseStrict, sourceElementVisitor); // var __moduleName = context_1 && context_1.id; statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( "__moduleName", + /*exclamationToken*/ undefined, /*type*/ undefined, - createLogicalAnd( + factory.createLogicalAnd( contextObject, - createPropertyAccess(contextObject, "id") + factory.createPropertyAccessExpression(contextObject, "id") ) ) ]) @@ -263,28 +265,27 @@ namespace ts { const exportStarFunction = addExportStarIfNeeded(statements)!; // TODO: GH#18217 const modifiers = node.transformFlags & TransformFlags.ContainsAwait ? - createModifiersFromModifierFlags(ModifierFlags.Async) : + factory.createModifiersFromModifierFlags(ModifierFlags.Async) : undefined; - const moduleObject = createObjectLiteral([ - createPropertyAssignment("setters", + const moduleObject = factory.createObjectLiteralExpression([ + factory.createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups) ), - createPropertyAssignment("execute", - createFunctionExpression( + factory.createPropertyAssignment("execute", + factory.createFunctionExpression( modifiers, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, - createBlock(executeStatements, /*multiLine*/ true) + factory.createBlock(executeStatements, /*multiLine*/ true) ) ) - ]); + ], /*multiLine*/ true); - moduleObject.multiLine = true; - statements.push(createReturn(moduleObject)); - return createBlock(statements, /*multiLine*/ true); + statements.push(factory.createReturnStatement(moduleObject)); + return factory.createBlock(statements, /*multiLine*/ true); } /** @@ -331,23 +332,24 @@ namespace ts { // write name of exported declaration, i.e 'export var x...' exportedNames.push( - createPropertyAssignment( - createLiteral(exportedLocalName), - createTrue() + factory.createPropertyAssignment( + factory.createStringLiteralFromNode(exportedLocalName), + factory.createTrue() ) ); } } - const exportedNamesStorageRef = createUniqueName("exportedNames"); + const exportedNamesStorageRef = factory.createUniqueName("exportedNames"); statements.push( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( exportedNamesStorageRef, + /*exclamationToken*/ undefined, /*type*/ undefined, - createObjectLiteral(exportedNames, /*multiline*/ true) + factory.createObjectLiteralExpression(exportedNames, /*multiline*/ true) ) ]) ) @@ -366,17 +368,17 @@ namespace ts { * names. */ function createExportStarFunction(localNames: Identifier | undefined) { - const exportStarFunction = createUniqueName("exportStar"); - const m = createIdentifier("m"); - const n = createIdentifier("n"); - const exports = createIdentifier("exports"); - let condition: Expression = createStrictInequality(n, createLiteral("default")); + const exportStarFunction = factory.createUniqueName("exportStar"); + const m = factory.createIdentifier("m"); + const n = factory.createIdentifier("n"); + const exports = factory.createIdentifier("exports"); + let condition: Expression = factory.createStrictInequality(n, factory.createStringLiteral("default")); if (localNames) { - condition = createLogicalAnd( + condition = factory.createLogicalAnd( condition, - createLogicalNot( - createCall( - createPropertyAccess(localNames, "hasOwnProperty"), + factory.createLogicalNot( + factory.createCallExpression( + factory.createPropertyAccessExpression(localNames, "hasOwnProperty"), /*typeArguments*/ undefined, [n] ) @@ -384,38 +386,39 @@ namespace ts { ); } - return createFunctionDeclaration( + return factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, exportStarFunction, /*typeParameters*/ undefined, - [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, m)], + [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, m)], /*type*/ undefined, - createBlock([ - createVariableStatement( + factory.createBlock([ + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( exports, + /*exclamationToken*/ undefined, /*type*/ undefined, - createObjectLiteral([]) + factory.createObjectLiteralExpression([]) ) ]) ), - createForIn( - createVariableDeclarationList([ - createVariableDeclaration(n, /*type*/ undefined) + factory.createForInStatement( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration(n) ]), m, - createBlock([ + factory.createBlock([ setEmitFlags( - createIf( + factory.createIfStatement( condition, - createExpressionStatement( - createAssignment( - createElementAccess(exports, n), - createElementAccess(m, n) + factory.createExpressionStatement( + factory.createAssignment( + factory.createElementAccessExpression(exports, n), + factory.createElementAccessExpression(m, n) ) ) ), @@ -423,8 +426,8 @@ namespace ts { ) ]) ), - createExpressionStatement( - createCall( + factory.createExpressionStatement( + factory.createCallExpression( exportFunction, /*typeArguments*/ undefined, [exports] @@ -444,11 +447,11 @@ namespace ts { const setters: Expression[] = []; for (const group of dependencyGroups) { // derive a unique name for parameter from the first named entry in the group - const localName = forEach(group.externalImports, i => getLocalNameForExternalImport(i, currentSourceFile)); - const parameterName = localName ? getGeneratedNameForNode(localName) : createUniqueName(""); + const localName = forEach(group.externalImports, i => getLocalNameForExternalImport(factory, i, currentSourceFile)); + const parameterName = localName ? factory.getGeneratedNameForNode(localName) : factory.createUniqueName(""); const statements: Statement[] = []; for (const entry of group.externalImports) { - const importVariableName = getLocalNameForExternalImport(entry, currentSourceFile)!; // TODO: GH#18217 + const importVariableName = getLocalNameForExternalImport(factory, entry, currentSourceFile)!; // TODO: GH#18217 switch (entry.kind) { case SyntaxKind.ImportDeclaration: if (!entry.importClause) { @@ -462,8 +465,8 @@ namespace ts { Debug.assert(importVariableName !== undefined); // save import into the local statements.push( - createExpressionStatement( - createAssignment(importVariableName, parameterName) + factory.createExpressionStatement( + factory.createAssignment(importVariableName, parameterName) ) ); break; @@ -483,34 +486,34 @@ namespace ts { const properties: PropertyAssignment[] = []; for (const e of entry.exportClause.elements) { properties.push( - createPropertyAssignment( - createLiteral(idText(e.name)), - createElementAccess( + factory.createPropertyAssignment( + factory.createStringLiteral(idText(e.name)), + factory.createElementAccessExpression( parameterName, - createLiteral(idText(e.propertyName || e.name)) + factory.createStringLiteral(idText(e.propertyName || e.name)) ) ) ); } statements.push( - createExpressionStatement( - createCall( + factory.createExpressionStatement( + factory.createCallExpression( exportFunction, /*typeArguments*/ undefined, - [createObjectLiteral(properties, /*multiline*/ true)] + [factory.createObjectLiteralExpression(properties, /*multiline*/ true)] ) ) ); } else { statements.push( - createExpressionStatement( - createCall( + factory.createExpressionStatement( + factory.createCallExpression( exportFunction, /*typeArguments*/ undefined, [ - createLiteral(idText(entry.exportClause.name)), + factory.createStringLiteral(idText(entry.exportClause.name)), parameterName ] ) @@ -525,8 +528,8 @@ namespace ts { // // exportStar(foo_1_1); statements.push( - createExpressionStatement( - createCall( + factory.createExpressionStatement( + factory.createCallExpression( exportStarFunction, /*typeArguments*/ undefined, [parameterName] @@ -539,19 +542,19 @@ namespace ts { } setters.push( - createFunctionExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], + [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], /*type*/ undefined, - createBlock(statements, /*multiLine*/ true) + factory.createBlock(statements, /*multiLine*/ true) ) ); } - return createArrayLiteral(setters, /*multiLine*/ true); + return factory.createArrayLiteralExpression(setters, /*multiLine*/ true); } // @@ -590,7 +593,7 @@ namespace ts { function visitImportDeclaration(node: ImportDeclaration): VisitResult { let statements: Statement[] | undefined; if (node.importClause) { - hoistVariableDeclaration(getLocalNameForExternalImport(node, currentSourceFile)!); // TODO: GH#18217 + hoistVariableDeclaration(getLocalNameForExternalImport(factory, node, currentSourceFile)!); // TODO: GH#18217 } if (hasAssociatedEndOfDeclarationMarker(node)) { @@ -619,7 +622,7 @@ namespace ts { Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); let statements: Statement[] | undefined; - hoistVariableDeclaration(getLocalNameForExternalImport(node, currentSourceFile)!); // TODO: GH#18217 + hoistVariableDeclaration(getLocalNameForExternalImport(factory, node, currentSourceFile)!); // TODO: GH#18217 if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node @@ -649,10 +652,10 @@ namespace ts { if (original && hasAssociatedEndOfDeclarationMarker(original)) { // Defer exports until we encounter an EndOfDeclarationMarker node const id = getOriginalNodeId(node); - deferredExports[id] = appendExportStatement(deferredExports[id], createIdentifier("default"), expression, /*allowComments*/ true); + deferredExports[id] = appendExportStatement(deferredExports[id], factory.createIdentifier("default"), expression, /*allowComments*/ true); } else { - return createExportStatement(createIdentifier("default"), expression, /*allowComments*/ true); + return createExportStatement(factory.createIdentifier("default"), expression, /*allowComments*/ true); } } @@ -664,12 +667,12 @@ namespace ts { function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { if (hasSyntacticModifier(node, ModifierFlags.Export)) { hoistedStatements = append(hoistedStatements, - updateFunctionDeclaration( + factory.updateFunctionDeclaration( node, node.decorators, visitNodes(node.modifiers, modifierVisitor, isModifier), node.asteriskToken, - getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), + factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, visitNodes(node.parameters, destructuringAndImportCallVisitor, isParameterDeclaration), /*type*/ undefined, @@ -700,17 +703,18 @@ namespace ts { let statements: Statement[] | undefined; // Hoist the name of the class declaration to the outer module body function. - const name = getLocalName(node); + const name = factory.getLocalName(node); hoistVariableDeclaration(name); // Rewrite the class declaration into an assignment of a class expression. statements = append(statements, setTextRange( - createExpressionStatement( - createAssignment( + factory.createExpressionStatement( + factory.createAssignment( name, setTextRange( - createClassExpression( + factory.createClassExpression( + visitNodes(node.decorators, destructuringAndImportCallVisitor, isDecorator), /*modifiers*/ undefined, node.name, /*typeParameters*/ undefined, @@ -762,7 +766,7 @@ namespace ts { let statements: Statement[] | undefined; if (expressions) { - statements = append(statements, setTextRange(createExpressionStatement(inlineExpressions(expressions)), node)); + statements = append(statements, setTextRange(factory.createExpressionStatement(factory.inlineExpressions(expressions)), node)); } if (isMarkedDeclaration) { @@ -791,7 +795,7 @@ namespace ts { } } else { - hoistVariableDeclaration(getSynthesizedClone(node.name)); + hoistVariableDeclaration(factory.cloneNode(node.name)); } } @@ -858,10 +862,10 @@ namespace ts { * @param isExportedDeclaration A value indicating whether the variable is exported. */ function createVariableAssignment(name: Identifier, value: Expression, location: TextRange | undefined, isExportedDeclaration: boolean) { - hoistVariableDeclaration(getSynthesizedClone(name)); + hoistVariableDeclaration(factory.cloneNode(name)); return isExportedDeclaration - ? createExportExpression(name, preventSubstitution(setTextRange(createAssignment(name, value), location))) - : preventSubstitution(setTextRange(createAssignment(name, value), location)); + ? createExportExpression(name, preventSubstitution(setTextRange(factory.createAssignment(name, value), location))) + : preventSubstitution(setTextRange(factory.createAssignment(name, value), location)); } /** @@ -1031,7 +1035,7 @@ namespace ts { else if (!isGeneratedIdentifier(decl.name)) { let excludeName: string | undefined; if (exportSelf) { - statements = appendExportStatement(statements, decl.name, getLocalName(decl)); + statements = appendExportStatement(statements, decl.name, factory.getLocalName(decl)); excludeName = idText(decl.name); } @@ -1057,8 +1061,8 @@ namespace ts { let excludeName: string | undefined; if (hasSyntacticModifier(decl, ModifierFlags.Export)) { - const exportName = hasSyntacticModifier(decl, ModifierFlags.Default) ? createLiteral("default") : decl.name!; - statements = appendExportStatement(statements, exportName, getLocalName(decl)); + const exportName = hasSyntacticModifier(decl, ModifierFlags.Default) ? factory.createStringLiteral("default") : decl.name!; + statements = appendExportStatement(statements, exportName, factory.getLocalName(decl)); excludeName = getTextOfIdentifierOrLiteral(exportName); } @@ -1083,7 +1087,7 @@ namespace ts { return statements; } - const name = getDeclarationName(decl); + const name = factory.getDeclarationName(decl); const exportSpecifiers = moduleInfo.exportSpecifiers.get(idText(name)); if (exportSpecifiers) { for (const exportSpecifier of exportSpecifiers) { @@ -1119,7 +1123,7 @@ namespace ts { * @param allowComments An optional value indicating whether to emit comments for the statement. */ function createExportStatement(name: Identifier | StringLiteral, value: Expression, allowComments?: boolean) { - const statement = createExpressionStatement(createExportExpression(name, value)); + const statement = factory.createExpressionStatement(createExportExpression(name, value)); startOnNewLine(statement); if (!allowComments) { setEmitFlags(statement, EmitFlags.NoComments); @@ -1135,9 +1139,9 @@ namespace ts { * @param value The exported value. */ function createExportExpression(name: Identifier | StringLiteral, value: Expression) { - const exportName = isIdentifier(name) ? createLiteral(name) : name; + const exportName = isIdentifier(name) ? factory.createStringLiteralFromNode(name) : name; setEmitFlags(value, getEmitFlags(value) | EmitFlags.NoComments); - return setCommentRange(createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value); + return setCommentRange(factory.createCallExpression(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value); } // @@ -1222,7 +1226,7 @@ namespace ts { const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; - node = updateFor( + node = factory.updateForStatement( node, node.initializer && visitForInitializer(node.initializer), visitNode(node.condition, destructuringAndImportCallVisitor, isExpression), @@ -1243,11 +1247,11 @@ namespace ts { const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; - node = updateForIn( + node = factory.updateForInStatement( node, visitForInitializer(node.initializer), visitNode(node.expression, destructuringAndImportCallVisitor, isExpression), - visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock) + visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock) ); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; @@ -1263,12 +1267,12 @@ namespace ts { const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; - node = updateForOf( + node = factory.updateForOfStatement( node, node.awaitModifier, visitForInitializer(node.initializer), visitNode(node.expression, destructuringAndImportCallVisitor, isExpression), - visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock) + visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock) ); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; @@ -1301,7 +1305,7 @@ namespace ts { } } - return expressions ? inlineExpressions(expressions) : createOmittedExpression(); + return expressions ? factory.inlineExpressions(expressions) : factory.createOmittedExpression(); } else { return visitEachChild(node, nestedElementVisitor, context); @@ -1314,9 +1318,9 @@ namespace ts { * @param node The node to visit. */ function visitDoStatement(node: DoStatement): VisitResult { - return updateDo( + return factory.updateDoStatement( node, - visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock), + visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock), visitNode(node.expression, destructuringAndImportCallVisitor, isExpression) ); } @@ -1327,10 +1331,10 @@ namespace ts { * @param node The node to visit. */ function visitWhileStatement(node: WhileStatement): VisitResult { - return updateWhile( + return factory.updateWhileStatement( node, visitNode(node.expression, destructuringAndImportCallVisitor, isExpression), - visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock) + visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock) ); } @@ -1340,10 +1344,10 @@ namespace ts { * @param node The node to visit. */ function visitLabeledStatement(node: LabeledStatement): VisitResult { - return updateLabel( + return factory.updateLabeledStatement( node, node.label, - visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock) + visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock) ); } @@ -1353,10 +1357,10 @@ namespace ts { * @param node The node to visit. */ function visitWithStatement(node: WithStatement): VisitResult { - return updateWith( + return factory.updateWithStatement( node, visitNode(node.expression, destructuringAndImportCallVisitor, isExpression), - visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock) + visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock) ); } @@ -1366,7 +1370,7 @@ namespace ts { * @param node The node to visit. */ function visitSwitchStatement(node: SwitchStatement): VisitResult { - return updateSwitch( + return factory.updateSwitchStatement( node, visitNode(node.expression, destructuringAndImportCallVisitor, isExpression), visitNode(node.caseBlock, nestedElementVisitor, isCaseBlock) @@ -1382,7 +1386,7 @@ namespace ts { const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; - node = updateCaseBlock( + node = factory.updateCaseBlock( node, visitNodes(node.clauses, nestedElementVisitor, isCaseOrDefaultClause) ); @@ -1397,7 +1401,7 @@ namespace ts { * @param node The node to visit. */ function visitCaseClause(node: CaseClause): VisitResult { - return updateCaseClause( + return factory.updateCaseClause( node, visitNode(node.expression, destructuringAndImportCallVisitor, isExpression), visitNodes(node.statements, nestedElementVisitor, isStatement) @@ -1431,7 +1435,7 @@ namespace ts { const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; - node = updateCatchClause( + node = factory.updateCatchClause( node, node.variableDeclaration, visitNode(node.block, nestedElementVisitor, isBlock) @@ -1491,10 +1495,10 @@ namespace ts { // } // }; // }); - return createCall( - createPropertyAccess( + return factory.createCallExpression( + factory.createPropertyAccessExpression( contextObject, - createIdentifier("import") + factory.createIdentifier("import") ), /*typeArguments*/ undefined, some(node.arguments) ? [visitNode(node.arguments[0], destructuringAndImportCallVisitor)] : [] @@ -1659,11 +1663,11 @@ namespace ts { if (importDeclaration) { if (isImportClause(importDeclaration)) { return setTextRange( - createPropertyAssignment( - getSynthesizedClone(name), - createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent), - createIdentifier("default") + factory.createPropertyAssignment( + factory.cloneNode(name), + factory.createPropertyAccessExpression( + factory.getGeneratedNameForNode(importDeclaration.parent), + factory.createIdentifier("default") ) ), /*location*/ node @@ -1671,11 +1675,11 @@ namespace ts { } else if (isImportSpecifier(importDeclaration)) { return setTextRange( - createPropertyAssignment( - getSynthesizedClone(name), - createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent.parent.parent), - getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name) + factory.createPropertyAssignment( + factory.cloneNode(name), + factory.createPropertyAccessExpression( + factory.getGeneratedNameForNode(importDeclaration.parent.parent.parent), + factory.cloneNode(importDeclaration.propertyName || importDeclaration.name) ), ), /*location*/ node @@ -1716,7 +1720,7 @@ namespace ts { if (getEmitFlags(node) & EmitFlags.HelperName) { const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile); if (externalHelpersModuleName) { - return createPropertyAccess(externalHelpersModuleName, node); + return factory.createPropertyAccessExpression(externalHelpersModuleName, node); } return node; @@ -1733,18 +1737,18 @@ namespace ts { if (importDeclaration) { if (isImportClause(importDeclaration)) { return setTextRange( - createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent), - createIdentifier("default") + factory.createPropertyAccessExpression( + factory.getGeneratedNameForNode(importDeclaration.parent), + factory.createIdentifier("default") ), /*location*/ node ); } else if (isImportSpecifier(importDeclaration)) { return setTextRange( - createPropertyAccess( - getGeneratedNameForNode(importDeclaration.parent.parent.parent), - getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name) + factory.createPropertyAccessExpression( + factory.getGeneratedNameForNode(importDeclaration.parent.parent.parent), + factory.cloneNode(importDeclaration.propertyName || importDeclaration.name) ), /*location*/ node ); @@ -1813,7 +1817,7 @@ namespace ts { if (exportedNames) { let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression ? setTextRange( - createPrefix( + factory.createPrefixUnaryExpression( node.operator, node.operand ), @@ -1827,8 +1831,8 @@ namespace ts { if (node.kind === SyntaxKind.PostfixUnaryExpression) { expression = node.operator === SyntaxKind.PlusPlusToken - ? createSubtract(preventSubstitution(expression), createLiteral(1)) - : createAdd(preventSubstitution(expression), createLiteral(1)); + ? factory.createSubtract(preventSubstitution(expression), factory.createNumericLiteral(1)) + : factory.createAdd(preventSubstitution(expression), factory.createNumericLiteral(1)); } return expression; @@ -1840,7 +1844,7 @@ namespace ts { function substituteMetaProperty(node: MetaProperty) { if (isImportMeta(node)) { - return createPropertyAccess(contextObject, createIdentifier("meta")); + return factory.createPropertyAccessExpression(contextObject, factory.createIdentifier("meta")); } return node; } @@ -1859,7 +1863,7 @@ namespace ts { if (valueDeclaration) { const exportContainer = resolver.getReferencedExportContainer(name, /*prefixLocals*/ false); if (exportContainer && exportContainer.kind === SyntaxKind.SourceFile) { - exportedNames = append(exportedNames, getDeclarationName(valueDeclaration)); + exportedNames = append(exportedNames, factory.getDeclarationName(valueDeclaration)); } exportedNames = addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[getOriginalNodeId(valueDeclaration)]); diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts index db2aa0d9df6f0..c3b3231916ab1 100644 --- a/src/compiler/transformers/taggedTemplate.ts +++ b/src/compiler/transformers/taggedTemplate.ts @@ -42,17 +42,19 @@ namespace ts { } } - const helperCall = createTemplateObjectHelper(context, createArrayLiteral(cookedStrings), createArrayLiteral(rawStrings)); + const helperCall = context.getEmitHelperFactory().createTemplateObjectHelper( + factory.createArrayLiteralExpression(cookedStrings), + factory.createArrayLiteralExpression(rawStrings)); // Create a variable to cache the template object if we're in a module. // Do not do this in the global scope, as any variable we currently generate could conflict with // variables from outside of the current compilation. In the future, we can revisit this behavior. if (isExternalModule(currentSourceFile)) { - const tempVar = createUniqueName("templateObject"); + const tempVar = factory.createUniqueName("templateObject"); recordTaggedTemplateString(tempVar); - templateArguments[0] = createLogicalOr( + templateArguments[0] = factory.createLogicalOr( tempVar, - createAssignment( + factory.createAssignment( tempVar, helperCall) ); @@ -61,11 +63,11 @@ namespace ts { templateArguments[0] = helperCall; } - return createCall(tag, /*typeArguments*/ undefined, templateArguments); + return factory.createCallExpression(tag, /*typeArguments*/ undefined, templateArguments); } function createTemplateCooked(template: TemplateHead | TemplateMiddle | TemplateTail | NoSubstitutionTemplateLiteral) { - return template.templateFlags ? createVoidZero() : createLiteral(template.text); + return template.templateFlags ? factory.createVoidZero() : factory.createStringLiteral(template.text); } /** @@ -93,30 +95,6 @@ namespace ts { // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's // and LineTerminatorSequences are normalized to for both TV and TRV. text = text.replace(/\r\n?/g, "\n"); - return setTextRange(createLiteral(text), node); + return setTextRange(factory.createStringLiteral(text), node); } - - function createTemplateObjectHelper(context: TransformationContext, cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression) { - context.requestEmitHelper(templateObjectHelper); - return createCall( - getUnscopedHelperName("__makeTemplateObject"), - /*typeArguments*/ undefined, - [ - cooked, - raw - ] - ); - } - - export const templateObjectHelper: UnscopedEmitHelper = { - name: "typescript:makeTemplateObject", - importName: "__makeTemplateObject", - scoped: false, - priority: 0, - text: ` - var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { - if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } - return cooked; - };` - }; } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 1e70dcc0d9f72..1eb4ddb777928 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -33,6 +33,8 @@ namespace ts { export function transformTypeScript(context: TransformationContext) { const { + factory, + getEmitHelperFactory: emitHelpers, startLexicalEnvironment, resumeLexicalEnvironment, endLexicalEnvironment, @@ -94,7 +96,7 @@ namespace ts { } function transformBundle(node: Bundle) { - return createBundle(node.sourceFiles.map(transformSourceFile), mapDefined(node.prepends, prepend => { + return factory.createBundle(node.sourceFiles.map(transformSourceFile), mapDefined(node.prepends, prepend => { if (prepend.kind === SyntaxKind.InputFiles) { return createUnparsedSourceFile(prepend, "js"); } @@ -231,13 +233,13 @@ namespace ts { case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.ExportAssignment: case SyntaxKind.ExportDeclaration: - return visitEllidableStatement(node); + return visitElidableStatement(node); default: return visitorWorker(node); } } - function visitEllidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult { + function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult { const parsed = getParseTreeNode(node); if (parsed !== node) { // If the node has been transformed by a `before` transformer, perform no ellision on it @@ -353,7 +355,7 @@ namespace ts { if (isStatement(node) && hasSyntacticModifier(node, ModifierFlags.Ambient)) { // TypeScript ambient declarations are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); } switch (node.kind) { @@ -428,7 +430,7 @@ namespace ts { case SyntaxKind.InterfaceDeclaration: // TypeScript interfaces are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); case SyntaxKind.ClassDeclaration: // This may be a class declaration with TypeScript syntax extensions. @@ -558,7 +560,7 @@ namespace ts { !(isExternalModule(node) && moduleKind >= ModuleKind.ES2015) && !isJsonSourceFile(node); - return updateSourceFileNode( + return factory.updateSourceFile( node, visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict)); } @@ -623,7 +625,7 @@ namespace ts { context.startLexicalEnvironment(); } - const name = node.name || (facts & ClassFacts.NeedsName ? getGeneratedNameForNode(node) : undefined); + const name = node.name || (facts & ClassFacts.NeedsName ? factory.getGeneratedNameForNode(node) : undefined); const classStatement = facts & ClassFacts.HasConstructorDecorators ? createClassDeclarationHeadWithDecorators(node, name) : createClassDeclarationHeadWithoutDecorators(node, name, facts); @@ -649,29 +651,30 @@ namespace ts { // }(); // const closingBraceLocation = createTokenRange(skipTrivia(currentSourceFile.text, node.members.end), SyntaxKind.CloseBraceToken); - const localName = getInternalName(node); + const localName = factory.getInternalName(node); // The following partially-emitted expression exists purely to align our sourcemap // emit with the original emitter. - const outer = createPartiallyEmittedExpression(localName); - outer.end = closingBraceLocation.end; + const outer = factory.createPartiallyEmittedExpression(localName); + setTextRangeEnd(outer, closingBraceLocation.end); setEmitFlags(outer, EmitFlags.NoComments); - const statement = createReturn(outer); - statement.pos = closingBraceLocation.pos; + const statement = factory.createReturnStatement(outer); + setTextRangePos(statement, closingBraceLocation.pos); setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps); statements.push(statement); insertStatementsAfterStandardPrologue(statements, context.endLexicalEnvironment()); - const iife = createImmediatelyInvokedArrowFunction(statements); + const iife = factory.createImmediatelyInvokedArrowFunction(statements); setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper); - const varStatement = createVariableStatement( + const varStatement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), + /*exclamationToken*/ undefined, /*type*/ undefined, iife ) @@ -693,16 +696,16 @@ namespace ts { } else if (facts & ClassFacts.UseImmediatelyInvokedFunctionExpression || facts & ClassFacts.HasConstructorDecorators) { if (facts & ClassFacts.IsDefaultExternalExport) { - statements.push(createExportDefault(getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))); + statements.push(factory.createExportDefault(factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))); } else if (facts & ClassFacts.IsNamedExternalExport) { - statements.push(createExternalModuleExport(getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))); + statements.push(factory.createExternalModuleExport(factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))); } } if (statements.length > 1) { // Add a DeclarationMarker as a marker for the end of the declaration - statements.push(createEndOfDeclarationMarker(node)); + statements.push(factory.createEndOfDeclarationMarker(node)); setEmitFlags(classStatement, getEmitFlags(classStatement) | EmitFlags.HasEndOfDeclarationMarker); } @@ -726,7 +729,7 @@ namespace ts { ? visitNodes(node.modifiers, modifierVisitor, isModifier) : undefined; - const classDeclaration = createClassDeclaration( + const classDeclaration = factory.createClassDeclaration( /*decorators*/ undefined, modifiers, name, @@ -742,7 +745,6 @@ namespace ts { emitFlags |= EmitFlags.NoTrailingSourceMap; } - aggregateTransformFlags(classDeclaration); setTextRange(classDeclaration, node); setOriginalNode(classDeclaration, node); setEmitFlags(classDeclaration, emitFlags); @@ -842,27 +844,27 @@ namespace ts { const location = moveRangePastDecorators(node); const classAlias = getClassAliasIfNeeded(node); - const declName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); + const declName = factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // ... = class ${name} ${heritageClauses} { // ${members} // } const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause); const members = transformClassMembers(node); - const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members); - aggregateTransformFlags(classExpression); + const classExpression = factory.createClassExpression(/*decorators*/ undefined, /*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members); setOriginalNode(classExpression, node); setTextRange(classExpression, location); // let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference // or decoratedClassAlias if the class contain self-reference. - const statement = createVariableStatement( + const statement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( declName, + /*exclamationToken*/ undefined, /*type*/ undefined, - classAlias ? createAssignment(classAlias, classExpression) : classExpression + classAlias ? factory.createAssignment(classAlias, classExpression) : classExpression ) ], NodeFlags.Let) ); @@ -877,7 +879,8 @@ namespace ts { return visitEachChild(node, visitor, context); } - const classExpression = createClassExpression( + const classExpression = factory.createClassExpression( + /*decorators*/ undefined, /*modifiers*/ undefined, node.name, /*typeParameters*/ undefined, @@ -885,7 +888,6 @@ namespace ts { transformClassMembers(node) ); - aggregateTransformFlags(classExpression); setOriginalNode(classExpression, node); setTextRange(classExpression, node); @@ -906,19 +908,19 @@ namespace ts { if (parametersWithPropertyAssignments) { for (const parameter of parametersWithPropertyAssignments) { if (isIdentifier(parameter.name)) { - members.push(setOriginalNode(aggregateTransformFlags(createProperty( + members.push(setOriginalNode(factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, parameter.name, /*questionOrExclamationToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined)), parameter)); + /*initializer*/ undefined), parameter)); } } } addRange(members, visitNodes(node.members, classElementVisitor, isClassElement)); - return setTextRange(createNodeArray(members), /*location*/ node.members); + return setTextRange(factory.createNodeArray(members), /*location*/ node.members); } @@ -1208,22 +1210,21 @@ namespace ts { ? member.kind === SyntaxKind.PropertyDeclaration // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it // should not invoke `Object.getOwnPropertyDescriptor`. - ? createVoidZero() + ? factory.createVoidZero() // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly. // We have this extra argument here so that we can inject an explicit property descriptor at a later date. - : createNull() + : factory.createNull() : undefined; - const helper = createDecorateHelper( - context, + const helper = emitHelpers().createDecorateHelper( decoratorExpressions, prefix, memberName, - descriptor, - moveRangePastDecorators(member) + descriptor ); + setTextRange(helper, moveRangePastDecorators(member)); setEmitFlags(helper, EmitFlags.NoComments); return helper; } @@ -1236,7 +1237,7 @@ namespace ts { function addConstructorDecorationStatement(statements: Statement[], node: ClassDeclaration) { const expression = generateConstructorDecorationExpression(node); if (expression) { - statements.push(setOriginalNode(createExpressionStatement(expression), node)); + statements.push(setOriginalNode(factory.createExpressionStatement(expression), node)); } } @@ -1253,9 +1254,9 @@ namespace ts { } const classAlias = classAliases && classAliases[getOriginalNodeId(node)]; - const localName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); - const decorate = createDecorateHelper(context, decoratorExpressions, localName); - const expression = createAssignment(localName, classAlias ? createAssignment(classAlias, decorate) : decorate); + const localName = factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); + const decorate = emitHelpers().createDecorateHelper(decoratorExpressions, localName); + const expression = factory.createAssignment(localName, classAlias ? factory.createAssignment(classAlias, decorate) : decorate); setEmitFlags(expression, EmitFlags.NoComments); setSourceMapRange(expression, moveRangePastDecorators(node)); return expression; @@ -1281,11 +1282,10 @@ namespace ts { if (decorators) { expressions = []; for (const decorator of decorators) { - const helper = createParamHelper( - context, + const helper = emitHelpers().createParamHelper( transformDecorator(decorator), - parameterOffset, - /*location*/ decorator.expression); + parameterOffset); + setTextRange(helper, decorator.expression); setEmitFlags(helper, EmitFlags.NoComments); expressions.push(helper); } @@ -1312,13 +1312,13 @@ namespace ts { function addOldTypeMetadata(node: Declaration, container: ClassLikeDeclaration, decoratorExpressions: Expression[]) { if (compilerOptions.emitDecoratorMetadata) { if (shouldAddTypeMetadata(node)) { - decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node))); + decoratorExpressions.push(emitHelpers().createMetadataHelper("design:type", serializeTypeOfNode(node))); } if (shouldAddParamTypesMetadata(node)) { - decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node, container))); + decoratorExpressions.push(emitHelpers().createMetadataHelper("design:paramtypes", serializeParameterTypesOfNode(node, container))); } if (shouldAddReturnTypeMetadata(node)) { - decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node))); + decoratorExpressions.push(emitHelpers().createMetadataHelper("design:returntype", serializeReturnTypeOfNode(node))); } } } @@ -1327,16 +1327,16 @@ namespace ts { if (compilerOptions.emitDecoratorMetadata) { let properties: ObjectLiteralElementLike[] | undefined; if (shouldAddTypeMetadata(node)) { - (properties || (properties = [])).push(createPropertyAssignment("type", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeTypeOfNode(node)))); + (properties || (properties = [])).push(factory.createPropertyAssignment("type", factory.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, factory.createToken(SyntaxKind.EqualsGreaterThanToken), serializeTypeOfNode(node)))); } if (shouldAddParamTypesMetadata(node)) { - (properties || (properties = [])).push(createPropertyAssignment("paramTypes", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeParameterTypesOfNode(node, container)))); + (properties || (properties = [])).push(factory.createPropertyAssignment("paramTypes", factory.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, factory.createToken(SyntaxKind.EqualsGreaterThanToken), serializeParameterTypesOfNode(node, container)))); } if (shouldAddReturnTypeMetadata(node)) { - (properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeReturnTypeOfNode(node)))); + (properties || (properties = [])).push(factory.createPropertyAssignment("returnType", factory.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, factory.createToken(SyntaxKind.EqualsGreaterThanToken), serializeReturnTypeOfNode(node)))); } if (properties) { - decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", createObjectLiteral(properties, /*multiLine*/ true))); + decoratorExpressions.push(emitHelpers().createMetadataHelper("design:typeinfo", factory.createObjectLiteralExpression(properties, /*multiLine*/ true))); } } } @@ -1412,9 +1412,9 @@ namespace ts { case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: case SyntaxKind.MethodDeclaration: - return createIdentifier("Function"); + return factory.createIdentifier("Function"); default: - return createVoidZero(); + return factory.createVoidZero(); } } @@ -1449,7 +1449,7 @@ namespace ts { } } - return createArrayLiteral(expressions); + return factory.createArrayLiteralExpression(expressions); } function getParametersOfDecoratedDeclaration(node: SignatureDeclaration, container: ClassLikeDeclaration) { @@ -1472,10 +1472,10 @@ namespace ts { return serializeTypeNode(node.type); } else if (isAsyncFunction(node)) { - return createIdentifier("Promise"); + return factory.createIdentifier("Promise"); } - return createVoidZero(); + return factory.createVoidZero(); } /** @@ -1498,59 +1498,61 @@ namespace ts { */ function serializeTypeNode(node: TypeNode | undefined): SerializedTypeNode { if (node === undefined) { - return createIdentifier("Object"); + return factory.createIdentifier("Object"); } switch (node.kind) { case SyntaxKind.VoidKeyword: case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NullKeyword: case SyntaxKind.NeverKeyword: - return createVoidZero(); + return factory.createVoidZero(); case SyntaxKind.ParenthesizedType: return serializeTypeNode((node).type); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: - return createIdentifier("Function"); + return factory.createIdentifier("Function"); case SyntaxKind.ArrayType: case SyntaxKind.TupleType: - return createIdentifier("Array"); + return factory.createIdentifier("Array"); case SyntaxKind.TypePredicate: case SyntaxKind.BooleanKeyword: - return createIdentifier("Boolean"); + return factory.createIdentifier("Boolean"); case SyntaxKind.StringKeyword: - return createIdentifier("String"); + return factory.createIdentifier("String"); case SyntaxKind.ObjectKeyword: - return createIdentifier("Object"); + return factory.createIdentifier("Object"); case SyntaxKind.LiteralType: switch ((node).literal.kind) { case SyntaxKind.StringLiteral: - return createIdentifier("String"); + return factory.createIdentifier("String"); case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.NumericLiteral: - return createIdentifier("Number"); + return factory.createIdentifier("Number"); case SyntaxKind.BigIntLiteral: return getGlobalBigIntNameWithFallback(); case SyntaxKind.TrueKeyword: case SyntaxKind.FalseKeyword: - return createIdentifier("Boolean"); + return factory.createIdentifier("Boolean"); + + case SyntaxKind.NullKeyword: + return factory.createVoidZero(); default: return Debug.failBadSyntaxKind((node).literal); } case SyntaxKind.NumberKeyword: - return createIdentifier("Number"); + return factory.createIdentifier("Number"); case SyntaxKind.BigIntKeyword: return getGlobalBigIntNameWithFallback(); @@ -1558,7 +1560,7 @@ namespace ts { case SyntaxKind.SymbolKeyword: return languageVersion < ScriptTarget.ES2015 ? getGlobalSymbolNameWithFallback() - : createIdentifier("Symbol"); + : factory.createIdentifier("Symbol"); case SyntaxKind.TypeReference: return serializeTypeReferenceNode(node); @@ -1598,12 +1600,11 @@ namespace ts { case SyntaxKind.JSDocNonNullableType: case SyntaxKind.JSDocOptionalType: return serializeTypeNode((node).type); - default: return Debug.failBadSyntaxKind(node); } - return createIdentifier("Object"); + return factory.createIdentifier("Object"); } function serializeTypeList(types: readonly TypeNode[]): SerializedTypeNode { @@ -1617,7 +1618,7 @@ namespace ts { if (typeNode.kind === SyntaxKind.NeverKeyword) { continue; // Always elide `never` from the union/intersection if possible } - if (!strictNullChecks && (typeNode.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) { + if (!strictNullChecks && (typeNode.kind === SyntaxKind.LiteralType && (typeNode as LiteralTypeNode).literal.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) { continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks } const serializedIndividual = serializeTypeNode(typeNode); @@ -1633,7 +1634,7 @@ namespace ts { if (!isIdentifier(serializedUnion) || !isIdentifier(serializedIndividual) || serializedUnion.escapedText !== serializedIndividual.escapedText) { - return createIdentifier("Object"); + return factory.createIdentifier("Object"); } } else { @@ -1643,7 +1644,7 @@ namespace ts { } // If we were able to find common type, use it - return serializedUnion || createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never + return serializedUnion || factory.createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never } /** @@ -1658,59 +1659,61 @@ namespace ts { case TypeReferenceSerializationKind.Unknown: // From conditional type type reference that cannot be resolved is Similar to any or unknown if (findAncestor(node, n => n.parent && isConditionalTypeNode(n.parent) && (n.parent.trueType === n || n.parent.falseType === n))) { - return createIdentifier("Object"); + return factory.createIdentifier("Object"); } const serialized = serializeEntityNameAsExpressionFallback(node.typeName); - const temp = createTempVariable(hoistVariableDeclaration); - return createConditional( - createTypeCheck(createAssignment(temp, serialized), "function"), + const temp = factory.createTempVariable(hoistVariableDeclaration); + return factory.createConditionalExpression( + factory.createTypeCheck(factory.createAssignment(temp, serialized), "function"), + /*questionToken*/ undefined, temp, - createIdentifier("Object") + /*colonToken*/ undefined, + factory.createIdentifier("Object") ); case TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue: return serializeEntityNameAsExpression(node.typeName); case TypeReferenceSerializationKind.VoidNullableOrNeverType: - return createVoidZero(); + return factory.createVoidZero(); case TypeReferenceSerializationKind.BigIntLikeType: return getGlobalBigIntNameWithFallback(); case TypeReferenceSerializationKind.BooleanType: - return createIdentifier("Boolean"); + return factory.createIdentifier("Boolean"); case TypeReferenceSerializationKind.NumberLikeType: - return createIdentifier("Number"); + return factory.createIdentifier("Number"); case TypeReferenceSerializationKind.StringLikeType: - return createIdentifier("String"); + return factory.createIdentifier("String"); case TypeReferenceSerializationKind.ArrayLikeType: - return createIdentifier("Array"); + return factory.createIdentifier("Array"); case TypeReferenceSerializationKind.ESSymbolType: return languageVersion < ScriptTarget.ES2015 ? getGlobalSymbolNameWithFallback() - : createIdentifier("Symbol"); + : factory.createIdentifier("Symbol"); case TypeReferenceSerializationKind.TypeWithCallSignature: - return createIdentifier("Function"); + return factory.createIdentifier("Function"); case TypeReferenceSerializationKind.Promise: - return createIdentifier("Promise"); + return factory.createIdentifier("Promise"); case TypeReferenceSerializationKind.ObjectType: - return createIdentifier("Object"); + return factory.createIdentifier("Object"); default: return Debug.assertNever(kind); } } function createCheckedValue(left: Expression, right: Expression) { - return createLogicalAnd( - createStrictInequality(createTypeOf(left), createLiteral("undefined")), + return factory.createLogicalAnd( + factory.createStrictInequality(factory.createTypeOfExpression(left), factory.createStringLiteral("undefined")), right ); } @@ -1732,13 +1735,13 @@ namespace ts { } // A.B.C -> typeof A !== undefined && (_a = A.B) !== void 0 && _a.C const left = serializeEntityNameAsExpressionFallback(node.left); - const temp = createTempVariable(hoistVariableDeclaration); - return createLogicalAnd( - createLogicalAnd( + const temp = factory.createTempVariable(hoistVariableDeclaration); + return factory.createLogicalAnd( + factory.createLogicalAnd( left.left, - createStrictInequality(createAssignment(temp, left.right), createVoidZero()) + factory.createStrictInequality(factory.createAssignment(temp, left.right), factory.createVoidZero()) ), - createPropertyAccess(temp, node.right) + factory.createPropertyAccessExpression(temp, node.right) ); } @@ -1752,11 +1755,9 @@ namespace ts { case SyntaxKind.Identifier: // Create a clone of the name with a new parent, and treat it as if it were // a source tree node for the purposes of the checker. - const name = getMutableClone(node); - name.flags &= ~NodeFlags.Synthesized; + const name = setParent(setTextRange(parseNodeFactory.cloneNode(node), node), node.parent); name.original = undefined; - name.parent = getParseTreeNode(currentLexicalScope); // ensure the parent is set to a parse tree node. - + setParent(name, getParseTreeNode(currentLexicalScope)); // ensure the parent is set to a parse tree node. return name; case SyntaxKind.QualifiedName: @@ -1772,7 +1773,7 @@ namespace ts { * qualified name at runtime. */ function serializeQualifiedNameAsExpression(node: QualifiedName): SerializedEntityNameAsExpression { - return createPropertyAccess(serializeEntityNameAsExpression(node.left), node.right); + return factory.createPropertyAccessExpression(serializeEntityNameAsExpression(node.left), node.right); } /** @@ -1780,10 +1781,12 @@ namespace ts { * available. */ function getGlobalSymbolNameWithFallback(): ConditionalExpression { - return createConditional( - createTypeCheck(createIdentifier("Symbol"), "function"), - createIdentifier("Symbol"), - createIdentifier("Object") + return factory.createConditionalExpression( + factory.createTypeCheck(factory.createIdentifier("Symbol"), "function"), + /*questionToken*/ undefined, + factory.createIdentifier("Symbol"), + /*colonToken*/ undefined, + factory.createIdentifier("Object") ); } @@ -1793,12 +1796,14 @@ namespace ts { */ function getGlobalBigIntNameWithFallback(): SerializedTypeNode { return languageVersion < ScriptTarget.ESNext - ? createConditional( - createTypeCheck(createIdentifier("BigInt"), "function"), - createIdentifier("BigInt"), - createIdentifier("Object") + ? factory.createConditionalExpression( + factory.createTypeCheck(factory.createIdentifier("BigInt"), "function"), + /*questionToken*/ undefined, + factory.createIdentifier("BigInt"), + /*colonToken*/ undefined, + factory.createIdentifier("Object") ) - : createIdentifier("BigInt"); + : factory.createIdentifier("BigInt"); } /** @@ -1810,18 +1815,18 @@ namespace ts { function getExpressionForPropertyName(member: ClassElement | EnumMember, generateNameForComputedPropertyName: boolean): Expression { const name = member.name!; if (isPrivateIdentifier(name)) { - return createIdentifier(""); + return factory.createIdentifier(""); } else if (isComputedPropertyName(name)) { return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression) - ? getGeneratedNameForNode(name) + ? factory.getGeneratedNameForNode(name) : name.expression; } else if (isIdentifier(name)) { - return createLiteral(idText(name)); + return factory.createStringLiteral(idText(name)); } else { - return getSynthesizedClone(name); + return factory.cloneNode(name); } } @@ -1842,9 +1847,9 @@ namespace ts { const expression = visitNode(name.expression, visitor, isExpression); const innerExpression = skipPartiallyEmittedExpressions(expression); if (!isSimpleInlineableExpression(innerExpression)) { - const generatedName = getGeneratedNameForNode(name); + const generatedName = factory.getGeneratedNameForNode(name); hoistVariableDeclaration(generatedName); - return updateComputedPropertyName(name, createAssignment(generatedName, expression)); + return factory.updateComputedPropertyName(name, factory.createAssignment(generatedName, expression)); } } return visitNode(name, visitor, isPropertyName); @@ -1876,10 +1881,10 @@ namespace ts { * @param node The ExpressionWithTypeArguments to transform. */ function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments): ExpressionWithTypeArguments { - return updateExpressionWithTypeArguments( + return factory.updateExpressionWithTypeArguments( node, - /*typeArguments*/ undefined, - visitNode(node.expression, visitor, isLeftHandSideExpression) + visitNode(node.expression, visitor, isLeftHandSideExpression), + /*typeArguments*/ undefined ); } @@ -1897,7 +1902,7 @@ namespace ts { if (node.flags & NodeFlags.Ambient) { return undefined; } - const updated = updateProperty( + const updated = factory.updatePropertyDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, visitor, isModifier), @@ -1920,7 +1925,7 @@ namespace ts { return undefined; } - return updateConstructor( + return factory.updateConstructorDeclaration( node, /*decorators*/ undefined, /*modifiers*/ undefined, @@ -1941,7 +1946,7 @@ namespace ts { resumeLexicalEnvironment(); - indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor); + indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(factory, constructor, statements, visitor); // Add parameters with property assignments. Transforms this: // @@ -1961,8 +1966,8 @@ namespace ts { addRange(statements, visitNodes(body.statements, visitor, isStatement, indexOfFirstStatement)); // End the lexical environment. - statements = mergeLexicalEnvironment(statements, endLexicalEnvironment()); - const block = createBlock(setTextRange(createNodeArray(statements), body.statements), /*multiLine*/ true); + statements = factory.mergeLexicalEnvironment(statements, endLexicalEnvironment()); + const block = factory.createBlock(setTextRange(factory.createNodeArray(statements), body.statements), /*multiLine*/ true); setTextRange(block, /*location*/ body); setOriginalNode(block, body); return block; @@ -1979,21 +1984,23 @@ namespace ts { return undefined; } - const propertyName = getMutableClone(name); + // TODO(rbuckton): Does this need to be parented? + const propertyName = setParent(setTextRange(factory.cloneNode(name), name), name.parent); setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoSourceMap); - const localName = getMutableClone(name); + // TODO(rbuckton): Does this need to be parented? + const localName = setParent(setTextRange(factory.cloneNode(name), name), name.parent); setEmitFlags(localName, EmitFlags.NoComments); return startOnNewLine( removeAllComments( setTextRange( setOriginalNode( - createExpressionStatement( - createAssignment( + factory.createExpressionStatement( + factory.createAssignment( setTextRange( - createPropertyAccess( - createThis(), + factory.createPropertyAccessExpression( + factory.createThis(), propertyName ), node.name @@ -2013,7 +2020,7 @@ namespace ts { if (!shouldEmitFunctionLikeDeclaration(node)) { return undefined; } - const updated = updateMethod( + const updated = factory.updateMethodDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, modifierVisitor, isModifier), @@ -2048,14 +2055,14 @@ namespace ts { if (!shouldEmitAccessorDeclaration(node)) { return undefined; } - const updated = updateGetAccessor( + const updated = factory.updateGetAccessorDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, modifierVisitor, isModifier), visitPropertyNameOfClassElement(node), visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - visitFunctionBody(node.body, visitor, context) || createBlock([]) + visitFunctionBody(node.body, visitor, context) || factory.createBlock([]) ); if (updated !== node) { // While we emit the source map for the node after skipping decorators and modifiers, @@ -2070,13 +2077,13 @@ namespace ts { if (!shouldEmitAccessorDeclaration(node)) { return undefined; } - const updated = updateSetAccessor( + const updated = factory.updateSetAccessorDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, modifierVisitor, isModifier), visitPropertyNameOfClassElement(node), visitParameterList(node.parameters, visitor, context), - visitFunctionBody(node.body, visitor, context) || createBlock([]) + visitFunctionBody(node.body, visitor, context) || factory.createBlock([]) ); if (updated !== node) { // While we emit the source map for the node after skipping decorators and modifiers, @@ -2089,9 +2096,9 @@ namespace ts { function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { if (!shouldEmitFunctionLikeDeclaration(node)) { - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); } - const updated = updateFunctionDeclaration( + const updated = factory.updateFunctionDeclaration( node, /*decorators*/ undefined, visitNodes(node.modifiers, modifierVisitor, isModifier), @@ -2100,7 +2107,7 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - visitFunctionBody(node.body, visitor, context) || createBlock([]) + visitFunctionBody(node.body, visitor, context) || factory.createBlock([]) ); if (isExportOfNamespace(node)) { const statements: Statement[] = [updated]; @@ -2112,9 +2119,9 @@ namespace ts { function visitFunctionExpression(node: FunctionExpression): Expression { if (!shouldEmitFunctionLikeDeclaration(node)) { - return createOmittedExpression(); + return factory.createOmittedExpression(); } - const updated = updateFunctionExpression( + const updated = factory.updateFunctionExpression( node, visitNodes(node.modifiers, modifierVisitor, isModifier), node.asteriskToken, @@ -2122,13 +2129,13 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - visitFunctionBody(node.body, visitor, context) || createBlock([]) + visitFunctionBody(node.body, visitor, context) || factory.createBlock([]) ); return updated; } function visitArrowFunction(node: ArrowFunction) { - const updated = updateArrowFunction( + const updated = factory.updateArrowFunction( node, visitNodes(node.modifiers, modifierVisitor, isModifier), /*typeParameters*/ undefined, @@ -2145,7 +2152,7 @@ namespace ts { return undefined; } - const updated = updateParameter( + const updated = factory.updateParameterDeclaration( node, /*decorators*/ undefined, /*modifiers*/ undefined, @@ -2175,8 +2182,8 @@ namespace ts { } return setTextRange( - createExpressionStatement( - inlineExpressions( + factory.createExpressionStatement( + factory.inlineExpressions( map(variables, transformInitializedVariable) ) ), @@ -2188,7 +2195,7 @@ namespace ts { } } - function transformInitializedVariable(node: VariableDeclaration): Expression { + function transformInitializedVariable(node: InitializedVariableDeclaration): Expression { const name = node.name; if (isBindingPattern(name)) { return flattenDestructuringAssignment( @@ -2202,7 +2209,7 @@ namespace ts { } else { return setTextRange( - createAssignment( + factory.createAssignment( getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), visitNode(node.initializer, visitor, isExpression) ), @@ -2212,10 +2219,10 @@ namespace ts { } function visitVariableDeclaration(node: VariableDeclaration) { - return updateTypeScriptVariableDeclaration( + return factory.updateVariableDeclaration( node, visitNode(node.name, visitor, isBindingName), - /*exclaimationToken*/ undefined, + /*exclamationToken*/ undefined, /*type*/ undefined, visitNode(node.initializer, visitor, isExpression)); } @@ -2243,9 +2250,9 @@ namespace ts { // HOWEVER - if there are leading comments on the expression itself, to handle ASI // correctly for return and throw, we must keep the parenthesis if (length(getLeadingCommentRangesOfNode(expression, currentSourceFile))) { - return updateParen(node, expression); + return factory.updateParenthesizedExpression(node, expression); } - return createPartiallyEmittedExpression(expression, node); + return factory.createPartiallyEmittedExpression(expression, node); } return visitEachChild(node, visitor, context); @@ -2253,16 +2260,16 @@ namespace ts { function visitAssertionExpression(node: AssertionExpression): Expression { const expression = visitNode(node.expression, visitor, isExpression); - return createPartiallyEmittedExpression(expression, node); + return factory.createPartiallyEmittedExpression(expression, node); } function visitNonNullExpression(node: NonNullExpression): Expression { const expression = visitNode(node.expression, visitor, isLeftHandSideExpression); - return createPartiallyEmittedExpression(expression, node); + return factory.createPartiallyEmittedExpression(expression, node); } function visitCallExpression(node: CallExpression) { - return updateCall( + return factory.updateCallExpression( node, visitNode(node.expression, visitor, isExpression), /*typeArguments*/ undefined, @@ -2270,7 +2277,7 @@ namespace ts { } function visitNewExpression(node: NewExpression) { - return updateNew( + return factory.updateNewExpression( node, visitNode(node.expression, visitor, isExpression), /*typeArguments*/ undefined, @@ -2278,7 +2285,7 @@ namespace ts { } function visitTaggedTemplateExpression(node: TaggedTemplateExpression) { - return updateTaggedTemplate( + return factory.updateTaggedTemplateExpression( node, visitNode(node.tag, visitor, isExpression), /*typeArguments*/ undefined, @@ -2286,7 +2293,7 @@ namespace ts { } function visitJsxSelfClosingElement(node: JsxSelfClosingElement) { - return updateJsxSelfClosingElement( + return factory.updateJsxSelfClosingElement( node, visitNode(node.tagName, visitor, isJsxTagNameExpression), /*typeArguments*/ undefined, @@ -2294,7 +2301,7 @@ namespace ts { } function visitJsxJsxOpeningElement(node: JsxOpeningElement) { - return updateJsxOpeningElement( + return factory.updateJsxOpeningElement( node, visitNode(node.tagName, visitor, isJsxTagNameExpression), /*typeArguments*/ undefined, @@ -2321,7 +2328,7 @@ namespace ts { */ function visitEnumDeclaration(node: EnumDeclaration): VisitResult { if (!shouldEmitEnumDeclaration(node)) { - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); } const statements: Statement[] = []; @@ -2349,40 +2356,40 @@ namespace ts { // `exportName` is the expression used within this node's container for any exported references. const exportName = hasSyntacticModifier(node, ModifierFlags.Export) - ? getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true) - : getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); + ? factory.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true) + : factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // x || (x = {}) // exports.x || (exports.x = {}) let moduleArg = - createLogicalOr( + factory.createLogicalOr( exportName, - createAssignment( + factory.createAssignment( exportName, - createObjectLiteral() + factory.createObjectLiteralExpression() ) ); if (hasNamespaceQualifiedExportName(node)) { // `localName` is the expression used within this node's containing scope for any local references. - const localName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); + const localName = factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // x = (exports.x || (exports.x = {})) - moduleArg = createAssignment(localName, moduleArg); + moduleArg = factory.createAssignment(localName, moduleArg); } // (function (x) { // x[x["y"] = 0] = "y"; // ... // })(x || (x = {})); - const enumStatement = createExpressionStatement( - createCall( - createFunctionExpression( + const enumStatement = factory.createExpressionStatement( + factory.createCallExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], + [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], /*type*/ undefined, transformEnumBody(node, containerName) ), @@ -2403,7 +2410,7 @@ namespace ts { // Add a DeclarationMarker for the enum to preserve trailing comments and mark // the end of the declaration. - statements.push(createEndOfDeclarationMarker(node)); + statements.push(factory.createEndOfDeclarationMarker(node)); return statements; } @@ -2423,8 +2430,8 @@ namespace ts { addRange(statements, members); currentNamespaceContainerName = savedCurrentNamespaceLocalName; - return createBlock( - setTextRange(createNodeArray(statements), /*location*/ node.members), + return factory.createBlock( + setTextRange(factory.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true ); } @@ -2440,8 +2447,8 @@ namespace ts { // old emitter always generate 'expression' part of the name as-is. const name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false); const valueExpression = transformEnumMemberDeclarationValue(member); - const innerAssignment = createAssignment( - createElementAccess( + const innerAssignment = factory.createAssignment( + factory.createElementAccessExpression( currentNamespaceContainerName, name ), @@ -2449,15 +2456,15 @@ namespace ts { ); const outerAssignment = valueExpression.kind === SyntaxKind.StringLiteral ? innerAssignment : - createAssignment( - createElementAccess( + factory.createAssignment( + factory.createElementAccessExpression( currentNamespaceContainerName, innerAssignment ), name ); return setTextRange( - createExpressionStatement( + factory.createExpressionStatement( setTextRange( outerAssignment, member @@ -2475,7 +2482,7 @@ namespace ts { function transformEnumMemberDeclarationValue(member: EnumMember): Expression { const value = resolver.getConstantValue(member); if (value !== undefined) { - return createLiteral(value); + return typeof value === "string" ? factory.createStringLiteral(value) : factory.createNumericLiteral(value); } else { enableSubstitutionForNonQualifiedEnumMembers(); @@ -2483,7 +2490,7 @@ namespace ts { return visitNode(member.initializer, visitor, isExpression); } else { - return createVoidZero(); + return factory.createVoidZero(); } } } @@ -2554,11 +2561,11 @@ namespace ts { // Emit a variable statement for the module. We emit top-level enums as a `var` // declaration to avoid static errors in global scripts scripts due to redeclaration. // enums in any other scope are emitted as a `let` declaration. - const statement = createVariableStatement( + const statement = factory.createVariableStatement( visitNodes(node.modifiers, modifierVisitor, isModifier), - createVariableDeclarationList([ - createVariableDeclaration( - getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true) + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true) ) ], currentLexicalScope.kind === SyntaxKind.SourceFile ? NodeFlags.None : NodeFlags.Let) ); @@ -2603,7 +2610,7 @@ namespace ts { // declaration we do not emit a leading variable declaration. To preserve the // begin/end semantics of the declararation and to properly handle exports // we wrap the leading variable declaration in a `MergeDeclarationMarker`. - const mergeMarker = createMergeDeclarationMarker(statement); + const mergeMarker = factory.createMergeDeclarationMarker(statement); setEmitFlags(mergeMarker, EmitFlags.NoComments | EmitFlags.HasEndOfDeclarationMarker); statements.push(mergeMarker); return false; @@ -2619,7 +2626,7 @@ namespace ts { */ function visitModuleDeclaration(node: ModuleDeclaration): VisitResult { if (!shouldEmitModuleDeclaration(node)) { - return createNotEmittedStatement(node); + return factory.createNotEmittedStatement(node); } Debug.assertNode(node.name, isIdentifier, "A TypeScript namespace should have an Identifier name."); @@ -2650,39 +2657,39 @@ namespace ts { // `exportName` is the expression used within this node's container for any exported references. const exportName = hasSyntacticModifier(node, ModifierFlags.Export) - ? getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true) - : getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); + ? factory.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true) + : factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // x || (x = {}) // exports.x || (exports.x = {}) let moduleArg = - createLogicalOr( + factory.createLogicalOr( exportName, - createAssignment( + factory.createAssignment( exportName, - createObjectLiteral() + factory.createObjectLiteralExpression() ) ); if (hasNamespaceQualifiedExportName(node)) { // `localName` is the expression used within this node's containing scope for any local references. - const localName = getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); + const localName = factory.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // x = (exports.x || (exports.x = {})) - moduleArg = createAssignment(localName, moduleArg); + moduleArg = factory.createAssignment(localName, moduleArg); } // (function (x_1) { // x_1.y = ...; // })(x || (x = {})); - const moduleStatement = createExpressionStatement( - createCall( - createFunctionExpression( + const moduleStatement = factory.createExpressionStatement( + factory.createCallExpression( + factory.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], + [factory.createParameterDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], /*type*/ undefined, transformModuleBody(node, containerName) ), @@ -2703,7 +2710,7 @@ namespace ts { // Add a DeclarationMarker for the namespace to preserve trailing comments and mark // the end of the declaration. - statements.push(createEndOfDeclarationMarker(node)); + statements.push(factory.createEndOfDeclarationMarker(node)); return statements; } @@ -2752,9 +2759,9 @@ namespace ts { currentNamespace = savedCurrentNamespace; currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName; - const block = createBlock( + const block = factory.createBlock( setTextRange( - createNodeArray(statements), + factory.createNodeArray(statements), /*location*/ statementsLocation ), /*multiLine*/ true @@ -2815,7 +2822,7 @@ namespace ts { return importClause || compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve || compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error - ? updateImportDeclaration( + ? factory.updateImportDeclaration( node, /*decorators*/ undefined, /*modifiers*/ undefined, @@ -2836,7 +2843,7 @@ namespace ts { // Elide the import clause if we elide both its name and its named bindings. const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined; const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings); - return (name || namedBindings) ? updateImportClause(node, name, namedBindings, /*isTypeOnly*/ false) : undefined; + return (name || namedBindings) ? factory.updateImportClause(node, /*isTypeOnly*/ false, name, namedBindings) : undefined; } /** @@ -2852,7 +2859,7 @@ namespace ts { else { // Elide named imports if all of its import specifiers are elided. const elements = visitNodes(node.elements, visitImportSpecifier, isImportSpecifier); - return some(elements) ? updateNamedImports(node, elements) : undefined; + return some(elements) ? factory.updateNamedImports(node, elements) : undefined; } } @@ -2905,13 +2912,13 @@ namespace ts { // Elide the export declaration if all of its named exports are elided. const exportClause = visitNode(node.exportClause, visitNamedExportBindings, isNamedExportBindings); return exportClause - ? updateExportDeclaration( + ? factory.updateExportDeclaration( node, /*decorators*/ undefined, /*modifiers*/ undefined, + node.isTypeOnly, exportClause, - node.moduleSpecifier, - node.isTypeOnly) + node.moduleSpecifier) : undefined; } @@ -2924,11 +2931,11 @@ namespace ts { function visitNamedExports(node: NamedExports): VisitResult { // Elide the named exports if all of its export specifiers were elided. const elements = visitNodes(node.elements, visitExportSpecifier, isExportSpecifier); - return some(elements) ? updateNamedExports(node, elements) : undefined; + return some(elements) ? factory.updateNamedExports(node, elements) : undefined; } function visitNamespaceExports(node: NamespaceExport): VisitResult { - return updateNamespaceExport(node, visitNode(node.name, visitor, isIdentifier)); + return factory.updateNamespaceExport(node, visitNode(node.name, visitor, isIdentifier)); } function visitNamedExportBindings(node: NamedExportBindings): VisitResult { @@ -2971,7 +2978,7 @@ namespace ts { if (!isReferenced && compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve) { return setOriginalNode( setTextRange( - createImportDeclaration( + factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, @@ -2990,7 +2997,7 @@ namespace ts { return undefined; } - const moduleReference = createExpressionFromEntityName(node.moduleReference); + const moduleReference = createExpressionFromEntityName(factory, node.moduleReference); setEmitFlags(moduleReference, EmitFlags.NoComments | EmitFlags.NoNestedComments); if (isNamedExternalModuleExport(node) || !isExportOfNamespace(node)) { @@ -2998,12 +3005,13 @@ namespace ts { // var ${name} = ${moduleReference}; return setOriginalNode( setTextRange( - createVariableStatement( + factory.createVariableStatement( visitNodes(node.modifiers, modifierVisitor, isModifier), - createVariableDeclarationList([ + factory.createVariableDeclarationList([ setOriginalNode( - createVariableDeclaration( + factory.createVariableDeclaration( node.name, + /*exclamationToken*/ undefined, /*type*/ undefined, moduleReference ), @@ -3071,26 +3079,26 @@ namespace ts { * Creates a statement for the provided expression. This is used in calls to `map`. */ function expressionToStatement(expression: Expression) { - return createExpressionStatement(expression); + return factory.createExpressionStatement(expression); } function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) { - const expression = createAssignment( - getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true), - getLocalName(node) + const expression = factory.createAssignment( + factory.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true), + factory.getLocalName(node) ); setSourceMapRange(expression, createRange(node.name ? node.name.pos : node.pos, node.end)); - const statement = createExpressionStatement(expression); + const statement = factory.createExpressionStatement(expression); setSourceMapRange(statement, createRange(-1, node.end)); statements.push(statement); } function createNamespaceExport(exportName: Identifier, exportValue: Expression, location?: TextRange) { return setTextRange( - createExpressionStatement( - createAssignment( - getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), + factory.createExpressionStatement( + factory.createAssignment( + factory.getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), exportValue ) ), @@ -3099,18 +3107,18 @@ namespace ts { } function createNamespaceExportExpression(exportName: Identifier, exportValue: Expression, location?: TextRange) { - return setTextRange(createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location); + return setTextRange(factory.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location); } function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name: Identifier) { - return getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true); + return factory.getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true); } /** * Gets the declaration name used inside of a namespace or enum. */ function getNamespaceParameterName(node: ModuleDeclaration | EnumDeclaration) { - const name = getGeneratedNameForNode(node); + const name = factory.getGeneratedNameForNode(node); setSourceMapRange(name, node.name); return name; } @@ -3120,7 +3128,7 @@ namespace ts { * of its declaration. */ function getNamespaceContainerName(node: ModuleDeclaration | EnumDeclaration) { - return getGeneratedNameForNode(node); + return factory.getGeneratedNameForNode(node); } /** @@ -3131,7 +3139,7 @@ namespace ts { function getClassAliasIfNeeded(node: ClassDeclaration) { if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { enableSubstitutionForClassAliases(); - const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? idText(node.name) : "default"); + const classAlias = factory.createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? idText(node.name) : "default"); classAliases[getOriginalNodeId(node)] = classAlias; hoistVariableDeclaration(classAlias); return classAlias; @@ -3139,12 +3147,12 @@ namespace ts { } function getClassPrototype(node: ClassExpression | ClassDeclaration) { - return createPropertyAccess(getDeclarationName(node), "prototype"); + return factory.createPropertyAccessExpression(factory.getDeclarationName(node), "prototype"); } function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) { return hasSyntacticModifier(member, ModifierFlags.Static) - ? getDeclarationName(node) + ? factory.getDeclarationName(node) : getClassPrototype(node); } @@ -3245,10 +3253,10 @@ namespace ts { // A shorthand property with an assignment initializer is probably part of a // destructuring assignment if (node.objectAssignmentInitializer) { - const initializer = createAssignment(exportedName, node.objectAssignmentInitializer); - return setTextRange(createPropertyAssignment(name, initializer), node); + const initializer = factory.createAssignment(exportedName, node.objectAssignmentInitializer); + return setTextRange(factory.createPropertyAssignment(name, initializer), node); } - return setTextRange(createPropertyAssignment(name, exportedName), node); + return setTextRange(factory.createPropertyAssignment(name, exportedName), node); } } return node; @@ -3285,7 +3293,7 @@ namespace ts { if (declaration) { const classAlias = classAliases[declaration.id!]; // TODO: GH#18217 if (classAlias) { - const clone = getSynthesizedClone(classAlias); + const clone = factory.cloneNode(classAlias); setSourceMapRange(clone, node); setCommentRange(clone, node); return clone; @@ -3309,7 +3317,7 @@ namespace ts { (applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration); if (substitute) { return setTextRange( - createPropertyAccess(getGeneratedNameForNode(container), node), + factory.createPropertyAccessExpression(factory.getGeneratedNameForNode(container), node), /*location*/ node ); } @@ -3333,7 +3341,7 @@ namespace ts { // track the constant value on the node for the printer in needsDotDotForPropertyAccess setConstantValue(node, constantValue); - const substitute = createLiteral(constantValue); + const substitute = typeof constantValue === "string" ? factory.createStringLiteral(constantValue) : factory.createNumericLiteral(constantValue); if (!compilerOptions.removeComments) { const originalNode = getOriginalNode(node, isAccessExpression); const propertyName = isPropertyAccessExpression(originalNode) @@ -3357,89 +3365,4 @@ namespace ts { return isPropertyAccessExpression(node) || isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined; } } - - function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) { - const argumentsArray: Expression[] = []; - argumentsArray.push(createArrayLiteral(decoratorExpressions, /*multiLine*/ true)); - argumentsArray.push(target); - if (memberName) { - argumentsArray.push(memberName); - if (descriptor) { - argumentsArray.push(descriptor); - } - } - - context.requestEmitHelper(decorateHelper); - return setTextRange( - createCall( - getUnscopedHelperName("__decorate"), - /*typeArguments*/ undefined, - argumentsArray - ), - location - ); - } - - export const decorateHelper: UnscopedEmitHelper = { - name: "typescript:decorate", - importName: "__decorate", - scoped: false, - priority: 2, - text: ` - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - };` - }; - - function createMetadataHelper(context: TransformationContext, metadataKey: string, metadataValue: Expression) { - context.requestEmitHelper(metadataHelper); - return createCall( - getUnscopedHelperName("__metadata"), - /*typeArguments*/ undefined, - [ - createLiteral(metadataKey), - metadataValue - ] - ); - } - - export const metadataHelper: UnscopedEmitHelper = { - name: "typescript:metadata", - importName: "__metadata", - scoped: false, - priority: 3, - text: ` - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - };` - }; - - function createParamHelper(context: TransformationContext, expression: Expression, parameterOffset: number, location?: TextRange) { - context.requestEmitHelper(paramHelper); - return setTextRange( - createCall( - getUnscopedHelperName("__param"), - /*typeArguments*/ undefined, - [ - createLiteral(parameterOffset), - expression - ] - ), - location - ); - } - - export const paramHelper: UnscopedEmitHelper = { - name: "typescript:param", - importName: "__param", - scoped: false, - priority: 4, - text: ` - var __param = (this && this.__param) || function (paramIndex, decorator) { - return function (target, key) { decorator(target, key, paramIndex); } - };` - }; } diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 48939d2106f40..fd897848e767c 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -25,7 +25,7 @@ namespace ts { return e.propertyName !== undefined && e.propertyName.escapedText === InternalSymbolName.Default; } - export function chainBundle(transformSourceFile: (x: SourceFile) => SourceFile): (x: SourceFile | Bundle) => SourceFile | Bundle { + export function chainBundle(context: CoreTransformationContext, transformSourceFile: (x: SourceFile) => SourceFile): (x: SourceFile | Bundle) => SourceFile | Bundle { return transformSourceFileOrBundle; function transformSourceFileOrBundle(node: SourceFile | Bundle) { @@ -33,7 +33,7 @@ namespace ts { } function transformBundle(node: Bundle) { - return createBundle(map(node.sourceFiles, transformSourceFile), node.prepends); + return context.factory.createBundle(map(node.sourceFiles, transformSourceFile), node.prepends); } } @@ -65,7 +65,7 @@ namespace ts { return !getImportNeedsImportStarHelper(node) && (isDefaultImport(node) || (!!node.importClause && isNamedImports(node.importClause.namedBindings!) && containsDefaultReference(node.importClause.namedBindings))); // TODO: GH#18217 } - export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo { + export function collectExternalModuleInfo(context: TransformationContext, sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo { const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = []; const exportSpecifiers = createMultiMap(); const exportedBindings: Identifier[][] = []; @@ -151,7 +151,7 @@ namespace ts { if (hasSyntacticModifier(node, ModifierFlags.Default)) { // export default function() { } if (!hasExportDefault) { - multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), context.factory.getDeclarationName(node)); hasExportDefault = true; } } @@ -172,7 +172,7 @@ namespace ts { if (hasSyntacticModifier(node, ModifierFlags.Default)) { // export default class { } if (!hasExportDefault) { - multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(node)); + multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), context.factory.getDeclarationName(node)); hasExportDefault = true; } } @@ -190,7 +190,7 @@ namespace ts { } } - const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar, hasImportDefault); + const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(context.factory, context.getEmitHelperFactory(), sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar, hasImportDefault); if (externalHelpersImportDeclaration) { externalImports.unshift(externalHelpersImportDeclaration); } @@ -303,11 +303,11 @@ namespace ts { * @param visitor The visitor to apply to each node added to the result array. * @returns index of the statement that follows super call */ - export function addPrologueDirectivesAndInitialSuperCall(ctor: ConstructorDeclaration, result: Statement[], visitor: Visitor): number { + export function addPrologueDirectivesAndInitialSuperCall(factory: NodeFactory, ctor: ConstructorDeclaration, result: Statement[], visitor: Visitor): number { if (ctor.body) { const statements = ctor.body.statements; // add prologue directives to the list (if any) - const index = addPrologue(result, statements, /*ensureUseStrict*/ false, visitor); + const index = factory.copyPrologue(statements, result, /*ensureUseStrict*/ false, visitor); if (index === statements.length) { // list contains nothing but prologue directives (or empty) - exit return index; @@ -327,29 +327,14 @@ namespace ts { return 0; } - - /** - * @param input Template string input strings - * @param args Names which need to be made file-level unique - */ - export function helperString(input: TemplateStringsArray, ...args: string[]) { - return (uniqueName: EmitHelperUniqueNameCallback) => { - let result = ""; - for (let i = 0; i < args.length; i++) { - result += input[i]; - result += uniqueName(args[i]); - } - result += input[input.length - 1]; - return result; - }; - } - /** * Gets all the static or all the instance property declarations of a class * * @param node The class node. * @param isStatic A value indicating whether to get properties from the static or instance side of the class. */ + export function getProperties(node: ClassExpression | ClassDeclaration, requireInitializer: true, isStatic: boolean): readonly InitializedPropertyDeclaration[]; + export function getProperties(node: ClassExpression | ClassDeclaration, requireInitializer: boolean, isStatic: boolean): readonly PropertyDeclaration[]; export function getProperties(node: ClassExpression | ClassDeclaration, requireInitializer: boolean, isStatic: boolean): readonly PropertyDeclaration[] { return filter(node.members, m => isInitializedOrStaticProperty(m, requireInitializer, isStatic)) as PropertyDeclaration[]; } diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index 846070b878166..6b17c1b21d32b 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -24,6 +24,15 @@ "scanner.ts", "utilitiesPublic.ts", "utilities.ts", + "factory/baseNodeFactory.ts", + "factory/parenthesizerRules.ts", + "factory/nodeConverters.ts", + "factory/nodeFactory.ts", + "factory/emitNode.ts", + "factory/emitHelpers.ts", + "factory/nodeTests.ts", + "factory/utilities.ts", + "factory/utilitiesPublic.ts", "parser.ts", "commandLineParser.ts", "moduleNameResolver.ts", @@ -31,10 +40,7 @@ "binder.ts", "symbolWalker.ts", "checker.ts", - "factoryPublic.ts", - "factory.ts", "visitorPublic.ts", - "visitor.ts", "sourcemap.ts", "transformers/utilities.ts", "transformers/destructuring.ts", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9d4f2fd9077a2..5c4e6f0c1592b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -11,112 +11,10 @@ namespace ts { end: number; } - export type JSDocSyntaxKind = - | SyntaxKind.EndOfFileToken - | SyntaxKind.WhitespaceTrivia - | SyntaxKind.AtToken - | SyntaxKind.NewLineTrivia - | SyntaxKind.AsteriskToken - | SyntaxKind.OpenBraceToken - | SyntaxKind.CloseBraceToken - | SyntaxKind.LessThanToken - | SyntaxKind.GreaterThanToken - | SyntaxKind.OpenBracketToken - | SyntaxKind.CloseBracketToken - | SyntaxKind.EqualsToken - | SyntaxKind.CommaToken - | SyntaxKind.DotToken - | SyntaxKind.Identifier - | SyntaxKind.BacktickToken - | SyntaxKind.Unknown - | KeywordSyntaxKind; - - export type KeywordSyntaxKind = - | SyntaxKind.AbstractKeyword - | SyntaxKind.AnyKeyword - | SyntaxKind.AsKeyword - | SyntaxKind.AssertsKeyword - | SyntaxKind.BigIntKeyword - | SyntaxKind.BooleanKeyword - | SyntaxKind.BreakKeyword - | SyntaxKind.CaseKeyword - | SyntaxKind.CatchKeyword - | SyntaxKind.ClassKeyword - | SyntaxKind.ContinueKeyword - | SyntaxKind.ConstKeyword - | SyntaxKind.ConstructorKeyword - | SyntaxKind.DebuggerKeyword - | SyntaxKind.DeclareKeyword - | SyntaxKind.DefaultKeyword - | SyntaxKind.DeleteKeyword - | SyntaxKind.DoKeyword - | SyntaxKind.ElseKeyword - | SyntaxKind.EnumKeyword - | SyntaxKind.ExportKeyword - | SyntaxKind.ExtendsKeyword - | SyntaxKind.FalseKeyword - | SyntaxKind.FinallyKeyword - | SyntaxKind.ForKeyword - | SyntaxKind.FromKeyword - | SyntaxKind.FunctionKeyword - | SyntaxKind.GetKeyword - | SyntaxKind.IfKeyword - | SyntaxKind.ImplementsKeyword - | SyntaxKind.ImportKeyword - | SyntaxKind.InKeyword - | SyntaxKind.InferKeyword - | SyntaxKind.InstanceOfKeyword - | SyntaxKind.InterfaceKeyword - | SyntaxKind.IsKeyword - | SyntaxKind.KeyOfKeyword - | SyntaxKind.LetKeyword - | SyntaxKind.ModuleKeyword - | SyntaxKind.NamespaceKeyword - | SyntaxKind.NeverKeyword - | SyntaxKind.NewKeyword - | SyntaxKind.NullKeyword - | SyntaxKind.NumberKeyword - | SyntaxKind.ObjectKeyword - | SyntaxKind.PackageKeyword - | SyntaxKind.PrivateKeyword - | SyntaxKind.ProtectedKeyword - | SyntaxKind.PublicKeyword - | SyntaxKind.ReadonlyKeyword - | SyntaxKind.RequireKeyword - | SyntaxKind.GlobalKeyword - | SyntaxKind.ReturnKeyword - | SyntaxKind.SetKeyword - | SyntaxKind.StaticKeyword - | SyntaxKind.StringKeyword - | SyntaxKind.SuperKeyword - | SyntaxKind.SwitchKeyword - | SyntaxKind.SymbolKeyword - | SyntaxKind.ThisKeyword - | SyntaxKind.ThrowKeyword - | SyntaxKind.TrueKeyword - | SyntaxKind.TryKeyword - | SyntaxKind.TypeKeyword - | SyntaxKind.TypeOfKeyword - | SyntaxKind.UndefinedKeyword - | SyntaxKind.UniqueKeyword - | SyntaxKind.UnknownKeyword - | SyntaxKind.VarKeyword - | SyntaxKind.VoidKeyword - | SyntaxKind.WhileKeyword - | SyntaxKind.WithKeyword - | SyntaxKind.YieldKeyword - | SyntaxKind.AsyncKeyword - | SyntaxKind.AwaitKeyword - | SyntaxKind.OfKeyword; - - export type JsxTokenSyntaxKind = - | SyntaxKind.LessThanSlashToken - | SyntaxKind.EndOfFileToken - | SyntaxKind.ConflictMarkerTrivia - | SyntaxKind.JsxText - | SyntaxKind.JsxTextAllWhiteSpaces - | SyntaxKind.OpenBraceToken - | SyntaxKind.LessThanToken; + export interface ReadonlyTextRange { + readonly pos: number; + readonly end: number; + } // token > SyntaxKind.Identifier => token is a keyword // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync @@ -542,6 +440,279 @@ namespace ts { /* @internal */ LastContextualKeyword = OfKeyword, } + export type TriviaSyntaxKind = + | SyntaxKind.SingleLineCommentTrivia + | SyntaxKind.MultiLineCommentTrivia + | SyntaxKind.NewLineTrivia + | SyntaxKind.WhitespaceTrivia + | SyntaxKind.ShebangTrivia + | SyntaxKind.ConflictMarkerTrivia + ; + + export type LiteralSyntaxKind = + | SyntaxKind.NumericLiteral + | SyntaxKind.BigIntLiteral + | SyntaxKind.StringLiteral + | SyntaxKind.JsxText + | SyntaxKind.JsxTextAllWhiteSpaces + | SyntaxKind.RegularExpressionLiteral + | SyntaxKind.NoSubstitutionTemplateLiteral + ; + + export type PseudoLiteralSyntaxKind = + | SyntaxKind.TemplateHead + | SyntaxKind.TemplateMiddle + | SyntaxKind.TemplateTail + ; + + export type PunctuationSyntaxKind = + | SyntaxKind.OpenBraceToken + | SyntaxKind.CloseBraceToken + | SyntaxKind.OpenParenToken + | SyntaxKind.CloseParenToken + | SyntaxKind.OpenBracketToken + | SyntaxKind.CloseBracketToken + | SyntaxKind.DotToken + | SyntaxKind.DotDotDotToken + | SyntaxKind.SemicolonToken + | SyntaxKind.CommaToken + | SyntaxKind.QuestionDotToken + | SyntaxKind.LessThanToken + | SyntaxKind.LessThanSlashToken + | SyntaxKind.GreaterThanToken + | SyntaxKind.LessThanEqualsToken + | SyntaxKind.GreaterThanEqualsToken + | SyntaxKind.EqualsEqualsToken + | SyntaxKind.ExclamationEqualsToken + | SyntaxKind.EqualsEqualsEqualsToken + | SyntaxKind.ExclamationEqualsEqualsToken + | SyntaxKind.EqualsGreaterThanToken + | SyntaxKind.PlusToken + | SyntaxKind.MinusToken + | SyntaxKind.AsteriskToken + | SyntaxKind.AsteriskAsteriskToken + | SyntaxKind.SlashToken + | SyntaxKind.PercentToken + | SyntaxKind.PlusPlusToken + | SyntaxKind.MinusMinusToken + | SyntaxKind.LessThanLessThanToken + | SyntaxKind.GreaterThanGreaterThanToken + | SyntaxKind.GreaterThanGreaterThanGreaterThanToken + | SyntaxKind.AmpersandToken + | SyntaxKind.BarToken + | SyntaxKind.CaretToken + | SyntaxKind.ExclamationToken + | SyntaxKind.TildeToken + | SyntaxKind.AmpersandAmpersandToken + | SyntaxKind.BarBarToken + | SyntaxKind.QuestionQuestionToken + | SyntaxKind.QuestionToken + | SyntaxKind.ColonToken + | SyntaxKind.AtToken + | SyntaxKind.BacktickToken + | SyntaxKind.EqualsToken + | SyntaxKind.PlusEqualsToken + | SyntaxKind.MinusEqualsToken + | SyntaxKind.AsteriskEqualsToken + | SyntaxKind.AsteriskAsteriskEqualsToken + | SyntaxKind.SlashEqualsToken + | SyntaxKind.PercentEqualsToken + | SyntaxKind.LessThanLessThanEqualsToken + | SyntaxKind.GreaterThanGreaterThanEqualsToken + | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken + | SyntaxKind.AmpersandEqualsToken + | SyntaxKind.BarEqualsToken + | SyntaxKind.CaretEqualsToken + ; + + export type KeywordSyntaxKind = + | SyntaxKind.AbstractKeyword + | SyntaxKind.AnyKeyword + | SyntaxKind.AsKeyword + | SyntaxKind.AssertsKeyword + | SyntaxKind.AsyncKeyword + | SyntaxKind.AwaitKeyword + | SyntaxKind.BigIntKeyword + | SyntaxKind.BooleanKeyword + | SyntaxKind.BreakKeyword + | SyntaxKind.CaseKeyword + | SyntaxKind.CatchKeyword + | SyntaxKind.ClassKeyword + | SyntaxKind.ConstKeyword + | SyntaxKind.ConstructorKeyword + | SyntaxKind.ContinueKeyword + | SyntaxKind.DebuggerKeyword + | SyntaxKind.DeclareKeyword + | SyntaxKind.DefaultKeyword + | SyntaxKind.DeleteKeyword + | SyntaxKind.DoKeyword + | SyntaxKind.ElseKeyword + | SyntaxKind.EnumKeyword + | SyntaxKind.ExportKeyword + | SyntaxKind.ExtendsKeyword + | SyntaxKind.FalseKeyword + | SyntaxKind.FinallyKeyword + | SyntaxKind.ForKeyword + | SyntaxKind.FromKeyword + | SyntaxKind.FunctionKeyword + | SyntaxKind.GetKeyword + | SyntaxKind.GlobalKeyword + | SyntaxKind.IfKeyword + | SyntaxKind.ImplementsKeyword + | SyntaxKind.ImportKeyword + | SyntaxKind.InferKeyword + | SyntaxKind.InKeyword + | SyntaxKind.InstanceOfKeyword + | SyntaxKind.InterfaceKeyword + | SyntaxKind.IsKeyword + | SyntaxKind.KeyOfKeyword + | SyntaxKind.LetKeyword + | SyntaxKind.ModuleKeyword + | SyntaxKind.NamespaceKeyword + | SyntaxKind.NeverKeyword + | SyntaxKind.NewKeyword + | SyntaxKind.NullKeyword + | SyntaxKind.NumberKeyword + | SyntaxKind.ObjectKeyword + | SyntaxKind.OfKeyword + | SyntaxKind.PackageKeyword + | SyntaxKind.PrivateKeyword + | SyntaxKind.ProtectedKeyword + | SyntaxKind.PublicKeyword + | SyntaxKind.ReadonlyKeyword + | SyntaxKind.RequireKeyword + | SyntaxKind.ReturnKeyword + | SyntaxKind.SetKeyword + | SyntaxKind.StaticKeyword + | SyntaxKind.StringKeyword + | SyntaxKind.SuperKeyword + | SyntaxKind.SwitchKeyword + | SyntaxKind.SymbolKeyword + | SyntaxKind.ThisKeyword + | SyntaxKind.ThrowKeyword + | SyntaxKind.TrueKeyword + | SyntaxKind.TryKeyword + | SyntaxKind.TypeKeyword + | SyntaxKind.TypeOfKeyword + | SyntaxKind.UndefinedKeyword + | SyntaxKind.UniqueKeyword + | SyntaxKind.UnknownKeyword + | SyntaxKind.VarKeyword + | SyntaxKind.VoidKeyword + | SyntaxKind.WhileKeyword + | SyntaxKind.WithKeyword + | SyntaxKind.YieldKeyword + ; + + export type ModifierSyntaxKind = + | SyntaxKind.AbstractKeyword + | SyntaxKind.AsyncKeyword + | SyntaxKind.ConstKeyword + | SyntaxKind.DeclareKeyword + | SyntaxKind.DefaultKeyword + | SyntaxKind.ExportKeyword + | SyntaxKind.PrivateKeyword + | SyntaxKind.ProtectedKeyword + | SyntaxKind.PublicKeyword + | SyntaxKind.ReadonlyKeyword + | SyntaxKind.StaticKeyword + ; + + export type KeywordTypeSyntaxKind = + | SyntaxKind.AnyKeyword + | SyntaxKind.BigIntKeyword + | SyntaxKind.BooleanKeyword + | SyntaxKind.NeverKeyword + | SyntaxKind.NumberKeyword + | SyntaxKind.ObjectKeyword + | SyntaxKind.StringKeyword + | SyntaxKind.SymbolKeyword + | SyntaxKind.UndefinedKeyword + | SyntaxKind.UnknownKeyword + | SyntaxKind.VoidKeyword + ; + + /* @internal */ + export type TypeNodeSyntaxKind = + | KeywordTypeSyntaxKind + | SyntaxKind.TypePredicate + | SyntaxKind.TypeReference + | SyntaxKind.FunctionType + | SyntaxKind.ConstructorType + | SyntaxKind.TypeQuery + | SyntaxKind.TypeLiteral + | SyntaxKind.ArrayType + | SyntaxKind.TupleType + | SyntaxKind.NamedTupleMember + | SyntaxKind.OptionalType + | SyntaxKind.RestType + | SyntaxKind.UnionType + | SyntaxKind.IntersectionType + | SyntaxKind.ConditionalType + | SyntaxKind.InferType + | SyntaxKind.ParenthesizedType + | SyntaxKind.ThisType + | SyntaxKind.TypeOperator + | SyntaxKind.IndexedAccessType + | SyntaxKind.MappedType + | SyntaxKind.LiteralType + | SyntaxKind.ImportType + | SyntaxKind.ExpressionWithTypeArguments + | SyntaxKind.JSDocTypeExpression + | SyntaxKind.JSDocAllType + | SyntaxKind.JSDocUnknownType + | SyntaxKind.JSDocNonNullableType + | SyntaxKind.JSDocNullableType + | SyntaxKind.JSDocOptionalType + | SyntaxKind.JSDocFunctionType + | SyntaxKind.JSDocVariadicType + | SyntaxKind.JSDocNamepathType + | SyntaxKind.JSDocSignature + | SyntaxKind.JSDocTypeLiteral + ; + + export type TokenSyntaxKind = + | SyntaxKind.Unknown + | SyntaxKind.EndOfFileToken + | TriviaSyntaxKind + | LiteralSyntaxKind + | PseudoLiteralSyntaxKind + | PunctuationSyntaxKind + | SyntaxKind.Identifier + | KeywordSyntaxKind + ; + + export type JsxTokenSyntaxKind = + | SyntaxKind.LessThanSlashToken + | SyntaxKind.EndOfFileToken + | SyntaxKind.ConflictMarkerTrivia + | SyntaxKind.JsxText + | SyntaxKind.JsxTextAllWhiteSpaces + | SyntaxKind.OpenBraceToken + | SyntaxKind.LessThanToken + ; + + export type JSDocSyntaxKind = + | SyntaxKind.EndOfFileToken + | SyntaxKind.WhitespaceTrivia + | SyntaxKind.AtToken + | SyntaxKind.NewLineTrivia + | SyntaxKind.AsteriskToken + | SyntaxKind.OpenBraceToken + | SyntaxKind.CloseBraceToken + | SyntaxKind.LessThanToken + | SyntaxKind.GreaterThanToken + | SyntaxKind.OpenBracketToken + | SyntaxKind.CloseBracketToken + | SyntaxKind.EqualsToken + | SyntaxKind.CommaToken + | SyntaxKind.DotToken + | SyntaxKind.Identifier + | SyntaxKind.BacktickToken + | SyntaxKind.Unknown + | KeywordSyntaxKind + ; + export const enum NodeFlags { None = 0, Let = 1 << 0, // Variable declaration @@ -647,15 +818,15 @@ namespace ts { ReportsMask = ReportsUnmeasurable | ReportsUnreliable } - export interface Node extends TextRange { - kind: SyntaxKind; - flags: NodeFlags; + export interface Node extends ReadonlyTextRange { + readonly kind: SyntaxKind; + readonly flags: NodeFlags; /* @internal */ modifierFlagsCache: ModifierFlags; - /* @internal */ transformFlags: TransformFlags; // Flags for transforms, possibly undefined - decorators?: NodeArray; // Array of decorators (in document order) - modifiers?: ModifiersArray; // Array of modifiers + /* @internal */ readonly transformFlags: TransformFlags; // Flags for transforms + readonly decorators?: NodeArray; // Array of decorators (in document order) + readonly modifiers?: ModifiersArray; // Array of modifiers /* @internal */ id?: number; // Unique id (used to look up NodeLinks) - parent: Node; // Parent node (initialized by binding) + readonly parent: Node; // Parent node (initialized by binding) /* @internal */ original?: Node; // The original node if this is an updated node. /* @internal */ symbol: Symbol; // Symbol declared by node (initialized by binding) /* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding) @@ -669,7 +840,7 @@ namespace ts { export interface JSDocContainer { /* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node - /* @internal */ jsDocCache?: readonly JSDocTag[]; // Cache for getJSDocTags + /* @internal */ jsDocCache?: readonly JSDocTag[]; // Cache for getJSDocTags } export type HasJSDoc = @@ -699,13 +870,17 @@ namespace ts { | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration + | ImportDeclaration + | NamespaceExportDeclaration + | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember - | EndOfFileToken; + | EndOfFileToken + ; export type HasType = | SignatureDeclaration @@ -723,7 +898,8 @@ namespace ts { | JSDocNonNullableType | JSDocNullableType | JSDocOptionalType - | JSDocVariadicType; + | JSDocVariadicType + ; export type HasTypeArguments = | CallExpression @@ -737,7 +913,8 @@ namespace ts { | ForStatement | ForInStatement | ForOfStatement - | JsxAttribute; + | JsxAttribute + ; export type HasExpressionInitializer = | VariableDeclaration @@ -746,61 +923,140 @@ namespace ts { | PropertySignature | PropertyDeclaration | PropertyAssignment - | EnumMember; + | EnumMember + ; + + // NOTE: Changing this list requires changes to `canHaveModifiers` in factory/utilities.ts and `updateModifiers` in factory/nodeFactory.ts + /* @internal */ + export type HasModifiers = + | ParameterDeclaration + | PropertySignature + | PropertyDeclaration + | MethodSignature + | MethodDeclaration + | ConstructorDeclaration + | GetAccessorDeclaration + | SetAccessorDeclaration + | IndexSignatureDeclaration + | FunctionExpression + | ArrowFunction + | ClassExpression + | VariableStatement + | FunctionDeclaration + | ClassDeclaration + | InterfaceDeclaration + | TypeAliasDeclaration + | EnumDeclaration + | ModuleDeclaration + | ImportEqualsDeclaration + | ImportDeclaration + | ExportAssignment + | ExportDeclaration + ; /* @internal */ export type MutableNodeArray = NodeArray & T[]; - export interface NodeArray extends ReadonlyArray, TextRange { + export interface NodeArray extends ReadonlyArray, ReadonlyTextRange { hasTrailingComma?: boolean; /* @internal */ transformFlags: TransformFlags; // Flags for transforms, possibly undefined } + // TODO(rbuckton): Constraint 'TKind' to 'TokenSyntaxKind' export interface Token extends Node { - kind: TKind; - } - - export type DotToken = Token; - export type DotDotDotToken = Token; - export type QuestionToken = Token; - export type QuestionDotToken = Token; - export type ExclamationToken = Token; - export type ColonToken = Token; - export type EqualsToken = Token; - export type AsteriskToken = Token; - export type EqualsGreaterThanToken = Token; + readonly kind: TKind; + } + export type EndOfFileToken = Token & JSDocContainer; - export type ReadonlyToken = Token; - export type AwaitKeywordToken = Token; - export type PlusToken = Token; - export type MinusToken = Token; - export type AssertsToken = Token; - - export type Modifier - = Token - | Token - | Token - | Token - | Token - | Token - | Token - | Token - | Token - | Token - | Token + + // Punctuation + export interface PunctuationToken extends Token { + } + + export type DotToken = PunctuationToken; + export type DotDotDotToken = PunctuationToken; + export type QuestionToken = PunctuationToken; + export type ExclamationToken = PunctuationToken; + export type ColonToken = PunctuationToken; + export type EqualsToken = PunctuationToken; + export type AsteriskToken = PunctuationToken; + export type EqualsGreaterThanToken = PunctuationToken; + export type PlusToken = PunctuationToken; + export type MinusToken = PunctuationToken; + export type QuestionDotToken = PunctuationToken; + + // Keywords + export interface KeywordToken extends Token { + } + + export type AssertsKeyword = KeywordToken; + export type AwaitKeyword = KeywordToken; + + /** @deprecated Use `AwaitKeyword` instead. */ + export type AwaitKeywordToken = AwaitKeyword; + + /** @deprecated Use `AssertsKeyword` instead. */ + export type AssertsToken = AssertsKeyword; + + export interface ModifierToken extends KeywordToken { + } + + export type AbstractKeyword = ModifierToken; + export type AsyncKeyword = ModifierToken; + export type ConstKeyword = ModifierToken; + export type DeclareKeyword = ModifierToken; + export type DefaultKeyword = ModifierToken; + export type ExportKeyword = ModifierToken; + export type PrivateKeyword = ModifierToken; + export type ProtectedKeyword = ModifierToken; + export type PublicKeyword = ModifierToken; + export type ReadonlyKeyword = ModifierToken; + export type StaticKeyword = ModifierToken; + + /** @deprecated Use `ReadonlyKeyword` instead. */ + export type ReadonlyToken = ReadonlyKeyword; + + export type Modifier = + | AbstractKeyword + | AsyncKeyword + | ConstKeyword + | DeclareKeyword + | DefaultKeyword + | ExportKeyword + | PrivateKeyword + | ProtectedKeyword + | PublicKeyword + | ReadonlyKeyword + | StaticKeyword + ; + + export type AccessibilityModifier = + | PublicKeyword + | PrivateKeyword + | ProtectedKeyword + ; + + export type ParameterPropertyModifier = + | AccessibilityModifier + | ReadonlyKeyword + ; + + export type ClassMemberModifier = + | AccessibilityModifier + | ReadonlyKeyword + | StaticKeyword ; export type ModifiersArray = NodeArray; - /*@internal*/ export const enum GeneratedIdentifierFlags { // Kinds None = 0, // Not automatically generated. - Auto = 1, // Automatically generated identifier. - Loop = 2, // Automatically generated identifier with a preference for '_i'. - Unique = 3, // Unique name based on the 'text' property. - Node = 4, // Unique name based on the node in the 'original' property. - KindMask = 7, // Mask to extract the kind of identifier from its flags. + /*@internal*/ Auto = 1, // Automatically generated identifier. + /*@internal*/ Loop = 2, // Automatically generated identifier with a preference for '_i'. + /*@internal*/ Unique = 3, // Unique name based on the 'text' property. + /*@internal*/ Node = 4, // Unique name based on the node in the 'original' property. + /*@internal*/ KindMask = 7, // Mask to extract the kind of identifier from its flags. // Flags ReservedInNestedScopes = 1 << 3, // Reserve the generated name in nested scopes @@ -809,15 +1065,15 @@ namespace ts { } export interface Identifier extends PrimaryExpression, Declaration { - kind: SyntaxKind.Identifier; + readonly kind: SyntaxKind.Identifier; /** * Prefer to use `id.unescapedText`. (Note: This is available only in services, not internally to the TypeScript compiler.) * Text of identifier, but if the identifier begins with two underscores, this will begin with three. */ - escapedText: __String; - originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later - /*@internal*/ autoGenerateFlags?: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. - /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. + readonly escapedText: __String; + readonly originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later + /*@internal*/ readonly autoGenerateFlags?: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. + /*@internal*/ readonly autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. @@ -834,9 +1090,9 @@ namespace ts { } export interface QualifiedName extends Node { - kind: SyntaxKind.QualifiedName; - left: EntityName; - right: Identifier; + readonly kind: SyntaxKind.QualifiedName; + readonly left: EntityName; + readonly right: Identifier; /*@internal*/ jsdocDotPos?: number; // QualifiedName occurs in JSDoc-style generic: Id1.Id2. } @@ -859,83 +1115,83 @@ namespace ts { } export interface NamedDeclaration extends Declaration { - name?: DeclarationName; + readonly name?: DeclarationName; } /* @internal */ export interface DynamicNamedDeclaration extends NamedDeclaration { - name: ComputedPropertyName; + readonly name: ComputedPropertyName; } /* @internal */ export interface DynamicNamedBinaryExpression extends BinaryExpression { - left: ElementAccessExpression; + readonly left: ElementAccessExpression; } /* @internal */ // A declaration that supports late-binding (used in checker) export interface LateBoundDeclaration extends DynamicNamedDeclaration { - name: LateBoundName; + readonly name: LateBoundName; } /* @internal */ export interface LateBoundBinaryExpressionDeclaration extends DynamicNamedBinaryExpression { - left: LateBoundElementAccessExpression; + readonly left: LateBoundElementAccessExpression; } /* @internal */ export interface LateBoundElementAccessExpression extends ElementAccessExpression { - argumentExpression: EntityNameExpression; + readonly argumentExpression: EntityNameExpression; } export interface DeclarationStatement extends NamedDeclaration, Statement { - name?: Identifier | StringLiteral | NumericLiteral; + readonly name?: Identifier | StringLiteral | NumericLiteral; } export interface ComputedPropertyName extends Node { - parent: Declaration; - kind: SyntaxKind.ComputedPropertyName; - expression: Expression; + readonly kind: SyntaxKind.ComputedPropertyName; + readonly parent: Declaration; + readonly expression: Expression; } export interface PrivateIdentifier extends Node { - kind: SyntaxKind.PrivateIdentifier; + readonly kind: SyntaxKind.PrivateIdentifier; // escaping not strictly necessary // avoids gotchas in transforms and utils - escapedText: __String; + readonly escapedText: __String; } /* @internal */ // A name that supports late-binding (used in checker) export interface LateBoundName extends ComputedPropertyName { - expression: EntityNameExpression; + readonly expression: EntityNameExpression; } export interface Decorator extends Node { - kind: SyntaxKind.Decorator; - parent: NamedDeclaration; - expression: LeftHandSideExpression; + readonly kind: SyntaxKind.Decorator; + readonly parent: NamedDeclaration; + readonly expression: LeftHandSideExpression; } export interface TypeParameterDeclaration extends NamedDeclaration { - kind: SyntaxKind.TypeParameter; - parent: DeclarationWithTypeParameterChildren | InferTypeNode; - name: Identifier; + readonly kind: SyntaxKind.TypeParameter; + readonly parent: DeclarationWithTypeParameterChildren | InferTypeNode; + readonly name: Identifier; /** Note: Consider calling `getEffectiveConstraintOfTypeParameter` */ - constraint?: TypeNode; - default?: TypeNode; + readonly constraint?: TypeNode; + readonly default?: TypeNode; // For error recovery purposes. expression?: Expression; } export interface SignatureDeclarationBase extends NamedDeclaration, JSDocContainer { - kind: SignatureDeclaration["kind"]; - name?: PropertyName; - typeParameters?: NodeArray; - parameters: NodeArray; - type?: TypeNode; + readonly kind: SignatureDeclaration["kind"]; + readonly name?: PropertyName; + readonly typeParameters?: NodeArray; + readonly parameters: NodeArray; + readonly type?: TypeNode; /* @internal */ typeArguments?: NodeArray; // Used for quick info, replaces typeParameters for instantiated signatures } @@ -955,68 +1211,71 @@ namespace ts { | ArrowFunction; export interface CallSignatureDeclaration extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.CallSignature; + readonly kind: SyntaxKind.CallSignature; } export interface ConstructSignatureDeclaration extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.ConstructSignature; + readonly kind: SyntaxKind.ConstructSignature; } export type BindingName = Identifier | BindingPattern; export interface VariableDeclaration extends NamedDeclaration { - kind: SyntaxKind.VariableDeclaration; - parent: VariableDeclarationList | CatchClause; - name: BindingName; // Declared variable name - exclamationToken?: ExclamationToken; // Optional definite assignment assertion - type?: TypeNode; // Optional type annotation - initializer?: Expression; // Optional initializer + readonly kind: SyntaxKind.VariableDeclaration; + readonly parent: VariableDeclarationList | CatchClause; + readonly name: BindingName; // Declared variable name + readonly exclamationToken?: ExclamationToken; // Optional definite assignment assertion + readonly type?: TypeNode; // Optional type annotation + readonly initializer?: Expression; // Optional initializer } + /* @internal */ + export type InitializedVariableDeclaration = VariableDeclaration & { readonly initializer: Expression }; + export interface VariableDeclarationList extends Node { - kind: SyntaxKind.VariableDeclarationList; - parent: VariableStatement | ForStatement | ForOfStatement | ForInStatement; - declarations: NodeArray; + readonly kind: SyntaxKind.VariableDeclarationList; + readonly parent: VariableStatement | ForStatement | ForOfStatement | ForInStatement; + readonly declarations: NodeArray; } export interface ParameterDeclaration extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.Parameter; - parent: SignatureDeclaration; - dotDotDotToken?: DotDotDotToken; // Present on rest parameter - name: BindingName; // Declared parameter name. - questionToken?: QuestionToken; // Present on optional parameter - type?: TypeNode; // Optional type annotation - initializer?: Expression; // Optional initializer + readonly kind: SyntaxKind.Parameter; + readonly parent: SignatureDeclaration; + readonly dotDotDotToken?: DotDotDotToken; // Present on rest parameter + readonly name: BindingName; // Declared parameter name. + readonly questionToken?: QuestionToken; // Present on optional parameter + readonly type?: TypeNode; // Optional type annotation + readonly initializer?: Expression; // Optional initializer } export interface BindingElement extends NamedDeclaration { - kind: SyntaxKind.BindingElement; - parent: BindingPattern; - propertyName?: PropertyName; // Binding property name (in object binding pattern) - dotDotDotToken?: DotDotDotToken; // Present on rest element (in object binding pattern) - name: BindingName; // Declared binding element name - initializer?: Expression; // Optional initializer + readonly kind: SyntaxKind.BindingElement; + readonly parent: BindingPattern; + readonly propertyName?: PropertyName; // Binding property name (in object binding pattern) + readonly dotDotDotToken?: DotDotDotToken; // Present on rest element (in object binding pattern) + readonly name: BindingName; // Declared binding element name + readonly initializer?: Expression; // Optional initializer } /*@internal*/ export type BindingElementGrandparent = BindingElement["parent"]["parent"]; export interface PropertySignature extends TypeElement, JSDocContainer { - kind: SyntaxKind.PropertySignature; - name: PropertyName; // Declared property name - questionToken?: QuestionToken; // Present on optional property - type?: TypeNode; // Optional type annotation - initializer?: Expression; // Optional initializer + readonly kind: SyntaxKind.PropertySignature; + readonly name: PropertyName; // Declared property name + readonly questionToken?: QuestionToken; // Present on optional property + readonly type?: TypeNode; // Optional type annotation + initializer?: Expression; // Present for use with reporting a grammar error } export interface PropertyDeclaration extends ClassElement, JSDocContainer { - kind: SyntaxKind.PropertyDeclaration; - parent: ClassLikeDeclaration; - name: PropertyName; - questionToken?: QuestionToken; // Present for use with reporting a grammar error - exclamationToken?: ExclamationToken; - type?: TypeNode; - initializer?: Expression; // Optional initializer + readonly kind: SyntaxKind.PropertyDeclaration; + readonly parent: ClassLikeDeclaration; + readonly name: PropertyName; + readonly questionToken?: QuestionToken; // Present for use with reporting a grammar error + readonly exclamationToken?: ExclamationToken; + readonly type?: TypeNode; + readonly initializer?: Expression; // Optional initializer } /*@internal*/ @@ -1024,9 +1283,12 @@ namespace ts { name: PrivateIdentifier; } + /* @internal */ + export type InitializedPropertyDeclaration = PropertyDeclaration & { readonly initializer: Expression }; + export interface ObjectLiteralElement extends NamedDeclaration { _objectLiteralBrand: any; - name?: PropertyName; + readonly name?: PropertyName; } /** Unlike ObjectLiteralElement, excludes JSXAttribute and JSXSpreadAttribute. */ @@ -1039,29 +1301,30 @@ namespace ts { ; export interface PropertyAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.PropertyAssignment; - name: PropertyName; - questionToken?: QuestionToken; - initializer: Expression; + readonly kind: SyntaxKind.PropertyAssignment; + readonly parent: ObjectLiteralExpression; + readonly name: PropertyName; + readonly questionToken?: QuestionToken; // Present for use with reporting a grammar error + readonly exclamationToken?: ExclamationToken; // Present for use with reporting a grammar error + readonly initializer: Expression; } export interface ShorthandPropertyAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.ShorthandPropertyAssignment; - name: Identifier; - questionToken?: QuestionToken; - exclamationToken?: ExclamationToken; + readonly kind: SyntaxKind.ShorthandPropertyAssignment; + readonly parent: ObjectLiteralExpression; + readonly name: Identifier; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; // used when ObjectLiteralExpression is used in ObjectAssignmentPattern - // it is grammar error to appear in actual object initializer - equalsToken?: Token; - objectAssignmentInitializer?: Expression; + // it is a grammar error to appear in actual object initializer: + readonly equalsToken?: EqualsToken; + readonly objectAssignmentInitializer?: Expression; } export interface SpreadAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.SpreadAssignment; - expression: Expression; + readonly kind: SyntaxKind.SpreadAssignment; + readonly parent: ObjectLiteralExpression; + readonly expression: Expression; } export type VariableLikeDeclaration = @@ -1078,19 +1341,19 @@ namespace ts { | JSDocParameterTag; export interface PropertyLikeDeclaration extends NamedDeclaration { - name: PropertyName; + readonly name: PropertyName; } export interface ObjectBindingPattern extends Node { - kind: SyntaxKind.ObjectBindingPattern; - parent: VariableDeclaration | ParameterDeclaration | BindingElement; - elements: NodeArray; + readonly kind: SyntaxKind.ObjectBindingPattern; + readonly parent: VariableDeclaration | ParameterDeclaration | BindingElement; + readonly elements: NodeArray; } export interface ArrayBindingPattern extends Node { - kind: SyntaxKind.ArrayBindingPattern; - parent: VariableDeclaration | ParameterDeclaration | BindingElement; - elements: NodeArray; + readonly kind: SyntaxKind.ArrayBindingPattern; + readonly parent: VariableDeclaration | ParameterDeclaration | BindingElement; + readonly elements: NodeArray; } export type BindingPattern = ObjectBindingPattern | ArrayBindingPattern; @@ -1108,10 +1371,10 @@ namespace ts { export interface FunctionLikeDeclarationBase extends SignatureDeclarationBase { _functionLikeDeclarationBrand: any; - asteriskToken?: AsteriskToken; - questionToken?: QuestionToken; - exclamationToken?: ExclamationToken; - body?: Block | Expression; + readonly asteriskToken?: AsteriskToken; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly body?: Block | Expression; /* @internal */ endFlowNode?: FlowNode; /* @internal */ returnFlowNode?: FlowNode; } @@ -1128,15 +1391,15 @@ namespace ts { export type FunctionLike = SignatureDeclaration; export interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { - kind: SyntaxKind.FunctionDeclaration; - name?: Identifier; - body?: FunctionBody; + readonly kind: SyntaxKind.FunctionDeclaration; + readonly name?: Identifier; + readonly body?: FunctionBody; } export interface MethodSignature extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.MethodSignature; - parent: ObjectTypeDeclaration; - name: PropertyName; + readonly kind: SyntaxKind.MethodSignature; + readonly parent: ObjectTypeDeclaration; + readonly name: PropertyName; } // Note that a MethodDeclaration is considered both a ClassElement and an ObjectLiteralElement. @@ -1149,225 +1412,225 @@ namespace ts { // at later stages of the compiler pipeline. In that case, you can either check the parent kind // of the method, or use helpers like isObjectLiteralMethodDeclaration export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.MethodDeclaration; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.MethodDeclaration; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; + /* @internal*/ exclamationToken?: ExclamationToken; // Present for use with reporting a grammar error } export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement, JSDocContainer { - kind: SyntaxKind.Constructor; - parent: ClassLikeDeclaration; - body?: FunctionBody; + readonly kind: SyntaxKind.Constructor; + readonly parent: ClassLikeDeclaration; + readonly body?: FunctionBody; + /* @internal */ typeParameters?: NodeArray; // Present for use with reporting a grammar error + /* @internal */ type?: TypeNode; // Present for use with reporting a grammar error } /** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */ export interface SemicolonClassElement extends ClassElement { - kind: SyntaxKind.SemicolonClassElement; - parent: ClassLikeDeclaration; + readonly kind: SyntaxKind.SemicolonClassElement; + readonly parent: ClassLikeDeclaration; } // See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a // ClassElement and an ObjectLiteralElement. export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.GetAccessor; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.GetAccessor; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; + /* @internal */ typeParameters?: NodeArray; // Present for use with reporting a grammar error } // See the comment on MethodDeclaration for the intuition behind SetAccessorDeclaration being a // ClassElement and an ObjectLiteralElement. export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.SetAccessor; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.SetAccessor; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; + /* @internal */ typeParameters?: NodeArray; // Present for use with reporting a grammar error + /* @internal */ type?: TypeNode; // Present for use with reporting a grammar error } export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration; export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { - kind: SyntaxKind.IndexSignature; - parent: ObjectTypeDeclaration; + readonly kind: SyntaxKind.IndexSignature; + readonly parent: ObjectTypeDeclaration; + readonly type: TypeNode; } export interface TypeNode extends Node { _typeNodeBrand: any; } - export interface KeywordTypeNode extends TypeNode { - kind: - | SyntaxKind.AnyKeyword - | SyntaxKind.UnknownKeyword - | SyntaxKind.NumberKeyword - | SyntaxKind.BigIntKeyword - | SyntaxKind.ObjectKeyword - | SyntaxKind.BooleanKeyword - | SyntaxKind.StringKeyword - | SyntaxKind.SymbolKeyword - | SyntaxKind.ThisKeyword - | SyntaxKind.VoidKeyword - | SyntaxKind.UndefinedKeyword - | SyntaxKind.NullKeyword - | SyntaxKind.NeverKeyword; + /* @internal */ + export interface TypeNode extends Node { + readonly kind: TypeNodeSyntaxKind; + } + + export interface KeywordTypeNode extends KeywordToken, TypeNode { + readonly kind: TKind; } export interface ImportTypeNode extends NodeWithTypeArguments { - kind: SyntaxKind.ImportType; - isTypeOf?: boolean; - argument: TypeNode; - qualifier?: EntityName; + readonly kind: SyntaxKind.ImportType; + readonly isTypeOf: boolean; + readonly argument: TypeNode; + readonly qualifier?: EntityName; } /* @internal */ - export type LiteralImportTypeNode = ImportTypeNode & { argument: LiteralTypeNode & { literal: StringLiteral } }; + export type LiteralImportTypeNode = ImportTypeNode & { readonly argument: LiteralTypeNode & { readonly literal: StringLiteral } }; export interface ThisTypeNode extends TypeNode { - kind: SyntaxKind.ThisType; + readonly kind: SyntaxKind.ThisType; } export type FunctionOrConstructorTypeNode = FunctionTypeNode | ConstructorTypeNode; export interface FunctionOrConstructorTypeNodeBase extends TypeNode, SignatureDeclarationBase { - kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType; - type: TypeNode; + readonly kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType; + readonly type: TypeNode; } export interface FunctionTypeNode extends FunctionOrConstructorTypeNodeBase { - kind: SyntaxKind.FunctionType; + readonly kind: SyntaxKind.FunctionType; } export interface ConstructorTypeNode extends FunctionOrConstructorTypeNodeBase { - kind: SyntaxKind.ConstructorType; + readonly kind: SyntaxKind.ConstructorType; } export interface NodeWithTypeArguments extends TypeNode { - typeArguments?: NodeArray; + readonly typeArguments?: NodeArray; } export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments; export interface TypeReferenceNode extends NodeWithTypeArguments { - kind: SyntaxKind.TypeReference; - typeName: EntityName; + readonly kind: SyntaxKind.TypeReference; + readonly typeName: EntityName; } export interface TypePredicateNode extends TypeNode { - kind: SyntaxKind.TypePredicate; - parent: SignatureDeclaration | JSDocTypeExpression; - assertsModifier?: AssertsToken; - parameterName: Identifier | ThisTypeNode; - type?: TypeNode; + readonly kind: SyntaxKind.TypePredicate; + readonly parent: SignatureDeclaration | JSDocTypeExpression; + readonly assertsModifier?: AssertsToken; + readonly parameterName: Identifier | ThisTypeNode; + readonly type?: TypeNode; } export interface TypeQueryNode extends TypeNode { - kind: SyntaxKind.TypeQuery; - exprName: EntityName; + readonly kind: SyntaxKind.TypeQuery; + readonly exprName: EntityName; } // A TypeLiteral is the declaration node for an anonymous symbol. export interface TypeLiteralNode extends TypeNode, Declaration { - kind: SyntaxKind.TypeLiteral; - members: NodeArray; + readonly kind: SyntaxKind.TypeLiteral; + readonly members: NodeArray; } export interface ArrayTypeNode extends TypeNode { - kind: SyntaxKind.ArrayType; - elementType: TypeNode; + readonly kind: SyntaxKind.ArrayType; + readonly elementType: TypeNode; } export interface TupleTypeNode extends TypeNode { - kind: SyntaxKind.TupleType; - elements: NodeArray; + readonly kind: SyntaxKind.TupleType; + readonly elements: NodeArray; } export interface NamedTupleMember extends TypeNode, JSDocContainer, Declaration { - kind: SyntaxKind.NamedTupleMember; - dotDotDotToken?: Token; - name: Identifier; - questionToken?: Token; - type: TypeNode; + readonly kind: SyntaxKind.NamedTupleMember; + readonly dotDotDotToken?: Token; + readonly name: Identifier; + readonly questionToken?: Token; + readonly type: TypeNode; } export interface OptionalTypeNode extends TypeNode { - kind: SyntaxKind.OptionalType; - type: TypeNode; + readonly kind: SyntaxKind.OptionalType; + readonly type: TypeNode; } export interface RestTypeNode extends TypeNode { - kind: SyntaxKind.RestType; - type: TypeNode; + readonly kind: SyntaxKind.RestType; + readonly type: TypeNode; } export type UnionOrIntersectionTypeNode = UnionTypeNode | IntersectionTypeNode; export interface UnionTypeNode extends TypeNode { - kind: SyntaxKind.UnionType; - types: NodeArray; + readonly kind: SyntaxKind.UnionType; + readonly types: NodeArray; } export interface IntersectionTypeNode extends TypeNode { - kind: SyntaxKind.IntersectionType; - types: NodeArray; + readonly kind: SyntaxKind.IntersectionType; + readonly types: NodeArray; } export interface ConditionalTypeNode extends TypeNode { - kind: SyntaxKind.ConditionalType; - checkType: TypeNode; - extendsType: TypeNode; - trueType: TypeNode; - falseType: TypeNode; + readonly kind: SyntaxKind.ConditionalType; + readonly checkType: TypeNode; + readonly extendsType: TypeNode; + readonly trueType: TypeNode; + readonly falseType: TypeNode; } export interface InferTypeNode extends TypeNode { - kind: SyntaxKind.InferType; - typeParameter: TypeParameterDeclaration; + readonly kind: SyntaxKind.InferType; + readonly typeParameter: TypeParameterDeclaration; } export interface ParenthesizedTypeNode extends TypeNode { - kind: SyntaxKind.ParenthesizedType; - type: TypeNode; + readonly kind: SyntaxKind.ParenthesizedType; + readonly type: TypeNode; } export interface TypeOperatorNode extends TypeNode { - kind: SyntaxKind.TypeOperator; - operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword; - type: TypeNode; + readonly kind: SyntaxKind.TypeOperator; + readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword; + readonly type: TypeNode; } /* @internal */ export interface UniqueTypeOperatorNode extends TypeOperatorNode { - operator: SyntaxKind.UniqueKeyword; + readonly operator: SyntaxKind.UniqueKeyword; } export interface IndexedAccessTypeNode extends TypeNode { - kind: SyntaxKind.IndexedAccessType; - objectType: TypeNode; - indexType: TypeNode; + readonly kind: SyntaxKind.IndexedAccessType; + readonly objectType: TypeNode; + readonly indexType: TypeNode; } export interface MappedTypeNode extends TypeNode, Declaration { - kind: SyntaxKind.MappedType; - readonlyToken?: ReadonlyToken | PlusToken | MinusToken; - typeParameter: TypeParameterDeclaration; - questionToken?: QuestionToken | PlusToken | MinusToken; - type?: TypeNode; + readonly kind: SyntaxKind.MappedType; + readonly readonlyToken?: ReadonlyToken | PlusToken | MinusToken; + readonly typeParameter: TypeParameterDeclaration; + readonly questionToken?: QuestionToken | PlusToken | MinusToken; + readonly type?: TypeNode; } export interface LiteralTypeNode extends TypeNode { - kind: SyntaxKind.LiteralType; - literal: BooleanLiteral | LiteralExpression | PrefixUnaryExpression; + readonly kind: SyntaxKind.LiteralType; + readonly literal: NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression; } export interface StringLiteral extends LiteralExpression, Declaration { - kind: SyntaxKind.StringLiteral; - /* @internal */ textSourceNode?: Identifier | StringLiteralLike | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). + readonly kind: SyntaxKind.StringLiteral; + /* @internal */ readonly textSourceNode?: Identifier | StringLiteralLike | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). /** Note: this is only set when synthesizing a node, not during parsing. */ - /* @internal */ singleQuote?: boolean; + /* @internal */ readonly singleQuote?: boolean; } export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral; + export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral; // Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing. // Consider 'Expression'. Without the brand, 'Expression' is actually no different @@ -1381,14 +1644,14 @@ namespace ts { } export interface OmittedExpression extends Expression { - kind: SyntaxKind.OmittedExpression; + readonly kind: SyntaxKind.OmittedExpression; } // Represents an expression that is elided as part of a transformation to emit comments on a // not-emitted node. The 'expression' property of a PartiallyEmittedExpression should be emitted. export interface PartiallyEmittedExpression extends LeftHandSideExpression { - kind: SyntaxKind.PartiallyEmittedExpression; - expression: Expression; + readonly kind: SyntaxKind.PartiallyEmittedExpression; + readonly expression: Expression; } export interface UnaryExpression extends Expression { @@ -1412,9 +1675,9 @@ namespace ts { | SyntaxKind.ExclamationToken; export interface PrefixUnaryExpression extends UpdateExpression { - kind: SyntaxKind.PrefixUnaryExpression; - operator: PrefixUnaryOperator; - operand: UnaryExpression; + readonly kind: SyntaxKind.PrefixUnaryExpression; + readonly operator: PrefixUnaryOperator; + readonly operand: UnaryExpression; } // see: https://tc39.github.io/ecma262/#prod-UpdateExpression @@ -1424,9 +1687,9 @@ namespace ts { ; export interface PostfixUnaryExpression extends UpdateExpression { - kind: SyntaxKind.PostfixUnaryExpression; - operand: LeftHandSideExpression; - operator: PostfixUnaryOperator; + readonly kind: SyntaxKind.PostfixUnaryExpression; + readonly operand: LeftHandSideExpression; + readonly operator: PostfixUnaryOperator; } export interface LeftHandSideExpression extends UpdateExpression { @@ -1441,105 +1704,111 @@ namespace ts { _primaryExpressionBrand: any; } - export interface NullLiteral extends PrimaryExpression, TypeNode { - kind: SyntaxKind.NullKeyword; + export interface NullLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.NullKeyword; + } + + export interface TrueLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.TrueKeyword; } - export interface BooleanLiteral extends PrimaryExpression, TypeNode { - kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword; + export interface FalseLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.FalseKeyword; } - export interface ThisExpression extends PrimaryExpression, KeywordTypeNode { - kind: SyntaxKind.ThisKeyword; + export type BooleanLiteral = TrueLiteral | FalseLiteral; + + export interface ThisExpression extends PrimaryExpression { + readonly kind: SyntaxKind.ThisKeyword; } export interface SuperExpression extends PrimaryExpression { - kind: SyntaxKind.SuperKeyword; + readonly kind: SyntaxKind.SuperKeyword; } export interface ImportExpression extends PrimaryExpression { - kind: SyntaxKind.ImportKeyword; + readonly kind: SyntaxKind.ImportKeyword; } export interface DeleteExpression extends UnaryExpression { - kind: SyntaxKind.DeleteExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.DeleteExpression; + readonly expression: UnaryExpression; } export interface TypeOfExpression extends UnaryExpression { - kind: SyntaxKind.TypeOfExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.TypeOfExpression; + readonly expression: UnaryExpression; } export interface VoidExpression extends UnaryExpression { - kind: SyntaxKind.VoidExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.VoidExpression; + readonly expression: UnaryExpression; } export interface AwaitExpression extends UnaryExpression { - kind: SyntaxKind.AwaitExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.AwaitExpression; + readonly expression: UnaryExpression; } export interface YieldExpression extends Expression { - kind: SyntaxKind.YieldExpression; - asteriskToken?: AsteriskToken; - expression?: Expression; + readonly kind: SyntaxKind.YieldExpression; + readonly asteriskToken?: AsteriskToken; + readonly expression?: Expression; } export interface SyntheticExpression extends Expression { - kind: SyntaxKind.SyntheticExpression; - isSpread: boolean; - type: Type; - tupleNameSource?: ParameterDeclaration | NamedTupleMember; + readonly kind: SyntaxKind.SyntheticExpression; + readonly isSpread: boolean; + readonly type: Type; + readonly tupleNameSource?: ParameterDeclaration | NamedTupleMember; } // see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression - export type ExponentiationOperator - = SyntaxKind.AsteriskAsteriskToken + export type ExponentiationOperator = + | SyntaxKind.AsteriskAsteriskToken ; // see: https://tc39.github.io/ecma262/#prod-MultiplicativeOperator - export type MultiplicativeOperator - = SyntaxKind.AsteriskToken + export type MultiplicativeOperator = + | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken ; // see: https://tc39.github.io/ecma262/#prod-MultiplicativeExpression - export type MultiplicativeOperatorOrHigher - = ExponentiationOperator + export type MultiplicativeOperatorOrHigher = + | ExponentiationOperator | MultiplicativeOperator ; // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression - export type AdditiveOperator - = SyntaxKind.PlusToken + export type AdditiveOperator = + | SyntaxKind.PlusToken | SyntaxKind.MinusToken ; // see: https://tc39.github.io/ecma262/#prod-AdditiveExpression - export type AdditiveOperatorOrHigher - = MultiplicativeOperatorOrHigher + export type AdditiveOperatorOrHigher = + | MultiplicativeOperatorOrHigher | AdditiveOperator ; // see: https://tc39.github.io/ecma262/#prod-ShiftExpression - export type ShiftOperator - = SyntaxKind.LessThanLessThanToken + export type ShiftOperator = + | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken ; // see: https://tc39.github.io/ecma262/#prod-ShiftExpression - export type ShiftOperatorOrHigher - = AdditiveOperatorOrHigher + export type ShiftOperatorOrHigher = + | AdditiveOperatorOrHigher | ShiftOperator ; // see: https://tc39.github.io/ecma262/#prod-RelationalExpression - export type RelationalOperator - = SyntaxKind.LessThanToken + export type RelationalOperator = + | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken @@ -1548,29 +1817,29 @@ namespace ts { ; // see: https://tc39.github.io/ecma262/#prod-RelationalExpression - export type RelationalOperatorOrHigher - = ShiftOperatorOrHigher + export type RelationalOperatorOrHigher = + | ShiftOperatorOrHigher | RelationalOperator ; // see: https://tc39.github.io/ecma262/#prod-EqualityExpression - export type EqualityOperator - = SyntaxKind.EqualsEqualsToken + export type EqualityOperator = + | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken ; // see: https://tc39.github.io/ecma262/#prod-EqualityExpression - export type EqualityOperatorOrHigher - = RelationalOperatorOrHigher + export type EqualityOperatorOrHigher = + | RelationalOperatorOrHigher | EqualityOperator; // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression - export type BitwiseOperator - = SyntaxKind.AmpersandToken + export type BitwiseOperator = + | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken ; @@ -1578,28 +1847,28 @@ namespace ts { // see: https://tc39.github.io/ecma262/#prod-BitwiseANDExpression // see: https://tc39.github.io/ecma262/#prod-BitwiseXORExpression // see: https://tc39.github.io/ecma262/#prod-BitwiseORExpression - export type BitwiseOperatorOrHigher - = EqualityOperatorOrHigher + export type BitwiseOperatorOrHigher = + | EqualityOperatorOrHigher | BitwiseOperator ; // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression - export type LogicalOperator - = SyntaxKind.AmpersandAmpersandToken + export type LogicalOperator = + | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken ; // see: https://tc39.github.io/ecma262/#prod-LogicalANDExpression // see: https://tc39.github.io/ecma262/#prod-LogicalORExpression - export type LogicalOperatorOrHigher - = BitwiseOperatorOrHigher + export type LogicalOperatorOrHigher = + | BitwiseOperatorOrHigher | LogicalOperator ; // see: https://tc39.github.io/ecma262/#prod-AssignmentOperator - export type CompoundAssignmentOperator - = SyntaxKind.PlusEqualsToken + export type CompoundAssignmentOperator = + | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken @@ -1617,21 +1886,21 @@ namespace ts { ; // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression - export type AssignmentOperator - = SyntaxKind.EqualsToken + export type AssignmentOperator = + | SyntaxKind.EqualsToken | CompoundAssignmentOperator ; // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression - export type AssignmentOperatorOrHigher - = SyntaxKind.QuestionQuestionToken + export type AssignmentOperatorOrHigher = + | SyntaxKind.QuestionQuestionToken | LogicalOperatorOrHigher | AssignmentOperator ; // see: https://tc39.github.io/ecma262/#prod-Expression - export type BinaryOperator - = AssignmentOperatorOrHigher + export type BinaryOperator = + | AssignmentOperatorOrHigher | SyntaxKind.CommaToken ; @@ -1644,39 +1913,48 @@ namespace ts { export type BinaryOperatorToken = Token; export interface BinaryExpression extends Expression, Declaration { - kind: SyntaxKind.BinaryExpression; - left: Expression; - operatorToken: BinaryOperatorToken; - right: Expression; + readonly kind: SyntaxKind.BinaryExpression; + readonly left: Expression; + readonly operatorToken: BinaryOperatorToken; + readonly right: Expression; } export type AssignmentOperatorToken = Token; export interface AssignmentExpression extends BinaryExpression { - left: LeftHandSideExpression; - operatorToken: TOperator; + readonly left: LeftHandSideExpression; + readonly operatorToken: TOperator; } export interface ObjectDestructuringAssignment extends AssignmentExpression { - left: ObjectLiteralExpression; + readonly left: ObjectLiteralExpression; } export interface ArrayDestructuringAssignment extends AssignmentExpression { - left: ArrayLiteralExpression; + readonly left: ArrayLiteralExpression; } - export type DestructuringAssignment - = ObjectDestructuringAssignment + export type DestructuringAssignment = + | ObjectDestructuringAssignment | ArrayDestructuringAssignment ; - export type BindingOrAssignmentElement - = VariableDeclaration + export type BindingOrAssignmentElement = + | VariableDeclaration | ParameterDeclaration + | ObjectBindingOrAssignmentElement + | ArrayBindingOrAssignmentElement + ; + + export type ObjectBindingOrAssignmentElement = | BindingElement | PropertyAssignment // AssignmentProperty | ShorthandPropertyAssignment // AssignmentProperty | SpreadAssignment // AssignmentRestProperty + ; + + export type ArrayBindingOrAssignmentElement = + | BindingElement | OmittedExpression // Elision | SpreadElement // AssignmentRestElement | ArrayLiteralExpression // ArrayAssignmentPattern @@ -1687,21 +1965,26 @@ namespace ts { | ElementAccessExpression // DestructuringAssignmentTarget ; - export type BindingOrAssignmentElementRestIndicator - = DotDotDotToken // from BindingElement + export type BindingOrAssignmentElementRestIndicator = + | DotDotDotToken // from BindingElement | SpreadElement // AssignmentRestElement | SpreadAssignment // AssignmentRestProperty ; - export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; + export type BindingOrAssignmentElementTarget = + | BindingOrAssignmentPattern + | Identifier + | PropertyAccessExpression + | ElementAccessExpression + | OmittedExpression; - export type ObjectBindingOrAssignmentPattern - = ObjectBindingPattern + export type ObjectBindingOrAssignmentPattern = + | ObjectBindingPattern | ObjectLiteralExpression // ObjectAssignmentPattern ; - export type ArrayBindingOrAssignmentPattern - = ArrayBindingPattern + export type ArrayBindingOrAssignmentPattern = + | ArrayBindingPattern | ArrayLiteralExpression // ArrayAssignmentPattern ; @@ -1710,28 +1993,28 @@ namespace ts { export type BindingOrAssignmentPattern = ObjectBindingOrAssignmentPattern | ArrayBindingOrAssignmentPattern; export interface ConditionalExpression extends Expression { - kind: SyntaxKind.ConditionalExpression; - condition: Expression; - questionToken: QuestionToken; - whenTrue: Expression; - colonToken: ColonToken; - whenFalse: Expression; + readonly kind: SyntaxKind.ConditionalExpression; + readonly condition: Expression; + readonly questionToken: QuestionToken; + readonly whenTrue: Expression; + readonly colonToken: ColonToken; + readonly whenFalse: Expression; } export type FunctionBody = Block; export type ConciseBody = FunctionBody | Expression; export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { - kind: SyntaxKind.FunctionExpression; - name?: Identifier; - body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional + readonly kind: SyntaxKind.FunctionExpression; + readonly name?: Identifier; + readonly body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional } export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase, JSDocContainer { - kind: SyntaxKind.ArrowFunction; - equalsGreaterThanToken: EqualsGreaterThanToken; - body: ConciseBody; - name: never; + readonly kind: SyntaxKind.ArrowFunction; + readonly equalsGreaterThanToken: EqualsGreaterThanToken; + readonly body: ConciseBody; + readonly name: never; } // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, @@ -1745,6 +2028,8 @@ namespace ts { export interface TemplateLiteralLikeNode extends LiteralLikeNode { rawText?: string; + /* @internal */ + templateFlags?: TokenFlags; } // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, @@ -1755,11 +2040,11 @@ namespace ts { } export interface RegularExpressionLiteral extends LiteralExpression { - kind: SyntaxKind.RegularExpressionLiteral; + readonly kind: SyntaxKind.RegularExpressionLiteral; } export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode, Declaration { - kind: SyntaxKind.NoSubstitutionTemplateLiteral; + readonly kind: SyntaxKind.NoSubstitutionTemplateLiteral; /* @internal */ templateFlags?: TokenFlags; } @@ -1788,73 +2073,98 @@ namespace ts { /* @internal */ BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier, /* @internal */ - NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinaryOrOctalSpecifier | ContainsSeparator + NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinaryOrOctalSpecifier | ContainsSeparator, + /* @internal */ + TemplateLiteralLikeFlags = ContainsInvalidEscape, } export interface NumericLiteral extends LiteralExpression, Declaration { - kind: SyntaxKind.NumericLiteral; + readonly kind: SyntaxKind.NumericLiteral; /* @internal */ - numericLiteralFlags: TokenFlags; + readonly numericLiteralFlags: TokenFlags; } export interface BigIntLiteral extends LiteralExpression { - kind: SyntaxKind.BigIntLiteral; + readonly kind: SyntaxKind.BigIntLiteral; } + export type LiteralToken = + | NumericLiteral + | BigIntLiteral + | StringLiteral + | JsxText + | RegularExpressionLiteral + | NoSubstitutionTemplateLiteral + ; + export interface TemplateHead extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateHead; - parent: TemplateExpression; + readonly kind: SyntaxKind.TemplateHead; + readonly parent: TemplateExpression; /* @internal */ templateFlags?: TokenFlags; } export interface TemplateMiddle extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateMiddle; - parent: TemplateSpan; + readonly kind: SyntaxKind.TemplateMiddle; + readonly parent: TemplateSpan; /* @internal */ templateFlags?: TokenFlags; } export interface TemplateTail extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateTail; - parent: TemplateSpan; + readonly kind: SyntaxKind.TemplateTail; + readonly parent: TemplateSpan; /* @internal */ templateFlags?: TokenFlags; } - export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral; + export type PseudoLiteralToken = + | TemplateHead + | TemplateMiddle + | TemplateTail + ; + + export type TemplateLiteralToken = + | NoSubstitutionTemplateLiteral + | PseudoLiteralToken + ; export interface TemplateExpression extends PrimaryExpression { - kind: SyntaxKind.TemplateExpression; - head: TemplateHead; - templateSpans: NodeArray; + readonly kind: SyntaxKind.TemplateExpression; + readonly head: TemplateHead; + readonly templateSpans: NodeArray; } + export type TemplateLiteral = + | TemplateExpression + | NoSubstitutionTemplateLiteral + ; + // Each of these corresponds to a substitution expression and a template literal, in that order. // The template literal must have kind TemplateMiddleLiteral or TemplateTailLiteral. export interface TemplateSpan extends Node { - kind: SyntaxKind.TemplateSpan; - parent: TemplateExpression; - expression: Expression; - literal: TemplateMiddle | TemplateTail; + readonly kind: SyntaxKind.TemplateSpan; + readonly parent: TemplateExpression; + readonly expression: Expression; + readonly literal: TemplateMiddle | TemplateTail; } export interface ParenthesizedExpression extends PrimaryExpression, JSDocContainer { - kind: SyntaxKind.ParenthesizedExpression; - expression: Expression; + readonly kind: SyntaxKind.ParenthesizedExpression; + readonly expression: Expression; } export interface ArrayLiteralExpression extends PrimaryExpression { - kind: SyntaxKind.ArrayLiteralExpression; - elements: NodeArray; + readonly kind: SyntaxKind.ArrayLiteralExpression; + readonly elements: NodeArray; /* @internal */ multiLine?: boolean; } export interface SpreadElement extends Expression { - kind: SyntaxKind.SpreadElement; - parent: ArrayLiteralExpression | CallExpression | NewExpression; - expression: Expression; + readonly kind: SyntaxKind.SpreadElement; + readonly parent: ArrayLiteralExpression | CallExpression | NewExpression; + readonly expression: Expression; } /** @@ -1864,60 +2174,58 @@ namespace ts { * ObjectLiteralElement (e.g. PropertyAssignment, ShorthandPropertyAssignment etc.) */ export interface ObjectLiteralExpressionBase extends PrimaryExpression, Declaration { - properties: NodeArray; + readonly properties: NodeArray; } // An ObjectLiteralExpression is the declaration node for an anonymous symbol. export interface ObjectLiteralExpression extends ObjectLiteralExpressionBase { - kind: SyntaxKind.ObjectLiteralExpression; + readonly kind: SyntaxKind.ObjectLiteralExpression; /* @internal */ multiLine?: boolean; } export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression; export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; - - /* @internal */ export type AccessExpression = PropertyAccessExpression | ElementAccessExpression; export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration { - kind: SyntaxKind.PropertyAccessExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - name: Identifier | PrivateIdentifier; + readonly kind: SyntaxKind.PropertyAccessExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly name: Identifier | PrivateIdentifier; } /*@internal*/ export interface PrivateIdentifierPropertyAccessExpression extends PropertyAccessExpression { - name: PrivateIdentifier; + readonly name: PrivateIdentifier; } export interface PropertyAccessChain extends PropertyAccessExpression { _optionalChainBrand: any; - name: Identifier; + readonly name: Identifier | PrivateIdentifier; } /* @internal */ export interface PropertyAccessChainRoot extends PropertyAccessChain { - questionDotToken: QuestionDotToken; + readonly questionDotToken: QuestionDotToken; } export interface SuperPropertyAccessExpression extends PropertyAccessExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; - expression: EntityNameExpression; - name: Identifier; + readonly expression: EntityNameExpression; + readonly name: Identifier; } export interface ElementAccessExpression extends MemberExpression { - kind: SyntaxKind.ElementAccessExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - argumentExpression: Expression; + readonly kind: SyntaxKind.ElementAccessExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly argumentExpression: Expression; } export interface ElementAccessChain extends ElementAccessExpression { @@ -1926,22 +2234,22 @@ namespace ts { /* @internal */ export interface ElementAccessChainRoot extends ElementAccessChain { - questionDotToken: QuestionDotToken; + readonly questionDotToken: QuestionDotToken; } export interface SuperElementAccessExpression extends ElementAccessExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } // see: https://tc39.github.io/ecma262/#prod-SuperProperty export type SuperProperty = SuperPropertyAccessExpression | SuperElementAccessExpression; export interface CallExpression extends LeftHandSideExpression, Declaration { - kind: SyntaxKind.CallExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - typeArguments?: NodeArray; - arguments: NodeArray; + readonly kind: SyntaxKind.CallExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly typeArguments?: NodeArray; + readonly arguments: NodeArray; } export interface CallChain extends CallExpression { @@ -1950,7 +2258,7 @@ namespace ts { /* @internal */ export interface CallChainRoot extends CallChain { - questionDotToken: QuestionDotToken; + readonly questionDotToken: QuestionDotToken; } export type OptionalChain = @@ -1969,87 +2277,116 @@ namespace ts { /** @internal */ export interface WellKnownSymbolExpression extends PropertyAccessExpression { - expression: Identifier & { escapedText: "Symbol" }; - name: Identifier; + readonly expression: Identifier & { readonly escapedText: __String & "Symbol" }; + readonly name: Identifier; } + /** @internal */ - export type BindableObjectDefinePropertyCall = CallExpression & { arguments: { 0: BindableStaticNameExpression, 1: StringLiteralLike | NumericLiteral, 2: ObjectLiteralExpression } }; + export type BindableObjectDefinePropertyCall = CallExpression & { + readonly arguments: readonly [BindableStaticNameExpression, StringLiteralLike | NumericLiteral, ObjectLiteralExpression] & Readonly; + }; + /** @internal */ - export type BindableStaticNameExpression = EntityNameExpression | BindableStaticElementAccessExpression; + export type BindableStaticNameExpression = + | EntityNameExpression + | BindableStaticElementAccessExpression + ; + /** @internal */ export type LiteralLikeElementAccessExpression = ElementAccessExpression & Declaration & { - argumentExpression: StringLiteralLike | NumericLiteral | WellKnownSymbolExpression; + readonly argumentExpression: StringLiteralLike | NumericLiteral | WellKnownSymbolExpression; }; + /** @internal */ export type BindableStaticElementAccessExpression = LiteralLikeElementAccessExpression & { - expression: BindableStaticNameExpression; + readonly expression: BindableStaticNameExpression; }; + /** @internal */ export type BindableElementAccessExpression = ElementAccessExpression & { - expression: BindableStaticNameExpression; + readonly expression: BindableStaticNameExpression; }; + /** @internal */ - export type BindableStaticAccessExpression = PropertyAccessEntityNameExpression | BindableStaticElementAccessExpression; + export type BindableStaticAccessExpression = + | PropertyAccessEntityNameExpression + | BindableStaticElementAccessExpression + ; + /** @internal */ - export type BindableAccessExpression = PropertyAccessEntityNameExpression | BindableElementAccessExpression; + export type BindableAccessExpression = + | PropertyAccessEntityNameExpression + | BindableElementAccessExpression + ; + /** @internal */ export interface BindableStaticPropertyAssignmentExpression extends BinaryExpression { - left: BindableStaticAccessExpression; + readonly left: BindableStaticAccessExpression; } + /** @internal */ export interface BindablePropertyAssignmentExpression extends BinaryExpression { - left: BindableAccessExpression; + readonly left: BindableAccessExpression; } // see: https://tc39.github.io/ecma262/#prod-SuperCall export interface SuperCall extends CallExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } export interface ImportCall extends CallExpression { - expression: ImportExpression; + readonly expression: ImportExpression; } export interface ExpressionWithTypeArguments extends NodeWithTypeArguments { - kind: SyntaxKind.ExpressionWithTypeArguments; - parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; - expression: LeftHandSideExpression; + readonly kind: SyntaxKind.ExpressionWithTypeArguments; + readonly parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; + readonly expression: LeftHandSideExpression; } export interface NewExpression extends PrimaryExpression, Declaration { - kind: SyntaxKind.NewExpression; - expression: LeftHandSideExpression; - typeArguments?: NodeArray; - arguments?: NodeArray; + readonly kind: SyntaxKind.NewExpression; + readonly expression: LeftHandSideExpression; + readonly typeArguments?: NodeArray; + readonly arguments?: NodeArray; } export interface TaggedTemplateExpression extends MemberExpression { - kind: SyntaxKind.TaggedTemplateExpression; - tag: LeftHandSideExpression; - typeArguments?: NodeArray; - template: TemplateLiteral; + readonly kind: SyntaxKind.TaggedTemplateExpression; + readonly tag: LeftHandSideExpression; + readonly typeArguments?: NodeArray; + readonly template: TemplateLiteral; /*@internal*/ questionDotToken?: QuestionDotToken; // NOTE: Invalid syntax, only used to report a grammar error. } - export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; + export type CallLikeExpression = + | CallExpression + | NewExpression + | TaggedTemplateExpression + | Decorator + | JsxOpeningLikeElement + ; export interface AsExpression extends Expression { - kind: SyntaxKind.AsExpression; - expression: Expression; - type: TypeNode; + readonly kind: SyntaxKind.AsExpression; + readonly expression: Expression; + readonly type: TypeNode; } export interface TypeAssertion extends UnaryExpression { - kind: SyntaxKind.TypeAssertionExpression; - type: TypeNode; - expression: UnaryExpression; + readonly kind: SyntaxKind.TypeAssertionExpression; + readonly type: TypeNode; + readonly expression: UnaryExpression; } - export type AssertionExpression = TypeAssertion | AsExpression; + export type AssertionExpression = + | TypeAssertion + | AsExpression + ; export interface NonNullExpression extends LeftHandSideExpression { - kind: SyntaxKind.NonNullExpression; - expression: Expression; + readonly kind: SyntaxKind.NonNullExpression; + readonly expression: Expression; } export interface NonNullChain extends NonNullExpression { @@ -2059,112 +2396,128 @@ namespace ts { // NOTE: MetaProperty is really a MemberExpression, but we consider it a PrimaryExpression // for the same reasons we treat NewExpression as a PrimaryExpression. export interface MetaProperty extends PrimaryExpression { - kind: SyntaxKind.MetaProperty; - keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; - name: Identifier; + readonly kind: SyntaxKind.MetaProperty; + readonly keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; + readonly name: Identifier; } /* @internal */ export interface ImportMetaProperty extends MetaProperty { - keywordToken: SyntaxKind.ImportKeyword; - name: Identifier & { escapedText: __String & "meta" }; + readonly keywordToken: SyntaxKind.ImportKeyword; + readonly name: Identifier & { readonly escapedText: __String & "meta" }; } /// A JSX expression of the form ... export interface JsxElement extends PrimaryExpression { - kind: SyntaxKind.JsxElement; - openingElement: JsxOpeningElement; - children: NodeArray; - closingElement: JsxClosingElement; + readonly kind: SyntaxKind.JsxElement; + readonly openingElement: JsxOpeningElement; + readonly children: NodeArray; + readonly closingElement: JsxClosingElement; } /// Either the opening tag in a ... pair or the lone in a self-closing form - export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; + export type JsxOpeningLikeElement = + | JsxSelfClosingElement + | JsxOpeningElement + ; - export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; + export type JsxAttributeLike = + | JsxAttribute + | JsxSpreadAttribute + ; - export type JsxTagNameExpression = Identifier | ThisExpression | JsxTagNamePropertyAccess; + export type JsxTagNameExpression = + | Identifier + | ThisExpression + | JsxTagNamePropertyAccess + ; export interface JsxTagNamePropertyAccess extends PropertyAccessExpression { - expression: JsxTagNameExpression; + readonly expression: JsxTagNameExpression; } export interface JsxAttributes extends ObjectLiteralExpressionBase { - kind: SyntaxKind.JsxAttributes; - parent: JsxOpeningLikeElement; + readonly kind: SyntaxKind.JsxAttributes; + readonly parent: JsxOpeningLikeElement; } /// The opening element of a ... JsxElement export interface JsxOpeningElement extends Expression { - kind: SyntaxKind.JsxOpeningElement; - parent: JsxElement; - tagName: JsxTagNameExpression; - typeArguments?: NodeArray; - attributes: JsxAttributes; + readonly kind: SyntaxKind.JsxOpeningElement; + readonly parent: JsxElement; + readonly tagName: JsxTagNameExpression; + readonly typeArguments?: NodeArray; + readonly attributes: JsxAttributes; } /// A JSX expression of the form export interface JsxSelfClosingElement extends PrimaryExpression { - kind: SyntaxKind.JsxSelfClosingElement; - tagName: JsxTagNameExpression; - typeArguments?: NodeArray; - attributes: JsxAttributes; + readonly kind: SyntaxKind.JsxSelfClosingElement; + readonly tagName: JsxTagNameExpression; + readonly typeArguments?: NodeArray; + readonly attributes: JsxAttributes; } /// A JSX expression of the form <>... export interface JsxFragment extends PrimaryExpression { - kind: SyntaxKind.JsxFragment; - openingFragment: JsxOpeningFragment; - children: NodeArray; - closingFragment: JsxClosingFragment; + readonly kind: SyntaxKind.JsxFragment; + readonly openingFragment: JsxOpeningFragment; + readonly children: NodeArray; + readonly closingFragment: JsxClosingFragment; } /// The opening element of a <>... JsxFragment export interface JsxOpeningFragment extends Expression { - kind: SyntaxKind.JsxOpeningFragment; - parent: JsxFragment; + readonly kind: SyntaxKind.JsxOpeningFragment; + readonly parent: JsxFragment; } /// The closing element of a <>... JsxFragment export interface JsxClosingFragment extends Expression { - kind: SyntaxKind.JsxClosingFragment; - parent: JsxFragment; + readonly kind: SyntaxKind.JsxClosingFragment; + readonly parent: JsxFragment; } export interface JsxAttribute extends ObjectLiteralElement { - kind: SyntaxKind.JsxAttribute; - parent: JsxAttributes; - name: Identifier; + readonly kind: SyntaxKind.JsxAttribute; + readonly parent: JsxAttributes; + readonly name: Identifier; /// JSX attribute initializers are optional; is sugar for - initializer?: StringLiteral | JsxExpression; + readonly initializer?: StringLiteral | JsxExpression; } export interface JsxSpreadAttribute extends ObjectLiteralElement { - kind: SyntaxKind.JsxSpreadAttribute; - parent: JsxAttributes; - expression: Expression; + readonly kind: SyntaxKind.JsxSpreadAttribute; + readonly parent: JsxAttributes; + readonly expression: Expression; } export interface JsxClosingElement extends Node { - kind: SyntaxKind.JsxClosingElement; - parent: JsxElement; - tagName: JsxTagNameExpression; + readonly kind: SyntaxKind.JsxClosingElement; + readonly parent: JsxElement; + readonly tagName: JsxTagNameExpression; } export interface JsxExpression extends Expression { - kind: SyntaxKind.JsxExpression; - parent: JsxElement | JsxAttributeLike; - dotDotDotToken?: Token; - expression?: Expression; + readonly kind: SyntaxKind.JsxExpression; + readonly parent: JsxElement | JsxAttributeLike; + readonly dotDotDotToken?: Token; + readonly expression?: Expression; } export interface JsxText extends LiteralLikeNode { - kind: SyntaxKind.JsxText; - containsOnlyTriviaWhiteSpaces: boolean; - parent: JsxElement; + readonly kind: SyntaxKind.JsxText; + readonly parent: JsxElement; + readonly containsOnlyTriviaWhiteSpaces: boolean; } - export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment; + export type JsxChild = + | JsxText + | JsxExpression + | JsxElement + | JsxSelfClosingElement + | JsxFragment + ; export interface Statement extends Node { _statementBrand: any; @@ -2173,7 +2526,7 @@ namespace ts { // Represents a statement that is elided as part of a transformation to emit comments on a // not-emitted node. export interface NotEmittedStatement extends Statement { - kind: SyntaxKind.NotEmittedStatement; + readonly kind: SyntaxKind.NotEmittedStatement; } /** @@ -2181,15 +2534,15 @@ namespace ts { */ /* @internal */ export interface EndOfDeclarationMarker extends Statement { - kind: SyntaxKind.EndOfDeclarationMarker; + readonly kind: SyntaxKind.EndOfDeclarationMarker; } /** * A list of comma-separated expressions. This node is only created by transformations. */ export interface CommaListExpression extends Expression { - kind: SyntaxKind.CommaListExpression; - elements: NodeArray; + readonly kind: SyntaxKind.CommaListExpression; + readonly elements: NodeArray; } /** @@ -2197,283 +2550,339 @@ namespace ts { */ /* @internal */ export interface MergeDeclarationMarker extends Statement { - kind: SyntaxKind.MergeDeclarationMarker; + readonly kind: SyntaxKind.MergeDeclarationMarker; } /* @internal */ export interface SyntheticReferenceExpression extends LeftHandSideExpression { - kind: SyntaxKind.SyntheticReferenceExpression; - expression: Expression; - thisArg: Expression; + readonly kind: SyntaxKind.SyntheticReferenceExpression; + readonly expression: Expression; + readonly thisArg: Expression; } export interface EmptyStatement extends Statement { - kind: SyntaxKind.EmptyStatement; + readonly kind: SyntaxKind.EmptyStatement; } export interface DebuggerStatement extends Statement { - kind: SyntaxKind.DebuggerStatement; + readonly kind: SyntaxKind.DebuggerStatement; } export interface MissingDeclaration extends DeclarationStatement { - kind: SyntaxKind.MissingDeclaration; - name?: Identifier; + /*@internal*/ decorators?: NodeArray; // Present for use with reporting a grammar error + /*@internal*/ modifiers?: ModifiersArray; // Present for use with reporting a grammar error + readonly kind: SyntaxKind.MissingDeclaration; + readonly name?: Identifier; } - export type BlockLike = SourceFile | Block | ModuleBlock | CaseOrDefaultClause; + export type BlockLike = + | SourceFile + | Block + | ModuleBlock + | CaseOrDefaultClause + ; export interface Block extends Statement { - kind: SyntaxKind.Block; - statements: NodeArray; + readonly kind: SyntaxKind.Block; + readonly statements: NodeArray; /*@internal*/ multiLine?: boolean; } export interface VariableStatement extends Statement, JSDocContainer { - kind: SyntaxKind.VariableStatement; - declarationList: VariableDeclarationList; + /* @internal*/ decorators?: NodeArray; // Present for use with reporting a grammar error + readonly kind: SyntaxKind.VariableStatement; + readonly declarationList: VariableDeclarationList; } export interface ExpressionStatement extends Statement, JSDocContainer { - kind: SyntaxKind.ExpressionStatement; - expression: Expression; + readonly kind: SyntaxKind.ExpressionStatement; + readonly expression: Expression; } /* @internal */ export interface PrologueDirective extends ExpressionStatement { - expression: StringLiteral; + readonly expression: StringLiteral; } export interface IfStatement extends Statement { - kind: SyntaxKind.IfStatement; - expression: Expression; - thenStatement: Statement; - elseStatement?: Statement; + readonly kind: SyntaxKind.IfStatement; + readonly expression: Expression; + readonly thenStatement: Statement; + readonly elseStatement?: Statement; } export interface IterationStatement extends Statement { - statement: Statement; + readonly statement: Statement; } export interface DoStatement extends IterationStatement { - kind: SyntaxKind.DoStatement; - expression: Expression; + readonly kind: SyntaxKind.DoStatement; + readonly expression: Expression; } export interface WhileStatement extends IterationStatement { - kind: SyntaxKind.WhileStatement; - expression: Expression; + readonly kind: SyntaxKind.WhileStatement; + readonly expression: Expression; } - export type ForInitializer = VariableDeclarationList | Expression; + export type ForInitializer = + | VariableDeclarationList + | Expression + ; export interface ForStatement extends IterationStatement { - kind: SyntaxKind.ForStatement; - initializer?: ForInitializer; - condition?: Expression; - incrementor?: Expression; + readonly kind: SyntaxKind.ForStatement; + readonly initializer?: ForInitializer; + readonly condition?: Expression; + readonly incrementor?: Expression; } - export type ForInOrOfStatement = ForInStatement | ForOfStatement; + export type ForInOrOfStatement = + | ForInStatement + | ForOfStatement + ; export interface ForInStatement extends IterationStatement { - kind: SyntaxKind.ForInStatement; - initializer: ForInitializer; - expression: Expression; + readonly kind: SyntaxKind.ForInStatement; + readonly initializer: ForInitializer; + readonly expression: Expression; } export interface ForOfStatement extends IterationStatement { - kind: SyntaxKind.ForOfStatement; - awaitModifier?: AwaitKeywordToken; - initializer: ForInitializer; - expression: Expression; + readonly kind: SyntaxKind.ForOfStatement; + readonly awaitModifier?: AwaitKeywordToken; + readonly initializer: ForInitializer; + readonly expression: Expression; } export interface BreakStatement extends Statement { - kind: SyntaxKind.BreakStatement; - label?: Identifier; + readonly kind: SyntaxKind.BreakStatement; + readonly label?: Identifier; } export interface ContinueStatement extends Statement { - kind: SyntaxKind.ContinueStatement; - label?: Identifier; + readonly kind: SyntaxKind.ContinueStatement; + readonly label?: Identifier; } - export type BreakOrContinueStatement = BreakStatement | ContinueStatement; + export type BreakOrContinueStatement = + | BreakStatement + | ContinueStatement + ; export interface ReturnStatement extends Statement { - kind: SyntaxKind.ReturnStatement; - expression?: Expression; + readonly kind: SyntaxKind.ReturnStatement; + readonly expression?: Expression; } export interface WithStatement extends Statement { - kind: SyntaxKind.WithStatement; - expression: Expression; - statement: Statement; + readonly kind: SyntaxKind.WithStatement; + readonly expression: Expression; + readonly statement: Statement; } export interface SwitchStatement extends Statement { - kind: SyntaxKind.SwitchStatement; - expression: Expression; - caseBlock: CaseBlock; - possiblyExhaustive?: boolean; + readonly kind: SyntaxKind.SwitchStatement; + readonly expression: Expression; + readonly caseBlock: CaseBlock; + possiblyExhaustive?: boolean; // initialized by binding } export interface CaseBlock extends Node { - kind: SyntaxKind.CaseBlock; - parent: SwitchStatement; - clauses: NodeArray; + readonly kind: SyntaxKind.CaseBlock; + readonly parent: SwitchStatement; + readonly clauses: NodeArray; } export interface CaseClause extends Node { - kind: SyntaxKind.CaseClause; - parent: CaseBlock; - expression: Expression; - statements: NodeArray; + readonly kind: SyntaxKind.CaseClause; + readonly parent: CaseBlock; + readonly expression: Expression; + readonly statements: NodeArray; /* @internal */ fallthroughFlowNode?: FlowNode; } export interface DefaultClause extends Node { - kind: SyntaxKind.DefaultClause; - parent: CaseBlock; - statements: NodeArray; + readonly kind: SyntaxKind.DefaultClause; + readonly parent: CaseBlock; + readonly statements: NodeArray; /* @internal */ fallthroughFlowNode?: FlowNode; } - export type CaseOrDefaultClause = CaseClause | DefaultClause; + export type CaseOrDefaultClause = + | CaseClause + | DefaultClause + ; export interface LabeledStatement extends Statement, JSDocContainer { - kind: SyntaxKind.LabeledStatement; - label: Identifier; - statement: Statement; + readonly kind: SyntaxKind.LabeledStatement; + readonly label: Identifier; + readonly statement: Statement; } export interface ThrowStatement extends Statement { - kind: SyntaxKind.ThrowStatement; - expression?: Expression; + readonly kind: SyntaxKind.ThrowStatement; + readonly expression?: Expression; } export interface TryStatement extends Statement { - kind: SyntaxKind.TryStatement; - tryBlock: Block; - catchClause?: CatchClause; - finallyBlock?: Block; + readonly kind: SyntaxKind.TryStatement; + readonly tryBlock: Block; + readonly catchClause?: CatchClause; + readonly finallyBlock?: Block; } export interface CatchClause extends Node { - kind: SyntaxKind.CatchClause; - parent: TryStatement; - variableDeclaration?: VariableDeclaration; - block: Block; + readonly kind: SyntaxKind.CatchClause; + readonly parent: TryStatement; + readonly variableDeclaration?: VariableDeclaration; + readonly block: Block; } - export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode; + export type ObjectTypeDeclaration = + | ClassLikeDeclaration + | InterfaceDeclaration + | TypeLiteralNode + ; + + export type DeclarationWithTypeParameters = + | DeclarationWithTypeParameterChildren + | JSDocTypedefTag + | JSDocCallbackTag + | JSDocSignature + ; - export type DeclarationWithTypeParameters = DeclarationWithTypeParameterChildren | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; - export type DeclarationWithTypeParameterChildren = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; + export type DeclarationWithTypeParameterChildren = + | SignatureDeclaration + | ClassLikeDeclaration + | InterfaceDeclaration + | TypeAliasDeclaration + | JSDocTemplateTag + ; export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; - name?: Identifier; - typeParameters?: NodeArray; - heritageClauses?: NodeArray; - members: NodeArray; + readonly kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; + readonly name?: Identifier; + readonly typeParameters?: NodeArray; + readonly heritageClauses?: NodeArray; + readonly members: NodeArray; } export interface ClassDeclaration extends ClassLikeDeclarationBase, DeclarationStatement { - kind: SyntaxKind.ClassDeclaration; + readonly kind: SyntaxKind.ClassDeclaration; /** May be undefined in `export default class { ... }`. */ - name?: Identifier; + readonly name?: Identifier; } export interface ClassExpression extends ClassLikeDeclarationBase, PrimaryExpression { - kind: SyntaxKind.ClassExpression; + readonly kind: SyntaxKind.ClassExpression; } - export type ClassLikeDeclaration = ClassDeclaration | ClassExpression; + export type ClassLikeDeclaration = + | ClassDeclaration + | ClassExpression + ; export interface ClassElement extends NamedDeclaration { _classElementBrand: any; - name?: PropertyName; + readonly name?: PropertyName; } export interface TypeElement extends NamedDeclaration { _typeElementBrand: any; - name?: PropertyName; - questionToken?: QuestionToken; + readonly name?: PropertyName; + readonly questionToken?: QuestionToken; } export interface InterfaceDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.InterfaceDeclaration; - name: Identifier; - typeParameters?: NodeArray; - heritageClauses?: NodeArray; - members: NodeArray; + readonly kind: SyntaxKind.InterfaceDeclaration; + readonly name: Identifier; + readonly typeParameters?: NodeArray; + readonly heritageClauses?: NodeArray; + readonly members: NodeArray; } export interface HeritageClause extends Node { - kind: SyntaxKind.HeritageClause; - parent: InterfaceDeclaration | ClassLikeDeclaration; - token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword; - types: NodeArray; + readonly kind: SyntaxKind.HeritageClause; + readonly parent: InterfaceDeclaration | ClassLikeDeclaration; + readonly token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword; + readonly types: NodeArray; } export interface TypeAliasDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.TypeAliasDeclaration; - name: Identifier; - typeParameters?: NodeArray; - type: TypeNode; + readonly kind: SyntaxKind.TypeAliasDeclaration; + readonly name: Identifier; + readonly typeParameters?: NodeArray; + readonly type: TypeNode; } export interface EnumMember extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.EnumMember; - parent: EnumDeclaration; + readonly kind: SyntaxKind.EnumMember; + readonly parent: EnumDeclaration; // This does include ComputedPropertyName, but the parser will give an error // if it parses a ComputedPropertyName in an EnumMember - name: PropertyName; - initializer?: Expression; + readonly name: PropertyName; + readonly initializer?: Expression; } export interface EnumDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.EnumDeclaration; - name: Identifier; - members: NodeArray; + readonly kind: SyntaxKind.EnumDeclaration; + readonly name: Identifier; + readonly members: NodeArray; } - export type ModuleName = Identifier | StringLiteral; + export type ModuleName = + | Identifier + | StringLiteral + ; - export type ModuleBody = NamespaceBody | JSDocNamespaceBody; + export type ModuleBody = + | NamespaceBody + | JSDocNamespaceBody + ; /* @internal */ - export interface AmbientModuleDeclaration extends ModuleDeclaration { body?: ModuleBlock; } + export interface AmbientModuleDeclaration extends ModuleDeclaration { + readonly body?: ModuleBlock; + } export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ModuleDeclaration; - parent: ModuleBody | SourceFile; - name: ModuleName; - body?: ModuleBody | JSDocNamespaceDeclaration; + readonly kind: SyntaxKind.ModuleDeclaration; + readonly parent: ModuleBody | SourceFile; + readonly name: ModuleName; + readonly body?: ModuleBody | JSDocNamespaceDeclaration; } - export type NamespaceBody = ModuleBlock | NamespaceDeclaration; + export type NamespaceBody = + | ModuleBlock + | NamespaceDeclaration + ; export interface NamespaceDeclaration extends ModuleDeclaration { - name: Identifier; - body: NamespaceBody; + readonly name: Identifier; + readonly body: NamespaceBody; } - export type JSDocNamespaceBody = Identifier | JSDocNamespaceDeclaration; + export type JSDocNamespaceBody = + | Identifier + | JSDocNamespaceDeclaration + ; export interface JSDocNamespaceDeclaration extends ModuleDeclaration { - name: Identifier; - body?: JSDocNamespaceBody; + readonly name: Identifier; + readonly body?: JSDocNamespaceBody; } export interface ModuleBlock extends Node, Statement { - kind: SyntaxKind.ModuleBlock; - parent: ModuleDeclaration; - statements: NodeArray; + readonly kind: SyntaxKind.ModuleBlock; + readonly parent: ModuleDeclaration; + readonly statements: NodeArray; } - export type ModuleReference = EntityName | ExternalModuleReference; + export type ModuleReference = + | EntityName + | ExternalModuleReference + ; /** * One of: @@ -2481,35 +2890,42 @@ namespace ts { * - import x = M.x; */ export interface ImportEqualsDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ImportEqualsDeclaration; - parent: SourceFile | ModuleBlock; - name: Identifier; + readonly kind: SyntaxKind.ImportEqualsDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly name: Identifier; // 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external // module reference. - moduleReference: ModuleReference; + readonly moduleReference: ModuleReference; } export interface ExternalModuleReference extends Node { - kind: SyntaxKind.ExternalModuleReference; - parent: ImportEqualsDeclaration; - expression: Expression; + readonly kind: SyntaxKind.ExternalModuleReference; + readonly parent: ImportEqualsDeclaration; + readonly expression: Expression; } // In case of: // import "mod" => importClause = undefined, moduleSpecifier = "mod" // In rest of the cases, module specifier is string literal corresponding to module // ImportClause information is shown at its declaration below. - export interface ImportDeclaration extends Statement { - kind: SyntaxKind.ImportDeclaration; - parent: SourceFile | ModuleBlock; - importClause?: ImportClause; + export interface ImportDeclaration extends Statement, JSDocContainer { + readonly kind: SyntaxKind.ImportDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly importClause?: ImportClause; /** If this is not a StringLiteral it will be a grammar error. */ - moduleSpecifier: Expression; + readonly moduleSpecifier: Expression; } - export type NamedImportBindings = NamespaceImport | NamedImports; - export type NamedExportBindings = NamespaceExport | NamedExports; + export type NamedImportBindings = + | NamespaceImport + | NamedImports + ; + + export type NamedExportBindings = + | NamespaceExport + | NamedExports + ; // In case of: // import d from "mod" => name = d, namedBinding = undefined @@ -2518,80 +2934,90 @@ namespace ts { // import { a, b as x } from "mod" => name = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} // import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} export interface ImportClause extends NamedDeclaration { - kind: SyntaxKind.ImportClause; - parent: ImportDeclaration; - isTypeOnly: boolean; - name?: Identifier; // Default binding - namedBindings?: NamedImportBindings; + readonly kind: SyntaxKind.ImportClause; + readonly parent: ImportDeclaration; + readonly isTypeOnly: boolean; + readonly name?: Identifier; // Default binding + readonly namedBindings?: NamedImportBindings; } export interface NamespaceImport extends NamedDeclaration { - kind: SyntaxKind.NamespaceImport; - parent: ImportClause; - name: Identifier; + readonly kind: SyntaxKind.NamespaceImport; + readonly parent: ImportClause; + readonly name: Identifier; } export interface NamespaceExport extends NamedDeclaration { - kind: SyntaxKind.NamespaceExport; - parent: ExportDeclaration; - name: Identifier + readonly kind: SyntaxKind.NamespaceExport; + readonly parent: ExportDeclaration; + readonly name: Identifier } - export interface NamespaceExportDeclaration extends DeclarationStatement { - kind: SyntaxKind.NamespaceExportDeclaration; - name: Identifier; + export interface NamespaceExportDeclaration extends DeclarationStatement, JSDocContainer { + readonly kind: SyntaxKind.NamespaceExportDeclaration; + readonly name: Identifier; + /* @internal */ decorators?: NodeArray; // Present for use with reporting a grammar error + /* @internal */ modifiers?: ModifiersArray; // Present for use with reporting a grammar error } export interface ExportDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ExportDeclaration; - parent: SourceFile | ModuleBlock; - isTypeOnly: boolean; + readonly kind: SyntaxKind.ExportDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly isTypeOnly: boolean; /** Will not be assigned in the case of `export * from "foo";` */ - exportClause?: NamedExportBindings; + readonly exportClause?: NamedExportBindings; /** If this is not a StringLiteral it will be a grammar error. */ - moduleSpecifier?: Expression; + readonly moduleSpecifier?: Expression; } export interface NamedImports extends Node { - kind: SyntaxKind.NamedImports; - parent: ImportClause; - elements: NodeArray; + readonly kind: SyntaxKind.NamedImports; + readonly parent: ImportClause; + readonly elements: NodeArray; } export interface NamedExports extends Node { - kind: SyntaxKind.NamedExports; - parent: ExportDeclaration; - elements: NodeArray; + readonly kind: SyntaxKind.NamedExports; + readonly parent: ExportDeclaration; + readonly elements: NodeArray; } export type NamedImportsOrExports = NamedImports | NamedExports; export interface ImportSpecifier extends NamedDeclaration { - kind: SyntaxKind.ImportSpecifier; - parent: NamedImports; - propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) - name: Identifier; // Declared name + readonly kind: SyntaxKind.ImportSpecifier; + readonly parent: NamedImports; + readonly propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) + readonly name: Identifier; // Declared name } export interface ExportSpecifier extends NamedDeclaration { - kind: SyntaxKind.ExportSpecifier; - parent: NamedExports; - propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) - name: Identifier; // Declared name + readonly kind: SyntaxKind.ExportSpecifier; + readonly parent: NamedExports; + readonly propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) + readonly name: Identifier; // Declared name } - export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier; - export type TypeOnlyCompatibleAliasDeclaration = ImportClause | NamespaceImport | ImportOrExportSpecifier; + export type ImportOrExportSpecifier = + | ImportSpecifier + | ExportSpecifier + ; + + export type TypeOnlyCompatibleAliasDeclaration = + | ImportClause + | NamespaceImport + | ImportOrExportSpecifier + ; /** * This is either an `export =` or an `export default` declaration. * Unless `isExportEquals` is set, this node was parsed as an `export default`. */ - export interface ExportAssignment extends DeclarationStatement { - kind: SyntaxKind.ExportAssignment; - parent: SourceFile; - isExportEquals?: boolean; - expression: Expression; + export interface ExportAssignment extends DeclarationStatement, JSDocContainer { + readonly kind: SyntaxKind.ExportAssignment; + readonly parent: SourceFile; + readonly isExportEquals?: boolean; + readonly expression: Expression; } export interface FileReference extends TextRange { @@ -2618,8 +3044,8 @@ namespace ts { // represents a top level: { type } expression in a JSDoc comment. export interface JSDocTypeExpression extends TypeNode { - kind: SyntaxKind.JSDocTypeExpression; - type: TypeNode; + readonly kind: SyntaxKind.JSDocTypeExpression; + readonly type: TypeNode; } export interface JSDocType extends TypeNode { @@ -2627,59 +3053,64 @@ namespace ts { } export interface JSDocAllType extends JSDocType { - kind: SyntaxKind.JSDocAllType; + readonly kind: SyntaxKind.JSDocAllType; } export interface JSDocUnknownType extends JSDocType { - kind: SyntaxKind.JSDocUnknownType; + readonly kind: SyntaxKind.JSDocUnknownType; } export interface JSDocNonNullableType extends JSDocType { - kind: SyntaxKind.JSDocNonNullableType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNonNullableType; + readonly type: TypeNode; } export interface JSDocNullableType extends JSDocType { - kind: SyntaxKind.JSDocNullableType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNullableType; + readonly type: TypeNode; } export interface JSDocOptionalType extends JSDocType { - kind: SyntaxKind.JSDocOptionalType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocOptionalType; + readonly type: TypeNode; } export interface JSDocFunctionType extends JSDocType, SignatureDeclarationBase { - kind: SyntaxKind.JSDocFunctionType; + readonly kind: SyntaxKind.JSDocFunctionType; } export interface JSDocVariadicType extends JSDocType { - kind: SyntaxKind.JSDocVariadicType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocVariadicType; + readonly type: TypeNode; } export interface JSDocNamepathType extends JSDocType { - kind: SyntaxKind.JSDocNamepathType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNamepathType; + readonly type: TypeNode; } - export type JSDocTypeReferencingNode = JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType; + export type JSDocTypeReferencingNode = + | JSDocVariadicType + | JSDocOptionalType + | JSDocNullableType + | JSDocNonNullableType + ; export interface JSDoc extends Node { - kind: SyntaxKind.JSDocComment; - parent: HasJSDoc; - tags?: NodeArray; - comment?: string; + readonly kind: SyntaxKind.JSDocComment; + readonly parent: HasJSDoc; + readonly tags?: NodeArray; + readonly comment?: string; } export interface JSDocTag extends Node { - parent: JSDoc | JSDocTypeLiteral; - tagName: Identifier; - comment?: string; + readonly parent: JSDoc | JSDocTypeLiteral; + readonly tagName: Identifier; + readonly comment?: string; } export interface JSDocUnknownTag extends JSDocTag { - kind: SyntaxKind.JSDocTag; + readonly kind: SyntaxKind.JSDocTag; } /** @@ -2687,111 +3118,111 @@ namespace ts { * Both tags are represented by this interface. */ export interface JSDocAugmentsTag extends JSDocTag { - kind: SyntaxKind.JSDocAugmentsTag; - class: ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression }; + readonly kind: SyntaxKind.JSDocAugmentsTag; + readonly class: ExpressionWithTypeArguments & { readonly expression: Identifier | PropertyAccessEntityNameExpression }; } export interface JSDocImplementsTag extends JSDocTag { - kind: SyntaxKind.JSDocImplementsTag; - class: ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression }; + readonly kind: SyntaxKind.JSDocImplementsTag; + readonly class: ExpressionWithTypeArguments & { readonly expression: Identifier | PropertyAccessEntityNameExpression }; } export interface JSDocAuthorTag extends JSDocTag { - kind: SyntaxKind.JSDocAuthorTag; + readonly kind: SyntaxKind.JSDocAuthorTag; } export interface JSDocClassTag extends JSDocTag { - kind: SyntaxKind.JSDocClassTag; + readonly kind: SyntaxKind.JSDocClassTag; } export interface JSDocPublicTag extends JSDocTag { - kind: SyntaxKind.JSDocPublicTag; + readonly kind: SyntaxKind.JSDocPublicTag; } export interface JSDocPrivateTag extends JSDocTag { - kind: SyntaxKind.JSDocPrivateTag; + readonly kind: SyntaxKind.JSDocPrivateTag; } export interface JSDocProtectedTag extends JSDocTag { - kind: SyntaxKind.JSDocProtectedTag; + readonly kind: SyntaxKind.JSDocProtectedTag; } export interface JSDocReadonlyTag extends JSDocTag { - kind: SyntaxKind.JSDocReadonlyTag; + readonly kind: SyntaxKind.JSDocReadonlyTag; } export interface JSDocEnumTag extends JSDocTag, Declaration { - parent: JSDoc; - kind: SyntaxKind.JSDocEnumTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocEnumTag; + readonly parent: JSDoc; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocThisTag extends JSDocTag { - kind: SyntaxKind.JSDocThisTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocThisTag; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocTemplateTag extends JSDocTag { - kind: SyntaxKind.JSDocTemplateTag; - constraint: JSDocTypeExpression | undefined; - typeParameters: NodeArray; + readonly kind: SyntaxKind.JSDocTemplateTag; + readonly constraint: JSDocTypeExpression | undefined; + readonly typeParameters: NodeArray; } export interface JSDocReturnTag extends JSDocTag { - kind: SyntaxKind.JSDocReturnTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocReturnTag; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocTypeTag extends JSDocTag { - kind: SyntaxKind.JSDocTypeTag; - typeExpression: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocTypeTag; + readonly typeExpression: JSDocTypeExpression; } export interface JSDocTypedefTag extends JSDocTag, NamedDeclaration { - parent: JSDoc; - kind: SyntaxKind.JSDocTypedefTag; - fullName?: JSDocNamespaceDeclaration | Identifier; - name?: Identifier; - typeExpression?: JSDocTypeExpression | JSDocTypeLiteral; + readonly kind: SyntaxKind.JSDocTypedefTag; + readonly parent: JSDoc; + readonly fullName?: JSDocNamespaceDeclaration | Identifier; + readonly name?: Identifier; + readonly typeExpression?: JSDocTypeExpression | JSDocTypeLiteral; } export interface JSDocCallbackTag extends JSDocTag, NamedDeclaration { - parent: JSDoc; - kind: SyntaxKind.JSDocCallbackTag; - fullName?: JSDocNamespaceDeclaration | Identifier; - name?: Identifier; - typeExpression: JSDocSignature; + readonly kind: SyntaxKind.JSDocCallbackTag; + readonly parent: JSDoc; + readonly fullName?: JSDocNamespaceDeclaration | Identifier; + readonly name?: Identifier; + readonly typeExpression: JSDocSignature; } export interface JSDocSignature extends JSDocType, Declaration { - kind: SyntaxKind.JSDocSignature; - typeParameters?: readonly JSDocTemplateTag[]; - parameters: readonly JSDocParameterTag[]; - type: JSDocReturnTag | undefined; + readonly kind: SyntaxKind.JSDocSignature; + readonly typeParameters?: readonly JSDocTemplateTag[]; + readonly parameters: readonly JSDocParameterTag[]; + readonly type: JSDocReturnTag | undefined; } export interface JSDocPropertyLikeTag extends JSDocTag, Declaration { - parent: JSDoc; - name: EntityName; - typeExpression?: JSDocTypeExpression; + readonly parent: JSDoc; + readonly name: EntityName; + readonly typeExpression?: JSDocTypeExpression; /** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */ - isNameFirst: boolean; - isBracketed: boolean; + readonly isNameFirst: boolean; + readonly isBracketed: boolean; } export interface JSDocPropertyTag extends JSDocPropertyLikeTag { - kind: SyntaxKind.JSDocPropertyTag; + readonly kind: SyntaxKind.JSDocPropertyTag; } export interface JSDocParameterTag extends JSDocPropertyLikeTag { - kind: SyntaxKind.JSDocParameterTag; + readonly kind: SyntaxKind.JSDocParameterTag; } export interface JSDocTypeLiteral extends JSDocType { - kind: SyntaxKind.JSDocTypeLiteral; - jsDocPropertyTags?: readonly JSDocPropertyLikeTag[]; + readonly kind: SyntaxKind.JSDocTypeLiteral; + readonly jsDocPropertyTags?: readonly JSDocPropertyLikeTag[]; /** If true, then this type literal represents an *array* of its type. */ - isArrayType?: boolean; + readonly isArrayType: boolean; } // NOTE: Ensure this is up-to-date with src/debug/debug.ts @@ -2921,9 +3352,9 @@ namespace ts { // Source files are declarations when they are external modules. export interface SourceFile extends Declaration { - kind: SyntaxKind.SourceFile; - statements: NodeArray; - endOfFileToken: Token; + readonly kind: SyntaxKind.SourceFile; + readonly statements: NodeArray; + readonly endOfFileToken: Token; fileName: string; /* @internal */ path: Path; @@ -3025,7 +3456,7 @@ namespace ts { /* @internal */ localJsxNamespace?: __String; /* @internal */ localJsxFactory?: EntityName; - /*@internal*/ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit; + /* @internal */ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit; } /* @internal */ @@ -3044,9 +3475,9 @@ namespace ts { export type ExportedModulesFromDeclarationEmit = readonly Symbol[]; export interface Bundle extends Node { - kind: SyntaxKind.Bundle; - prepends: readonly (InputFiles | UnparsedSource)[]; - sourceFiles: readonly SourceFile[]; + readonly kind: SyntaxKind.Bundle; + readonly prepends: readonly (InputFiles | UnparsedSource)[]; + readonly sourceFiles: readonly SourceFile[]; /* @internal */ syntheticFileReferences?: readonly FileReference[]; /* @internal */ syntheticTypeReferences?: readonly FileReference[]; /* @internal */ syntheticLibReferences?: readonly FileReference[]; @@ -3054,7 +3485,7 @@ namespace ts { } export interface InputFiles extends Node { - kind: SyntaxKind.InputFiles; + readonly kind: SyntaxKind.InputFiles; javascriptPath?: string; javascriptText: string; javascriptMapPath?: string; @@ -3069,10 +3500,10 @@ namespace ts { } export interface UnparsedSource extends Node { - kind: SyntaxKind.UnparsedSource; + readonly kind: SyntaxKind.UnparsedSource; fileName: string; text: string; - prologues: readonly UnparsedPrologue[]; + readonly prologues: readonly UnparsedPrologue[]; helpers: readonly UnscopedEmitHelper[] | undefined; // References and noDefaultLibAre Dts only @@ -3083,8 +3514,8 @@ namespace ts { sourceMapPath?: string; sourceMapText?: string; - syntheticReferences?: readonly UnparsedSyntheticReference[]; - texts: readonly UnparsedSourceText[]; + readonly syntheticReferences?: readonly UnparsedSyntheticReference[]; + readonly texts: readonly UnparsedSourceText[]; /*@internal*/ oldFileOfCurrentEmit?: boolean; /*@internal*/ parsedSourceMap?: RawSourceMap | false | undefined; // Adding this to satisfy services, fix later @@ -3092,41 +3523,49 @@ namespace ts { getLineAndCharacterOfPosition(pos: number): LineAndCharacter; } - export type UnparsedSourceText = UnparsedPrepend | UnparsedTextLike; - export type UnparsedNode = UnparsedPrologue | UnparsedSourceText | UnparsedSyntheticReference; + export type UnparsedSourceText = + | UnparsedPrepend + | UnparsedTextLike + ; + + export type UnparsedNode = + | UnparsedPrologue + | UnparsedSourceText + | UnparsedSyntheticReference + ; export interface UnparsedSection extends Node { - kind: SyntaxKind; - data?: string; - parent: UnparsedSource; + readonly kind: SyntaxKind; + readonly parent: UnparsedSource; + readonly data?: string; } export interface UnparsedPrologue extends UnparsedSection { - kind: SyntaxKind.UnparsedPrologue; - data: string; - parent: UnparsedSource; + readonly kind: SyntaxKind.UnparsedPrologue; + readonly parent: UnparsedSource; + readonly data: string; } export interface UnparsedPrepend extends UnparsedSection { - kind: SyntaxKind.UnparsedPrepend; - data: string; - parent: UnparsedSource; - texts: readonly UnparsedTextLike[]; + readonly kind: SyntaxKind.UnparsedPrepend; + readonly parent: UnparsedSource; + readonly data: string; + readonly texts: readonly UnparsedTextLike[]; } export interface UnparsedTextLike extends UnparsedSection { - kind: SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText; - parent: UnparsedSource; + readonly kind: SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText; + readonly parent: UnparsedSource; } export interface UnparsedSyntheticReference extends UnparsedSection { - kind: SyntaxKind.UnparsedSyntheticReference; - parent: UnparsedSource; - /*@internal*/ section: BundleFileHasNoDefaultLib | BundleFileReference; + readonly kind: SyntaxKind.UnparsedSyntheticReference; + readonly parent: UnparsedSource; + /*@internal*/ readonly section: BundleFileHasNoDefaultLib | BundleFileReference; } export interface JsonSourceFile extends SourceFile { - statements: NodeArray; + readonly statements: NodeArray; } export interface TsConfigSourceFile extends JsonSourceFile { @@ -3134,13 +3573,23 @@ namespace ts { } export interface JsonMinusNumericLiteral extends PrefixUnaryExpression { - kind: SyntaxKind.PrefixUnaryExpression; - operator: SyntaxKind.MinusToken; - operand: NumericLiteral; + readonly kind: SyntaxKind.PrefixUnaryExpression; + readonly operator: SyntaxKind.MinusToken; + readonly operand: NumericLiteral; } + export type JsonObjectExpression = + | ObjectLiteralExpression + | ArrayLiteralExpression + | JsonMinusNumericLiteral + | NumericLiteral + | StringLiteral + | BooleanLiteral + | NullLiteral + ; + export interface JsonObjectExpressionStatement extends ExpressionStatement { - expression: ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | BooleanLiteral | NullLiteral; + readonly expression: JsonObjectExpression; } export interface ScriptReferenceHost { @@ -3580,9 +4029,9 @@ namespace ts { /* @internal */ createAnonymousType(symbol: Symbol | undefined, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): Type; /* @internal */ createSignature( declaration: SignatureDeclaration, - typeParameters: TypeParameter[] | undefined, + typeParameters: readonly TypeParameter[] | undefined, thisParameter: Symbol | undefined, - parameters: Symbol[], + parameters: readonly Symbol[], resolvedReturnType: Type, typePredicate: TypePredicate | undefined, minArgumentCount: number, @@ -3691,7 +4140,7 @@ namespace ts { WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) UseOnlyExternalAliasing = 1 << 7, // Only use external aliases for a symbol - SuppressAnyReturnType = 1 << 8, // If the return type is any-like, don't offer a return type. + SuppressAnyReturnType = 1 << 8, // If the return type is any-like and can be elided, don't offer a return type. WriteTypeParametersInQualifiedName = 1 << 9, MultilineObjectLiterals = 1 << 10, // Always write object literals across multiple lines WriteClassExpressionAsTypeLiteral = 1 << 11, // Write class {} as { new(): {} } - used for mixin declaration emit @@ -5074,6 +5523,7 @@ namespace ts { source?: string; relatedInformation?: DiagnosticRelatedInformation[]; } + export interface DiagnosticRelatedInformation { category: DiagnosticCategory; code: number; @@ -5082,12 +5532,21 @@ namespace ts { length: number | undefined; messageText: string | DiagnosticMessageChain; } + export interface DiagnosticWithLocation extends Diagnostic { file: SourceFile; start: number; length: number; } + /* @internal*/ + export interface DiagnosticWithDetachedLocation extends Diagnostic { + file: undefined; + fileName: string; + start: number; + length: number; + } + export enum DiagnosticCategory { Warning, Error, @@ -6011,6 +6470,763 @@ namespace ts { set?: Expression; } + export const enum OuterExpressionKinds { + Parentheses = 1 << 0, + TypeAssertions = 1 << 1, + NonNullAssertions = 1 << 2, + PartiallyEmittedExpressions = 1 << 3, + + Assertions = TypeAssertions | NonNullAssertions, + All = Parentheses | Assertions | PartiallyEmittedExpressions + } + + /* @internal */ + export type OuterExpression = + | ParenthesizedExpression + | TypeAssertion + | AsExpression + | NonNullExpression + | PartiallyEmittedExpression; + + export type TypeOfTag = "undefined" | "number" | "bigint" | "boolean" | "string" | "symbol" | "object" | "function"; + + /* @internal */ + export interface CallBinding { + target: LeftHandSideExpression; + thisArg: Expression; + } + + /* @internal */ + export interface ParenthesizerRules { + parenthesizeLeftSideOfBinary(binaryOperator: SyntaxKind, leftSide: Expression): Expression; + parenthesizeRightSideOfBinary(binaryOperator: SyntaxKind, leftSide: Expression | undefined, rightSide: Expression): Expression; + parenthesizeExpressionOfComputedPropertyName(expression: Expression): Expression; + parenthesizeConditionOfConditionalExpression(condition: Expression): Expression; + parenthesizeBranchOfConditionalExpression(branch: Expression): Expression; + parenthesizeExpressionOfExportDefault(expression: Expression): Expression; + parenthesizeExpressionOfNew(expression: Expression): LeftHandSideExpression; + parenthesizeLeftSideOfAccess(expression: Expression): LeftHandSideExpression; + parenthesizeOperandOfPostfixUnary(operand: Expression): LeftHandSideExpression; + parenthesizeOperandOfPrefixUnary(operand: Expression): UnaryExpression; + parenthesizeExpressionsOfCommaDelimitedList(elements: readonly Expression[]): NodeArray; + parenthesizeExpressionForDisallowedComma(expression: Expression): Expression; + parenthesizeExpressionOfExpressionStatement(expression: Expression): Expression; + parenthesizeConciseBodyOfArrowFunction(body: ConciseBody): ConciseBody; + parenthesizeMemberOfConditionalType(member: TypeNode): TypeNode; + parenthesizeMemberOfElementType(member: TypeNode): TypeNode; + parenthesizeElementTypeOfArrayType(member: TypeNode): TypeNode; + parenthesizeConstituentTypesOfUnionOrIntersectionType(members: readonly TypeNode[]): NodeArray; + parenthesizeTypeArguments(typeParameters: readonly TypeNode[] | undefined): NodeArray | undefined; + } + + /* @internal */ + export interface NodeConverters { + convertToFunctionBlock(node: ConciseBody, multiLine?: boolean): Block; + convertToFunctionExpression(node: FunctionDeclaration): FunctionExpression; + convertToArrayAssignmentElement(element: ArrayBindingOrAssignmentElement): Expression; + convertToObjectAssignmentElement(element: ObjectBindingOrAssignmentElement): ObjectLiteralElementLike; + convertToAssignmentPattern(node: BindingOrAssignmentPattern): AssignmentPattern; + convertToObjectAssignmentPattern(node: ObjectBindingOrAssignmentPattern): ObjectLiteralExpression; + convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern): ArrayLiteralExpression; + convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression; + } + + export interface NodeFactory { + /* @internal */ readonly parenthesizer: ParenthesizerRules; + /* @internal */ readonly converters: NodeConverters; + createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray; + + // + // Literals + // + + createNumericLiteral(value: string | number, numericLiteralFlags?: TokenFlags): NumericLiteral; + createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral; + createStringLiteral(text: string, isSingleQuote?: boolean): StringLiteral; + /* @internal*/ createStringLiteral(text: string, isSingleQuote?: boolean, hasExtendedUnicodeEscape?: boolean): StringLiteral; // eslint-disable-line @typescript-eslint/unified-signatures + createStringLiteralFromNode(sourceNode: PropertyNameLiteral, isSingleQuote?: boolean): StringLiteral; + createRegularExpressionLiteral(text: string): RegularExpressionLiteral; + + // + // Identifiers + // + + createIdentifier(text: string): Identifier; + /* @internal */ createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[], originalKeywordKind?: SyntaxKind): Identifier; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal */ updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; + + /** Create a unique temporary variable. */ + createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; + /* @internal */ createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): Identifier; // eslint-disable-line @typescript-eslint/unified-signatures + + /** Create a unique temporary variable for use in a loop. */ + createLoopVariable(): Identifier; + + /** Create a unique name based on the supplied text. */ + createUniqueName(text: string, flags?: GeneratedIdentifierFlags): Identifier; + + /** Create a unique name generated for a node. */ + getGeneratedNameForNode(node: Node | undefined): Identifier; + /* @internal */ getGeneratedNameForNode(node: Node | undefined, flags?: GeneratedIdentifierFlags): Identifier; // eslint-disable-line @typescript-eslint/unified-signatures + + createPrivateIdentifier(text: string): PrivateIdentifier + + // + // Punctuation + // + + createToken(token: SyntaxKind.SuperKeyword): SuperExpression; + createToken(token: SyntaxKind.ThisKeyword): ThisExpression; + createToken(token: SyntaxKind.NullKeyword): NullLiteral; + createToken(token: SyntaxKind.TrueKeyword): TrueLiteral; + createToken(token: SyntaxKind.FalseKeyword): FalseLiteral; + createToken(token: TKind): PunctuationToken; + createToken(token: TKind): KeywordTypeNode; + createToken(token: TKind): ModifierToken; + createToken(token: TKind): KeywordToken; + createToken(token: TKind): Token; + /*@internal*/ createToken(token: TKind): Token; + + // + // Reserved words + // + + createSuper(): SuperExpression; + createThis(): ThisExpression; + createNull(): NullLiteral; + createTrue(): TrueLiteral; + createFalse(): FalseLiteral; + + // + // Modifiers + // + + createModifier(kind: T): ModifierToken; + createModifiersFromModifierFlags(flags: ModifierFlags): Modifier[]; + + // + // Names + // + + createQualifiedName(left: EntityName, right: string | Identifier): QualifiedName; + updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName; + createComputedPropertyName(expression: Expression): ComputedPropertyName; + updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName; + + // + // Signature elements + // + + createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; + updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined): TypeParameterDeclaration; + createParameterDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): ParameterDeclaration; + updateParameterDeclaration(node: ParameterDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): ParameterDeclaration; + createDecorator(expression: Expression): Decorator; + updateDecorator(node: Decorator, expression: Expression): Decorator; + + // + // Type Elements + // + + createPropertySignature(modifiers: readonly Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined): PropertySignature; + updatePropertySignature(node: PropertySignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined): PropertySignature; + createPropertyDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + updatePropertyDeclaration(node: PropertyDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + createMethodSignature(modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): MethodSignature; + updateMethodSignature(node: MethodSignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): MethodSignature; + createMethodDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; + updateMethodDeclaration(node: MethodDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; + createConstructorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; + updateConstructorDeclaration(node: ConstructorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; + createGetAccessorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; + updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; + createSetAccessorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; + updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; + createCallSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration; + updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration; + createConstructSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration; + updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration; + createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; + /* @internal */ createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): IndexSignatureDeclaration; // eslint-disable-line @typescript-eslint/unified-signatures + updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; + + // + // Types + // + + createKeywordTypeNode(kind: TKind): KeywordTypeNode; + createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; + createTypeReferenceNode(typeName: string | EntityName, typeArguments?: readonly TypeNode[]): TypeReferenceNode; + updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; + createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; + updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; + createTypeQueryNode(exprName: EntityName): TypeQueryNode; + updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; + createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; + updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode; + createArrayTypeNode(elementType: TypeNode): ArrayTypeNode; + updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode; + createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; + updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; + createNamedTupleMember(dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode): NamedTupleMember; + updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode): NamedTupleMember; + createOptionalTypeNode(type: TypeNode): OptionalTypeNode; + updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode; + createRestTypeNode(type: TypeNode): RestTypeNode; + updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode; + createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode; + updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode; + createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode; + updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode; + createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; + updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; + createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; + updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; + createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; + updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean): ImportTypeNode; + createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; + updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; + createThisTypeNode(): ThisTypeNode; + createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; + updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; + createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; + updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; + createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; + updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; + + // + // Binding Patterns + // + + createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern; + updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]): ObjectBindingPattern; + createArrayBindingPattern(elements: readonly ArrayBindingElement[]): ArrayBindingPattern; + updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]): ArrayBindingPattern; + createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression): BindingElement; + updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined): BindingElement; + + // + // Expression + // + + createArrayLiteralExpression(elements?: readonly Expression[], multiLine?: boolean): ArrayLiteralExpression; + updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; + createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; + updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; + createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression; + updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression; + createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier): PropertyAccessChain; + updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier): PropertyAccessChain; + createElementAccessExpression(expression: Expression, index: number | Expression): ElementAccessExpression; + updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression; + createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain; + updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression): ElementAccessChain; + createCallExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallExpression; + updateCallExpression(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallExpression; + createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallChain; + updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallChain; + createNewExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; + updateNewExpression(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; + createTaggedTemplateExpression(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; + updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; + createParenthesizedExpression(expression: Expression): ParenthesizedExpression; + updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression; + createFunctionExpression(modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[] | undefined, type: TypeNode | undefined, body: Block): FunctionExpression; + updateFunctionExpression(node: FunctionExpression, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block): FunctionExpression; + createArrowFunction(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; + updateArrowFunction(node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody): ArrowFunction; + createDeleteExpression(expression: Expression): DeleteExpression; + updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression; + createTypeOfExpression(expression: Expression): TypeOfExpression; + updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression; + createVoidExpression(expression: Expression): VoidExpression; + updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression; + createAwaitExpression(expression: Expression): AwaitExpression; + updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression; + createPrefixUnaryExpression(operator: PrefixUnaryOperator, operand: Expression): PrefixUnaryExpression; + updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression; + createPostfixUnaryExpression(operand: Expression, operator: PostfixUnaryOperator): PostfixUnaryExpression; + updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression; + createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; + updateBinaryExpression(node: BinaryExpression, left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; + createConditionalExpression(condition: Expression, questionToken: QuestionToken | undefined, whenTrue: Expression, colonToken: ColonToken | undefined, whenFalse: Expression): ConditionalExpression; + updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; + createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; + updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; + createTemplateHead(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateHead; + createTemplateHead(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateHead; + createTemplateMiddle(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateMiddle; + createTemplateMiddle(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateMiddle; + createTemplateTail(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateTail; + createTemplateTail(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateTail; + createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; + createNoSubstitutionTemplateLiteral(text: string | undefined, rawText: string): NoSubstitutionTemplateLiteral; + /* @internal */ createLiteralLikeNode(kind: LiteralToken["kind"] | SyntaxKind.JsxTextAllWhiteSpaces, text: string): LiteralToken; + /* @internal */ createTemplateLiteralLikeNode(kind: TemplateLiteralToken["kind"], text: string, rawText: string, templateFlags: TokenFlags | undefined): TemplateLiteralLikeNode; + createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression; + createYieldExpression(asteriskToken: undefined, expression: Expression | undefined): YieldExpression; + /* @internal */ createYieldExpression(asteriskToken: AsteriskToken | undefined, expression: Expression | undefined): YieldExpression; // eslint-disable-line @typescript-eslint/unified-signatures + updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression | undefined): YieldExpression; + createSpreadElement(expression: Expression): SpreadElement; + updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement; + createClassExpression(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; + updateClassExpression(node: ClassExpression, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; + createOmittedExpression(): OmittedExpression; + createExpressionWithTypeArguments(expression: Expression, typeArguments: readonly TypeNode[] | undefined): ExpressionWithTypeArguments; + updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: readonly TypeNode[] | undefined): ExpressionWithTypeArguments; + createAsExpression(expression: Expression, type: TypeNode): AsExpression; + updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression; + createNonNullExpression(expression: Expression): NonNullExpression; + updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression; + createNonNullChain(expression: Expression): NonNullChain; + updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain; + createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier): MetaProperty; + updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty; + + // + // Misc + // + + createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; + updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; + createSemicolonClassElement(): SemicolonClassElement; + + // + // Element + // + + createBlock(statements: readonly Statement[], multiLine?: boolean): Block; + updateBlock(node: Block, statements: readonly Statement[]): Block; + createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]): VariableStatement; + updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList): VariableStatement; + createEmptyStatement(): EmptyStatement; + createExpressionStatement(expression: Expression): ExpressionStatement; + updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement; + createIfStatement(expression: Expression, thenStatement: Statement, elseStatement?: Statement): IfStatement; + updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined): IfStatement; + createDoStatement(statement: Statement, expression: Expression): DoStatement; + updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement; + createWhileStatement(expression: Expression, statement: Statement): WhileStatement; + updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement; + createForStatement(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; + updateForStatement(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; + createForInStatement(initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; + updateForInStatement(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; + createForOfStatement(awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; + updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; + createContinueStatement(label?: string | Identifier): ContinueStatement; + updateContinueStatement(node: ContinueStatement, label: Identifier | undefined): ContinueStatement; + createBreakStatement(label?: string | Identifier): BreakStatement; + updateBreakStatement(node: BreakStatement, label: Identifier | undefined): BreakStatement; + createReturnStatement(expression?: Expression): ReturnStatement; + updateReturnStatement(node: ReturnStatement, expression: Expression | undefined): ReturnStatement; + createWithStatement(expression: Expression, statement: Statement): WithStatement; + updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement; + createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement; + updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement; + createLabeledStatement(label: string | Identifier, statement: Statement): LabeledStatement; + updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement; + createThrowStatement(expression: Expression): ThrowStatement; + updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement; + createTryStatement(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; + updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; + createDebuggerStatement(): DebuggerStatement; + createVariableDeclaration(name: string | BindingName, exclamationToken?: ExclamationToken, type?: TypeNode, initializer?: Expression): VariableDeclaration; + updateVariableDeclaration(node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList; + updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]): VariableDeclarationList; + createFunctionDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; + updateFunctionDeclaration(node: FunctionDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; + createClassDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; + updateClassDeclaration(node: ClassDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; + createInterfaceDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; + updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; + createTypeAliasDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; + updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; + createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]): EnumDeclaration; + updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]): EnumDeclaration; + createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags): ModuleDeclaration; + updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined): ModuleDeclaration; + createModuleBlock(statements: readonly Statement[]): ModuleBlock; + updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]): ModuleBlock; + createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock; + updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]): CaseBlock; + createNamespaceExportDeclaration(name: string | Identifier): NamespaceExportDeclaration; + updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration; + createImportEqualsDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; + updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; + createImportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; + updateImportDeclaration(node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; + createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createNamespaceImport(name: Identifier): NamespaceImport; + updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport; + createNamespaceExport(name: Identifier): NamespaceExport; + updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport; + createNamedImports(elements: readonly ImportSpecifier[]): NamedImports; + updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]): NamedImports; + createImportSpecifier(propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; + updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; + createExportAssignment(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression): ExportAssignment; + updateExportAssignment(node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression): ExportAssignment; + createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression): ExportDeclaration; + updateExportDeclaration(node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined): ExportDeclaration; + createNamedExports(elements: readonly ExportSpecifier[]): NamedExports; + updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]): NamedExports; + createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier): ExportSpecifier; + updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; + /* @internal*/ createMissingDeclaration(): MissingDeclaration; + + // + // Module references + // + + createExternalModuleReference(expression: Expression): ExternalModuleReference; + updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; + + // + // JSDoc + // + + createJSDocAllType(): JSDocAllType; + createJSDocUnknownType(): JSDocUnknownType; + createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType; + updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType; + createJSDocNullableType(type: TypeNode): JSDocNullableType; + updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType; + createJSDocOptionalType(type: TypeNode): JSDocOptionalType; + updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType; + createJSDocFunctionType(parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType; + updateJSDocFunctionType(node: JSDocFunctionType, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType; + createJSDocVariadicType(type: TypeNode): JSDocVariadicType; + updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType; + createJSDocNamepathType(type: TypeNode): JSDocNamepathType; + updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType; + createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression; + updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression; + createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral; + updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: readonly JSDocPropertyLikeTag[] | undefined, isArrayType: boolean | undefined): JSDocTypeLiteral; + createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature; + updateJSDocSignature(node: JSDocSignature, typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type: JSDocReturnTag | undefined): JSDocSignature; + createJSDocTemplateTag(tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string): JSDocTemplateTag; + updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | undefined): JSDocTemplateTag; + createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocTypedefTag; + updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocTypedefTag; + createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; + updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; + createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; + updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; + createJSDocTypeTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; + updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocTypeTag; + createJSDocReturnTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag; + updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment: string | undefined): JSDocReturnTag; + createJSDocThisTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocThisTag; + updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment: string | undefined): JSDocThisTag; + createJSDocEnumTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocEnumTag; + updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocEnumTag; + createJSDocCallbackTag(tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocCallbackTag; + updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocCallbackTag; + createJSDocAugmentsTag(tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment?: string): JSDocAugmentsTag; + updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment: string | undefined): JSDocAugmentsTag; + createJSDocImplementsTag(tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag; + updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment: string | undefined): JSDocImplementsTag; + createJSDocAuthorTag(tagName: Identifier | undefined, comment?: string): JSDocAuthorTag; + updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier | undefined, comment: string | undefined): JSDocAuthorTag; + createJSDocClassTag(tagName: Identifier | undefined, comment?: string): JSDocClassTag; + updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier | undefined, comment: string | undefined): JSDocClassTag; + createJSDocPublicTag(tagName: Identifier | undefined, comment?: string): JSDocPublicTag; + updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier | undefined, comment: string | undefined): JSDocPublicTag; + createJSDocPrivateTag(tagName: Identifier | undefined, comment?: string): JSDocPrivateTag; + updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier | undefined, comment: string | undefined): JSDocPrivateTag; + createJSDocProtectedTag(tagName: Identifier | undefined, comment?: string): JSDocProtectedTag; + updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier | undefined, comment: string | undefined): JSDocProtectedTag; + createJSDocReadonlyTag(tagName: Identifier | undefined, comment?: string): JSDocReadonlyTag; + updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | undefined): JSDocReadonlyTag; + createJSDocUnknownTag(tagName: Identifier, comment?: string): JSDocUnknownTag; + updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | undefined): JSDocUnknownTag; + createJSDocComment(comment?: string | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc; + updateJSDocComment(node: JSDoc, comment: string | undefined, tags: readonly JSDocTag[] | undefined): JSDoc; + + // + // JSX + // + + createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; + updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; + createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; + updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; + createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement; + updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement; + createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; + createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; + updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; + createJsxOpeningFragment(): JsxOpeningFragment; + createJsxJsxClosingFragment(): JsxClosingFragment; + updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; + createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression | undefined): JsxAttribute; + updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression | undefined): JsxAttribute; + createJsxAttributes(properties: readonly JsxAttributeLike[]): JsxAttributes; + updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]): JsxAttributes; + createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute; + updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute; + createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined): JsxExpression; + updateJsxExpression(node: JsxExpression, expression: Expression | undefined): JsxExpression; + + // + // Clauses + // + + createCaseClause(expression: Expression, statements: readonly Statement[]): CaseClause; + updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]): CaseClause; + createDefaultClause(statements: readonly Statement[]): DefaultClause; + updateDefaultClause(node: DefaultClause, statements: readonly Statement[]): DefaultClause; + createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]): HeritageClause; + updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]): HeritageClause; + createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause; + updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause; + + // + // Property assignments + // + + createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment; + updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment; + createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment; + updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined): ShorthandPropertyAssignment; + createSpreadAssignment(expression: Expression): SpreadAssignment; + updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; + + // + // Enum + // + + createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; + updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; + + // + // Top-level nodes + // + + createSourceFile(statements: readonly Statement[], endOfFileToken: EndOfFileToken, flags: NodeFlags): SourceFile; + updateSourceFile(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: readonly FileReference[], typeReferences?: readonly FileReference[], hasNoDefaultLib?: boolean, libReferences?: readonly FileReference[]): SourceFile; + + /* @internal */ createUnparsedSource(prologues: readonly UnparsedPrologue[], syntheticReferences: readonly UnparsedSyntheticReference[] | undefined, texts: readonly UnparsedSourceText[]): UnparsedSource; + /* @internal */ createUnparsedPrologue(data?: string): UnparsedPrologue; + /* @internal */ createUnparsedPrepend(data: string | undefined, texts: readonly UnparsedSourceText[]): UnparsedPrepend; + /* @internal */ createUnparsedTextLike(data: string | undefined, internal: boolean): UnparsedTextLike; + /* @internal */ createUnparsedSyntheticReference(section: BundleFileHasNoDefaultLib | BundleFileReference): UnparsedSyntheticReference; + /* @internal */ createInputFiles(): InputFiles; + + // + // Synthetic Nodes + // + /* @internal */ createSyntheticExpression(type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember): SyntheticExpression; + /* @internal */ createSyntaxList(children: Node[]): SyntaxList; + + // + // Transformation nodes + // + + createNotEmittedStatement(original: Node): NotEmittedStatement; + /* @internal */ createEndOfDeclarationMarker(original: Node): EndOfDeclarationMarker; + /* @internal */ createMergeDeclarationMarker(original: Node): MergeDeclarationMarker; + createPartiallyEmittedExpression(expression: Expression, original?: Node): PartiallyEmittedExpression; + updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression; + /* @internal */ createSyntheticReferenceExpression(expression: Expression, thisArg: Expression): SyntheticReferenceExpression; + /* @internal */ updateSyntheticReferenceExpression(node: SyntheticReferenceExpression, expression: Expression, thisArg: Expression): SyntheticReferenceExpression; + createCommaListExpression(elements: readonly Expression[]): CommaListExpression; + updateCommaListExpression(node: CommaListExpression, elements: readonly Expression[]): CommaListExpression; + createBundle(sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; + updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; + + // + // Common operators + // + + createComma(left: Expression, right: Expression): BinaryExpression; + createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; + createAssignment(left: Expression, right: Expression): AssignmentExpression; + createLogicalOr(left: Expression, right: Expression): BinaryExpression; + createLogicalAnd(left: Expression, right: Expression): BinaryExpression; + createBitwiseOr(left: Expression, right: Expression): BinaryExpression; + createBitwiseXor(left: Expression, right: Expression): BinaryExpression; + createBitwiseAnd(left: Expression, right: Expression): BinaryExpression; + createStrictEquality(left: Expression, right: Expression): BinaryExpression; + createStrictInequality(left: Expression, right: Expression): BinaryExpression; + createEquality(left: Expression, right: Expression): BinaryExpression; + createInequality(left: Expression, right: Expression): BinaryExpression; + createLessThan(left: Expression, right: Expression): BinaryExpression; + createLessThanEquals(left: Expression, right: Expression): BinaryExpression; + createGreaterThan(left: Expression, right: Expression): BinaryExpression; + createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression; + createLeftShift(left: Expression, right: Expression): BinaryExpression; + createRightShift(left: Expression, right: Expression): BinaryExpression; + createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression; + createAdd(left: Expression, right: Expression): BinaryExpression; + createSubtract(left: Expression, right: Expression): BinaryExpression; + createMultiply(left: Expression, right: Expression): BinaryExpression; + createDivide(left: Expression, right: Expression): BinaryExpression; + createModulo(left: Expression, right: Expression): BinaryExpression; + createExponent(left: Expression, right: Expression): BinaryExpression; + createPrefixPlus(operand: Expression): PrefixUnaryExpression; + createPrefixMinus(operand: Expression): PrefixUnaryExpression; + createPrefixIncrement(operand: Expression): PrefixUnaryExpression; + createPrefixDecrement(operand: Expression): PrefixUnaryExpression; + createBitwiseNot(operand: Expression): PrefixUnaryExpression; + createLogicalNot(operand: Expression): PrefixUnaryExpression; + createPostfixIncrement(operand: Expression): PostfixUnaryExpression; + createPostfixDecrement(operand: Expression): PostfixUnaryExpression; + + // + // Compound Nodes + // + + createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; + createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; + createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + + + createVoidZero(): VoidExpression; + createExportDefault(expression: Expression): ExportAssignment; + createExternalModuleExport(exportName: Identifier): ExportDeclaration; + + /* @internal */ createTypeCheck(value: Expression, tag: TypeOfTag): Expression; + /* @internal */ createMethodCall(object: Expression, methodName: string | Identifier, argumentsList: readonly Expression[]): CallExpression; + /* @internal */ createGlobalMethodCall(globalObjectName: string, globalMethodName: string, argumentsList: readonly Expression[]): CallExpression; + /* @internal */ createFunctionBindCall(target: Expression, thisArg: Expression, argumentsList: readonly Expression[]): CallExpression; + /* @internal */ createFunctionCallCall(target: Expression, thisArg: Expression, argumentsList: readonly Expression[]): CallExpression; + /* @internal */ createFunctionApplyCall(target: Expression, thisArg: Expression, argumentsExpression: Expression): CallExpression; + /* @internal */ createObjectDefinePropertyCall(target: Expression, propertyName: string | Expression, attributes: Expression): CallExpression; + /* @internal */ createPropertyDescriptor(attributes: PropertyDescriptorAttributes, singleLine?: boolean): ObjectLiteralExpression; + /* @internal */ createArraySliceCall(array: Expression, start?: number | Expression): CallExpression; + /* @internal */ createArrayConcatCall(array: Expression, values: readonly Expression[]): CallExpression; + /* @internal */ createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers?: boolean): CallBinding; + /* @internal */ inlineExpressions(expressions: readonly Expression[]): Expression; + /** + * Gets the internal name of a declaration. This is primarily used for declarations that can be + * referred to by name in the body of an ES5 class function body. An internal name will *never* + * be prefixed with an module or namespace export modifier like "exports." when emitted as an + * expression. An internal name will also *never* be renamed due to a collision with a block + * scoped variable. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + /* @internal */ getInternalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier; + /** + * Gets the local name of a declaration. This is primarily used for declarations that can be + * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A + * local name will *never* be prefixed with an module or namespace export modifier like + * "exports." when emitted as an expression. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + /* @internal */ getLocalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier; + /** + * Gets the export name of a declaration. This is primarily used for declarations that can be + * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An + * export name will *always* be prefixed with a module or namespace export modifier like + * `"exports."` when emitted as an expression if the name points to an exported symbol. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + /* @internal */ getExportName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier; + /** + * Gets the name of a declaration for use in declarations. + * + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + /* @internal */ getDeclarationName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier; + /** + * Gets a namespace-qualified name for use in expressions. + * + * @param ns The namespace identifier. + * @param name The name. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + /* @internal */ getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression; + /** + * Gets the exported name of a declaration for use in expressions. + * + * An exported name will *always* be prefixed with an module or namespace export modifier like + * "exports." if the name points to an exported symbol. + * + * @param ns The namespace identifier. + * @param node The declaration. + * @param allowComments A value indicating whether comments may be emitted for the name. + * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. + */ + /* @internal */ getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression; + + // + // Utilities + // + + restoreOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds?: OuterExpressionKinds): Expression; + /* @internal */ restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement | undefined, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement; + /* @internal */ createUseStrictPrologue(): PrologueDirective; + /** + * Copies any necessary standard and custom prologue-directives into target array. + * @param source origin statements array + * @param target result statements array + * @param ensureUseStrict boolean determining whether the function need to add prologue-directives + * @param visitor Optional callback used to visit any custom prologue directives. + */ + /* @internal */ copyPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number; + /** + * Copies only the standard (string-expression) prologue-directives into the target statement-array. + * @param source origin statements array + * @param target result statements array + * @param ensureUseStrict boolean determining whether the function need to add prologue-directives + */ + /* @internal */ copyStandardPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean): number; + /** + * Copies only the custom prologue-directives into target statement-array. + * @param source origin statements array + * @param target result statements array + * @param statementOffset The offset at which to begin the copy. + * @param visitor Optional callback used to visit any custom prologue directives. + */ + /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number; + /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number | undefined; + /* @internal */ ensureUseStrict(statements: NodeArray): NodeArray; + /* @internal */ liftToBlock(nodes: readonly Node[]): Statement; + /** + * Merges generated lexical declarations into a new statement list. + */ + /* @internal */ mergeLexicalEnvironment(statements: NodeArray, declarations: readonly Statement[] | undefined): NodeArray; + /** + * Appends generated lexical declarations to an array of statements. + */ + /* @internal */ mergeLexicalEnvironment(statements: Statement[], declarations: readonly Statement[] | undefined): Statement[]; + /** + * Creates a shallow, memberwise clone of a node. + * - The result will have its `original` pointer set to `node`. + * - The result will have its `pos` and `end` set to `-1`. + * - *DO NOT USE THIS* if a more appropriate function is available. + */ + /* @internal */ cloneNode(node: T): T; + /* @internal */ updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags): T; + } + /* @internal */ export const enum LexicalEnvironmentFlags { None = 0, @@ -6018,9 +7234,8 @@ namespace ts { VariablesHoistedInParameters = 1 << 1 // a temp variable was hoisted while visiting a parameter list } - export interface TransformationContext { - /*@internal*/ getEmitResolver(): EmitResolver; - /*@internal*/ getEmitHost(): EmitHost; + export interface CoreTransformationContext { + readonly factory: NodeFactory; /** Gets the compiler options supplied to the transformer. */ getCompilerOptions(): CompilerOptions; @@ -6049,6 +7264,12 @@ namespace ts { /** Adds an initialization statement to the top of the lexical environment. */ /* @internal */ addInitializationStatement(node: Statement): void; + } + + export interface TransformationContext extends CoreTransformationContext { + /*@internal*/ getEmitResolver(): EmitResolver; + /*@internal*/ getEmitHost(): EmitHost; + /*@internal*/ getEmitHelperFactory(): EmitHelperFactory; /** Records a request for a non-scoped emit helper in the current context. */ requestEmitHelper(helper: EmitHelper): void; @@ -6148,6 +7369,16 @@ namespace ts { */ export type Visitor = (node: Node) => VisitResult; + export interface NodeVisitor { + (nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; + (nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T | undefined; + } + + export interface NodesVisitor { + (nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; + (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + } + export type VisitResult = T | T[] | undefined; export interface Printer { @@ -6534,6 +7765,7 @@ namespace ts { // SyntaxKind.SyntaxList export interface SyntaxList extends Node { + kind: SyntaxKind.SyntaxList; _children: Node[]; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4fb0922febf68..90bc40b4aebc4 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -290,13 +290,13 @@ namespace ts { // If so, mark ourselves accordingly. if (thisNodeOrAnySubNodesHasError) { - node.flags |= NodeFlags.ThisNodeOrAnySubNodesHasError; + (node as Mutable).flags |= NodeFlags.ThisNodeOrAnySubNodesHasError; } // Also mark that we've propagated the child information to this node. This way we can // always consult the bit directly on this node without needing to check its children // again. - node.flags |= NodeFlags.HasAggregatedChildData; + (node as Mutable).flags |= NodeFlags.HasAggregatedChildData; } } @@ -1637,8 +1637,9 @@ namespace ts { ? (node).expression : undefined; - case SyntaxKind.Identifier: - case SyntaxKind.QualifiedName: + // TODO(rbuckton): These aren't valid TypeNodes, but we treat them as such because of `isPartOfTypeNode`, which returns `true` for things that aren't `TypeNode`s. + case SyntaxKind.Identifier as TypeNodeSyntaxKind: + case SyntaxKind.QualifiedName as TypeNodeSyntaxKind: return (node); } @@ -3104,7 +3105,6 @@ namespace ts { } } - export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral; export function isPropertyNameLiteral(node: Node): node is PropertyNameLiteral { switch (node.kind) { case SyntaxKind.Identifier: @@ -3253,24 +3253,217 @@ namespace ts { } } + export const enum OperatorPrecedence { + // Expression: + // AssignmentExpression + // Expression `,` AssignmentExpression + Comma, + + // NOTE: `Spread` is higher than `Comma` due to how it is parsed in |ElementList| + // SpreadElement: + // `...` AssignmentExpression + Spread, + + // AssignmentExpression: + // ConditionalExpression + // YieldExpression + // ArrowFunction + // AsyncArrowFunction + // LeftHandSideExpression `=` AssignmentExpression + // LeftHandSideExpression AssignmentOperator AssignmentExpression + // + // NOTE: AssignmentExpression is broken down into several precedences due to the requirements + // of the parenthesizer rules. + + // AssignmentExpression: YieldExpression + // YieldExpression: + // `yield` + // `yield` AssignmentExpression + // `yield` `*` AssignmentExpression + Yield, + + // AssignmentExpression: LeftHandSideExpression `=` AssignmentExpression + // AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression + // AssignmentOperator: one of + // `*=` `/=` `%=` `+=` `-=` `<<=` `>>=` `>>>=` `&=` `^=` `|=` `**=` + Assignment, + + // NOTE: `Conditional` is considered higher than `Assignment` here, but in reality they have + // the same precedence. + // AssignmentExpression: ConditionalExpression + // ConditionalExpression: + // ShortCircuitExpression + // ShortCircuitExpression `?` AssignmentExpression `:` AssignmentExpression + // ShortCircuitExpression: + // LogicalORExpression + // CoalesceExpression + Conditional, + + // CoalesceExpression: + // CoalesceExpressionHead `??` BitwiseORExpression + // CoalesceExpressionHead: + // CoalesceExpression + // BitwiseORExpression + Coalesce = Conditional, // NOTE: This is wrong + + // LogicalORExpression: + // LogicalANDExpression + // LogicalORExpression `||` LogicalANDExpression + LogicalOR, + + // LogicalANDExpression: + // BitwiseORExpression + // LogicalANDExprerssion `&&` BitwiseORExpression + LogicalAND, + + // BitwiseORExpression: + // BitwiseXORExpression + // BitwiseORExpression `^` BitwiseXORExpression + BitwiseOR, + + // BitwiseXORExpression: + // BitwiseANDExpression + // BitwiseXORExpression `^` BitwiseANDExpression + BitwiseXOR, + + // BitwiseANDExpression: + // EqualityExpression + // BitwiseANDExpression `^` EqualityExpression + BitwiseAND, + + // EqualityExpression: + // RelationalExpression + // EqualityExpression `==` RelationalExpression + // EqualityExpression `!=` RelationalExpression + // EqualityExpression `===` RelationalExpression + // EqualityExpression `!==` RelationalExpression + Equality, + + // RelationalExpression: + // ShiftExpression + // RelationalExpression `<` ShiftExpression + // RelationalExpression `>` ShiftExpression + // RelationalExpression `<=` ShiftExpression + // RelationalExpression `>=` ShiftExpression + // RelationalExpression `instanceof` ShiftExpression + // RelationalExpression `in` ShiftExpression + // [+TypeScript] RelationalExpression `as` Type + Relational, + + // ShiftExpression: + // AdditiveExpression + // ShiftExpression `<<` AdditiveExpression + // ShiftExpression `>>` AdditiveExpression + // ShiftExpression `>>>` AdditiveExpression + Shift, + + // AdditiveExpression: + // MultiplicativeExpression + // AdditiveExpression `+` MultiplicativeExpression + // AdditiveExpression `-` MultiplicativeExpression + Additive, + + // MultiplicativeExpression: + // ExponentiationExpression + // MultiplicativeExpression MultiplicativeOperator ExponentiationExpression + // MultiplicativeOperator: one of `*`, `/`, `%` + Multiplicative, + + // ExponentiationExpression: + // UnaryExpression + // UpdateExpression `**` ExponentiationExpression + Exponentiation, + + // UnaryExpression: + // UpdateExpression + // `delete` UnaryExpression + // `void` UnaryExpression + // `typeof` UnaryExpression + // `+` UnaryExpression + // `-` UnaryExpression + // `~` UnaryExpression + // `!` UnaryExpression + // AwaitExpression + // UpdateExpression: // TODO: Do we need to investigate the precedence here? + // `++` UnaryExpression + // `--` UnaryExpression + Unary, + + + // UpdateExpression: + // LeftHandSideExpression + // LeftHandSideExpression `++` + // LeftHandSideExpression `--` + Update, + + // LeftHandSideExpression: + // NewExpression + // CallExpression + // NewExpression: + // MemberExpression + // `new` NewExpression + LeftHandSide, + + // CallExpression: + // CoverCallExpressionAndAsyncArrowHead + // SuperCall + // ImportCall + // CallExpression Arguments + // CallExpression `[` Expression `]` + // CallExpression `.` IdentifierName + // CallExpression TemplateLiteral + // MemberExpression: + // PrimaryExpression + // MemberExpression `[` Expression `]` + // MemberExpression `.` IdentifierName + // MemberExpression TemplateLiteral + // SuperProperty + // MetaProperty + // `new` MemberExpression Arguments + Member, + + // TODO: JSXElement? + // PrimaryExpression: + // `this` + // IdentifierReference + // Literal + // ArrayLiteral + // ObjectLiteral + // FunctionExpression + // ClassExpression + // GeneratorExpression + // AsyncFunctionExpression + // AsyncGeneratorExpression + // RegularExpressionLiteral + // TemplateLiteral + // CoverParenthesizedExpressionAndArrowParameterList + Primary, + + Highest = Primary, + Lowest = Comma, + // -1 is lower than all other precedences. Returning it will cause binary expression + // parsing to stop. + Invalid = -1, + } + export function getOperatorPrecedence(nodeKind: SyntaxKind, operatorKind: SyntaxKind, hasArguments?: boolean) { switch (nodeKind) { case SyntaxKind.CommaListExpression: - return 0; + return OperatorPrecedence.Comma; case SyntaxKind.SpreadElement: - return 1; + return OperatorPrecedence.Spread; case SyntaxKind.YieldExpression: - return 2; + return OperatorPrecedence.Yield; case SyntaxKind.ConditionalExpression: - return 4; + return OperatorPrecedence.Conditional; case SyntaxKind.BinaryExpression: switch (operatorKind) { case SyntaxKind.CommaToken: - return 0; + return OperatorPrecedence.Comma; case SyntaxKind.EqualsToken: case SyntaxKind.PlusEqualsToken: @@ -3288,32 +3481,34 @@ namespace ts { case SyntaxKind.BarBarEqualsToken: case SyntaxKind.AmpersandAmpersandEqualsToken: case SyntaxKind.QuestionQuestionEqualsToken: - return 3; + return OperatorPrecedence.Assignment; default: return getBinaryOperatorPrecedence(operatorKind); } + // TODO: Should prefix `++` and `--` be moved to the `Update` precedence? + // TODO: We are missing `TypeAssertionExpression` case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.TypeOfExpression: case SyntaxKind.VoidExpression: case SyntaxKind.DeleteExpression: case SyntaxKind.AwaitExpression: - return 16; + return OperatorPrecedence.Unary; case SyntaxKind.PostfixUnaryExpression: - return 17; + return OperatorPrecedence.Update; case SyntaxKind.CallExpression: - return 18; + return OperatorPrecedence.LeftHandSide; case SyntaxKind.NewExpression: - return hasArguments ? 19 : 18; + return hasArguments ? OperatorPrecedence.Member : OperatorPrecedence.LeftHandSide; case SyntaxKind.TaggedTemplateExpression: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: - return 19; + return OperatorPrecedence.Member; case SyntaxKind.ThisKeyword: case SyntaxKind.SuperKeyword: @@ -3329,40 +3524,40 @@ namespace ts { case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: case SyntaxKind.ClassExpression: - case SyntaxKind.JsxElement: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxFragment: case SyntaxKind.RegularExpressionLiteral: case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.TemplateExpression: case SyntaxKind.ParenthesizedExpression: case SyntaxKind.OmittedExpression: - return 20; + case SyntaxKind.JsxElement: + case SyntaxKind.JsxSelfClosingElement: + case SyntaxKind.JsxFragment: + return OperatorPrecedence.Primary; default: - return -1; + return OperatorPrecedence.Invalid; } } - export function getBinaryOperatorPrecedence(kind: SyntaxKind): number { + export function getBinaryOperatorPrecedence(kind: SyntaxKind): OperatorPrecedence { switch (kind) { case SyntaxKind.QuestionQuestionToken: - return 4; + return OperatorPrecedence.Coalesce; case SyntaxKind.BarBarToken: - return 5; + return OperatorPrecedence.LogicalOR; case SyntaxKind.AmpersandAmpersandToken: - return 6; + return OperatorPrecedence.LogicalAND; case SyntaxKind.BarToken: - return 7; + return OperatorPrecedence.BitwiseOR; case SyntaxKind.CaretToken: - return 8; + return OperatorPrecedence.BitwiseXOR; case SyntaxKind.AmpersandToken: - return 9; + return OperatorPrecedence.BitwiseAND; case SyntaxKind.EqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.ExclamationEqualsEqualsToken: - return 10; + return OperatorPrecedence.Equality; case SyntaxKind.LessThanToken: case SyntaxKind.GreaterThanToken: case SyntaxKind.LessThanEqualsToken: @@ -3370,20 +3565,20 @@ namespace ts { case SyntaxKind.InstanceOfKeyword: case SyntaxKind.InKeyword: case SyntaxKind.AsKeyword: - return 11; + return OperatorPrecedence.Relational; case SyntaxKind.LessThanLessThanToken: case SyntaxKind.GreaterThanGreaterThanToken: case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - return 12; + return OperatorPrecedence.Shift; case SyntaxKind.PlusToken: case SyntaxKind.MinusToken: - return 13; + return OperatorPrecedence.Additive; case SyntaxKind.AsteriskToken: case SyntaxKind.SlashToken: case SyntaxKind.PercentToken: - return 14; + return OperatorPrecedence.Multiplicative; case SyntaxKind.AsteriskAsteriskToken: - return 15; + return OperatorPrecedence.Exponentiation; } // -1 is lower than all other precedences. Returning it will cause binary expression @@ -4927,7 +5122,7 @@ namespace ts { return filter(node.declarations, isInitializedVariable); } - function isInitializedVariable(node: VariableDeclaration) { + function isInitializedVariable(node: VariableDeclaration): node is InitializedVariableDeclaration { return node.initializer !== undefined; } @@ -5195,7 +5390,7 @@ namespace ts { return isClassLike(node) || isInterfaceDeclaration(node) || isTypeLiteralNode(node); } - export function isTypeNodeKind(kind: SyntaxKind) { + export function isTypeNodeKind(kind: SyntaxKind): kind is TypeNodeSyntaxKind { return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) || kind === SyntaxKind.AnyKeyword || kind === SyntaxKind.UnknownKeyword @@ -5205,10 +5400,8 @@ namespace ts { || kind === SyntaxKind.BooleanKeyword || kind === SyntaxKind.StringKeyword || kind === SyntaxKind.SymbolKeyword - || kind === SyntaxKind.ThisKeyword || kind === SyntaxKind.VoidKeyword || kind === SyntaxKind.UndefinedKeyword - || kind === SyntaxKind.NullKeyword || kind === SyntaxKind.NeverKeyword || kind === SyntaxKind.ExpressionWithTypeArguments || kind === SyntaxKind.JSDocAllType @@ -5246,6 +5439,43 @@ namespace ts { return node.kind === SyntaxKind.NamedImports || node.kind === SyntaxKind.NamedExports; } + export function getLeftmostExpression(node: Expression, stopAtCallExpressions: boolean) { + while (true) { + switch (node.kind) { + case SyntaxKind.PostfixUnaryExpression: + node = (node).operand; + continue; + + case SyntaxKind.BinaryExpression: + node = (node).left; + continue; + + case SyntaxKind.ConditionalExpression: + node = (node).condition; + continue; + + case SyntaxKind.TaggedTemplateExpression: + node = (node).tag; + continue; + + case SyntaxKind.CallExpression: + if (stopAtCallExpressions) { + return node; + } + // falls through + case SyntaxKind.AsExpression: + case SyntaxKind.ElementAccessExpression: + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.NonNullExpression: + case SyntaxKind.PartiallyEmittedExpression: + node = (node).expression; + continue; + } + + return node; + } + } + export interface ObjectAllocator { getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token; @@ -5282,7 +5512,7 @@ namespace ts { } } - function Node(this: Node, kind: SyntaxKind, pos: number, end: number) { + function Node(this: Mutable, kind: SyntaxKind, pos: number, end: number) { this.pos = pos; this.end = end; this.kind = kind; @@ -5294,7 +5524,7 @@ namespace ts { this.original = undefined; } - function Token(this: Node, kind: SyntaxKind, pos: number, end: number) { + function Token(this: Mutable, kind: SyntaxKind, pos: number, end: number) { this.pos = pos; this.end = end; this.kind = kind; @@ -5304,7 +5534,7 @@ namespace ts { this.parent = undefined!; } - function Identifier(this: Node, kind: SyntaxKind, pos: number, end: number) { + function Identifier(this: Mutable, kind: SyntaxKind, pos: number, end: number) { this.pos = pos; this.end = end; this.kind = kind; @@ -5354,6 +5584,76 @@ namespace ts { return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message; } + export function createDetachedDiagnostic(fileName: string, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithDetachedLocation; + export function createDetachedDiagnostic(fileName: string, start: number, length: number, message: DiagnosticMessage): DiagnosticWithDetachedLocation { + Debug.assertGreaterThanOrEqual(start, 0); + Debug.assertGreaterThanOrEqual(length, 0); + + let text = getLocaleSpecificMessage(message); + + if (arguments.length > 4) { + text = formatStringFromArgs(text, arguments, 4); + } + + return { + file: undefined, + start, + length, + + messageText: text, + category: message.category, + code: message.code, + reportsUnnecessary: message.reportsUnnecessary, + fileName, + }; + } + + function isDiagnosticWithDetachedLocation(diagnostic: DiagnosticRelatedInformation | DiagnosticWithDetachedLocation): diagnostic is DiagnosticWithDetachedLocation { + return diagnostic.file === undefined + && diagnostic.start !== undefined + && diagnostic.length !== undefined + && typeof (diagnostic as DiagnosticWithDetachedLocation).fileName === "string"; + } + + function attachFileToDiagnostic(diagnostic: DiagnosticWithDetachedLocation, file: SourceFile): DiagnosticWithLocation { + const fileName = file.fileName || ""; + const length = file.text.length; + Debug.assertEqual(diagnostic.fileName, fileName); + Debug.assertLessThanOrEqual(diagnostic.start, length); + Debug.assertLessThanOrEqual(diagnostic.start + diagnostic.length, length); + const diagnosticWithLocation: DiagnosticWithLocation = { + file, + start: diagnostic.start, + length: diagnostic.length, + messageText: diagnostic.messageText, + category: diagnostic.category, + code: diagnostic.code, + reportsUnnecessary: diagnostic.reportsUnnecessary + }; + if (diagnostic.relatedInformation) { + diagnosticWithLocation.relatedInformation = []; + for (const related of diagnostic.relatedInformation) { + if (isDiagnosticWithDetachedLocation(related) && related.fileName === fileName) { + Debug.assertLessThanOrEqual(related.start, length); + Debug.assertLessThanOrEqual(related.start + related.length, length); + diagnosticWithLocation.relatedInformation.push(attachFileToDiagnostic(related, file)); + } + else { + diagnosticWithLocation.relatedInformation.push(related); + } + } + } + return diagnosticWithLocation; + } + + export function attachFileToDiagnostics(diagnostics: DiagnosticWithDetachedLocation[], file: SourceFile): DiagnosticWithLocation[] { + const diagnosticsWithLocation: DiagnosticWithLocation[] = []; + for (const diagnostic of diagnostics) { + diagnosticsWithLocation.push(attachFileToDiagnostic(diagnostic, file)); + } + return diagnosticsWithLocation; + } + export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation; export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): DiagnosticWithLocation { Debug.assertGreaterThanOrEqual(start, 0); @@ -5522,6 +5822,11 @@ namespace ts { return Comparison.EqualTo; } + export function getLanguageVariant(scriptKind: ScriptKind) { + // .tsx and .jsx files are treated as jsx language variant. + return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; + } + export function getEmitScriptTarget(compilerOptions: CompilerOptions) { return compilerOptions.target || ScriptTarget.ES3; } @@ -6479,4 +6784,119 @@ namespace ts { } return true; } + + /** + * Bypasses immutability and directly sets the `pos` property of a `TextRange` or `Node`. + */ + /* @internal */ + export function setTextRangePos(range: T, pos: number) { + (range as TextRange).pos = pos; + return range; + } + + /** + * Bypasses immutability and directly sets the `end` property of a `TextRange` or `Node`. + */ + /* @internal */ + export function setTextRangeEnd(range: T, end: number) { + (range as TextRange).end = end; + return range; + } + + /** + * Bypasses immutability and directly sets the `pos` and `end` properties of a `TextRange` or `Node`. + */ + /* @internal */ + export function setTextRangePosEnd(range: T, pos: number, end: number) { + return setTextRangeEnd(setTextRangePos(range, pos), end); + } + + /** + * Bypasses immutability and directly sets the `pos` and `end` properties of a `TextRange` or `Node` from the + * provided position and width. + */ + /* @internal */ + export function setTextRangePosWidth(range: T, pos: number, width: number) { + return setTextRangePosEnd(range, pos, pos + width); + } + + /** + * Bypasses immutability and directly sets the `flags` property of a `Node`. + */ + /* @internal */ + export function setNodeFlags(node: T, newFlags: NodeFlags): T; + /* @internal */ + export function setNodeFlags(node: T | undefined, newFlags: NodeFlags): T | undefined; + export function setNodeFlags(node: T | undefined, newFlags: NodeFlags): T | undefined { + if (node) { + (node as Mutable).flags = newFlags; + } + return node; + } + + /** + * Bypasses immutability and directly sets the `parent` property of a `Node`. + */ + /* @internal */ + export function setParent(child: T, parent: T["parent"] | undefined): T; + /* @internal */ + export function setParent(child: T | undefined, parent: T["parent"] | undefined): T | undefined; + export function setParent(child: T | undefined, parent: T["parent"] | undefined): T | undefined { + if (child && parent) { + (child as Mutable).parent = parent; + } + return child; + } + + /** + * Bypasses immutability and directly sets the `parent` property of each `Node` in an array of nodes, if is not already set. + */ + /* @internal */ + export function setEachParent(children: T, parent: T[number]["parent"]): T; + /* @internal */ + export function setEachParent(children: T | undefined, parent: T[number]["parent"]): T | undefined; + export function setEachParent(children: T | undefined, parent: T[number]["parent"]): T | undefined { + if (children) { + for (const child of children) { + setParent(child, parent); + } + } + return children; + } + + /** + * Bypasses immutability and directly sets the `parent` property of each `Node` recursively. + * @param rootNode The root node from which to start the recursion. + * @param incremental When `true`, only recursively descends through nodes whose `parent` pointers are incorrect. + * This allows us to quickly bail out of setting `parent` for subtrees during incremental parsing. + */ + /* @internal */ + export function setParentRecursive(rootNode: T, incremental: boolean): T; + /* @internal */ + export function setParentRecursive(rootNode: T | undefined, incremental: boolean): T | undefined; + export function setParentRecursive(rootNode: T | undefined, incremental: boolean): T | undefined { + if (!rootNode) return rootNode; + forEachChildRecursively(rootNode, isJSDocNode(rootNode) ? bindParentToChildIgnoringJSDoc : bindParentToChild); + return rootNode; + + function bindParentToChildIgnoringJSDoc(child: Node, parent: Node): void | "skip" { + if (incremental && child.parent === parent) { + return "skip"; + } + setParent(child, parent); + } + + function bindJSDoc(child: Node) { + if (hasJSDocNodes(child)) { + for (const doc of child.jsDoc!) { + bindParentToChildIgnoringJSDoc(doc, child); + forEachChildRecursively(doc, bindParentToChildIgnoringJSDoc); + } + } + } + + function bindParentToChild(child: Node, parent: Node) { + return bindParentToChildIgnoringJSDoc(child, parent) || bindJSDoc(child); + } + } } diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index add1ad2afab04..8968db02d00a4 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -413,7 +413,7 @@ namespace ts { * @param node The original node. * @returns The original parse tree node if found; otherwise, undefined. */ - export function getParseTreeNode(node: Node): Node; + export function getParseTreeNode(node: Node | undefined): Node | undefined; /** * Gets the original parse tree node for a node. @@ -422,19 +422,19 @@ namespace ts { * @param nodeTest A callback used to ensure the correct type of parse tree node is returned. * @returns The original parse tree node if found; otherwise, undefined. */ - export function getParseTreeNode(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined; + export function getParseTreeNode(node: T | undefined, nodeTest?: (node: Node) => node is T): T | undefined; export function getParseTreeNode(node: Node | undefined, nodeTest?: (node: Node) => boolean): Node | undefined { if (node === undefined || isParseTreeNode(node)) { return node; } - node = getOriginalNode(node); - - if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) { - return node; + node = node.original; + while (node) { + if (isParseTreeNode(node)) { + return !nodeTest || nodeTest(node) ? node : undefined; + } + node = node.original; } - - return undefined; } /** Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' */ @@ -888,251 +888,24 @@ namespace ts { } // #region - // Simple node tests of the form `node.kind === SyntaxKind.Foo`. - // Literals - export function isNumericLiteral(node: Node): node is NumericLiteral { - return node.kind === SyntaxKind.NumericLiteral; - } - - export function isBigIntLiteral(node: Node): node is BigIntLiteral { - return node.kind === SyntaxKind.BigIntLiteral; - } - - export function isStringLiteral(node: Node): node is StringLiteral { - return node.kind === SyntaxKind.StringLiteral; - } - - export function isJsxText(node: Node): node is JsxText { - return node.kind === SyntaxKind.JsxText; - } - - export function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral { - return node.kind === SyntaxKind.RegularExpressionLiteral; - } - - export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral { - return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral; - } - - // Pseudo-literals - - export function isTemplateHead(node: Node): node is TemplateHead { - return node.kind === SyntaxKind.TemplateHead; - } - - export function isTemplateMiddle(node: Node): node is TemplateMiddle { - return node.kind === SyntaxKind.TemplateMiddle; - } - - export function isTemplateTail(node: Node): node is TemplateTail { - return node.kind === SyntaxKind.TemplateTail; - } - - export function isIdentifier(node: Node): node is Identifier { - return node.kind === SyntaxKind.Identifier; - } - - // Names - - export function isQualifiedName(node: Node): node is QualifiedName { - return node.kind === SyntaxKind.QualifiedName; - } - - export function isComputedPropertyName(node: Node): node is ComputedPropertyName { - return node.kind === SyntaxKind.ComputedPropertyName; - } - - export function isPrivateIdentifier(node: Node): node is PrivateIdentifier { - return node.kind === SyntaxKind.PrivateIdentifier; - } export function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier { return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateIdentifier; } - // Signature elements - - export function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration { - return node.kind === SyntaxKind.TypeParameter; - } - - export function isParameter(node: Node): node is ParameterDeclaration { - return node.kind === SyntaxKind.Parameter; - } - - export function isDecorator(node: Node): node is Decorator { - return node.kind === SyntaxKind.Decorator; - } - - // TypeMember - - export function isPropertySignature(node: Node): node is PropertySignature { - return node.kind === SyntaxKind.PropertySignature; - } - - export function isPropertyDeclaration(node: Node): node is PropertyDeclaration { - return node.kind === SyntaxKind.PropertyDeclaration; - } - - export function isMethodSignature(node: Node): node is MethodSignature { - return node.kind === SyntaxKind.MethodSignature; - } - - export function isMethodDeclaration(node: Node): node is MethodDeclaration { - return node.kind === SyntaxKind.MethodDeclaration; - } - - export function isConstructorDeclaration(node: Node): node is ConstructorDeclaration { - return node.kind === SyntaxKind.Constructor; - } - - export function isGetAccessorDeclaration(node: Node): node is GetAccessorDeclaration { - return node.kind === SyntaxKind.GetAccessor; - } - - export function isSetAccessorDeclaration(node: Node): node is SetAccessorDeclaration { - return node.kind === SyntaxKind.SetAccessor; - } - - export function isCallSignatureDeclaration(node: Node): node is CallSignatureDeclaration { - return node.kind === SyntaxKind.CallSignature; - } - - export function isConstructSignatureDeclaration(node: Node): node is ConstructSignatureDeclaration { - return node.kind === SyntaxKind.ConstructSignature; - } - - export function isIndexSignatureDeclaration(node: Node): node is IndexSignatureDeclaration { - return node.kind === SyntaxKind.IndexSignature; - } - /* @internal */ export function isGetOrSetAccessorDeclaration(node: Node): node is AccessorDeclaration { return node.kind === SyntaxKind.SetAccessor || node.kind === SyntaxKind.GetAccessor; } - // Type - - export function isTypePredicateNode(node: Node): node is TypePredicateNode { - return node.kind === SyntaxKind.TypePredicate; - } - - export function isTypeReferenceNode(node: Node): node is TypeReferenceNode { - return node.kind === SyntaxKind.TypeReference; - } - - export function isFunctionTypeNode(node: Node): node is FunctionTypeNode { - return node.kind === SyntaxKind.FunctionType; - } - - export function isConstructorTypeNode(node: Node): node is ConstructorTypeNode { - return node.kind === SyntaxKind.ConstructorType; - } - - export function isTypeQueryNode(node: Node): node is TypeQueryNode { - return node.kind === SyntaxKind.TypeQuery; - } - - export function isTypeLiteralNode(node: Node): node is TypeLiteralNode { - return node.kind === SyntaxKind.TypeLiteral; - } - - export function isArrayTypeNode(node: Node): node is ArrayTypeNode { - return node.kind === SyntaxKind.ArrayType; - } - - export function isTupleTypeNode(node: Node): node is TupleTypeNode { - return node.kind === SyntaxKind.TupleType; - } - - export function isUnionTypeNode(node: Node): node is UnionTypeNode { - return node.kind === SyntaxKind.UnionType; - } - - export function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode { - return node.kind === SyntaxKind.IntersectionType; - } - - export function isConditionalTypeNode(node: Node): node is ConditionalTypeNode { - return node.kind === SyntaxKind.ConditionalType; - } - - export function isInferTypeNode(node: Node): node is InferTypeNode { - return node.kind === SyntaxKind.InferType; - } - - export function isParenthesizedTypeNode(node: Node): node is ParenthesizedTypeNode { - return node.kind === SyntaxKind.ParenthesizedType; - } - - export function isThisTypeNode(node: Node): node is ThisTypeNode { - return node.kind === SyntaxKind.ThisType; - } - - export function isTypeOperatorNode(node: Node): node is TypeOperatorNode { - return node.kind === SyntaxKind.TypeOperator; - } - - export function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode { - return node.kind === SyntaxKind.IndexedAccessType; - } - - export function isMappedTypeNode(node: Node): node is MappedTypeNode { - return node.kind === SyntaxKind.MappedType; - } - - export function isLiteralTypeNode(node: Node): node is LiteralTypeNode { - return node.kind === SyntaxKind.LiteralType; - } - - export function isImportTypeNode(node: Node): node is ImportTypeNode { - return node.kind === SyntaxKind.ImportType; - } - - // Binding patterns - - export function isObjectBindingPattern(node: Node): node is ObjectBindingPattern { - return node.kind === SyntaxKind.ObjectBindingPattern; - } - - export function isArrayBindingPattern(node: Node): node is ArrayBindingPattern { - return node.kind === SyntaxKind.ArrayBindingPattern; - } - - export function isBindingElement(node: Node): node is BindingElement { - return node.kind === SyntaxKind.BindingElement; - } - - // Expression - - export function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression { - return node.kind === SyntaxKind.ArrayLiteralExpression; - } - - export function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression { - return node.kind === SyntaxKind.ObjectLiteralExpression; - } - - export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression { - return node.kind === SyntaxKind.PropertyAccessExpression; - } - export function isPropertyAccessChain(node: Node): node is PropertyAccessChain { return isPropertyAccessExpression(node) && !!(node.flags & NodeFlags.OptionalChain); } - export function isElementAccessExpression(node: Node): node is ElementAccessExpression { - return node.kind === SyntaxKind.ElementAccessExpression; - } - export function isElementAccessChain(node: Node): node is ElementAccessChain { return isElementAccessExpression(node) && !!(node.flags & NodeFlags.OptionalChain); } - export function isCallExpression(node: Node): node is CallExpression { - return node.kind === SyntaxKind.CallExpression; - } - export function isCallChain(node: Node): node is CallChain { return isCallExpression(node) && !!(node.flags & NodeFlags.OptionalChain); } @@ -1181,408 +954,29 @@ namespace ts { return node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.QuestionQuestionToken; } - export function isNewExpression(node: Node): node is NewExpression { - return node.kind === SyntaxKind.NewExpression; - } - - export function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression { - return node.kind === SyntaxKind.TaggedTemplateExpression; - } - - export function isTypeAssertion(node: Node): node is TypeAssertion { - return node.kind === SyntaxKind.TypeAssertionExpression; - } - export function isConstTypeReference(node: Node) { return isTypeReferenceNode(node) && isIdentifier(node.typeName) && node.typeName.escapedText === "const" && !node.typeArguments; } - export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression { - return node.kind === SyntaxKind.ParenthesizedExpression; - } - export function skipPartiallyEmittedExpressions(node: Expression): Expression; export function skipPartiallyEmittedExpressions(node: Node): Node; export function skipPartiallyEmittedExpressions(node: Node) { return skipOuterExpressions(node, OuterExpressionKinds.PartiallyEmittedExpressions); } - export function isFunctionExpression(node: Node): node is FunctionExpression { - return node.kind === SyntaxKind.FunctionExpression; - } - - export function isArrowFunction(node: Node): node is ArrowFunction { - return node.kind === SyntaxKind.ArrowFunction; - } - - export function isDeleteExpression(node: Node): node is DeleteExpression { - return node.kind === SyntaxKind.DeleteExpression; - } - - export function isTypeOfExpression(node: Node): node is TypeOfExpression { - return node.kind === SyntaxKind.TypeOfExpression; - } - - export function isVoidExpression(node: Node): node is VoidExpression { - return node.kind === SyntaxKind.VoidExpression; - } - - export function isAwaitExpression(node: Node): node is AwaitExpression { - return node.kind === SyntaxKind.AwaitExpression; - } - - export function isPrefixUnaryExpression(node: Node): node is PrefixUnaryExpression { - return node.kind === SyntaxKind.PrefixUnaryExpression; - } - - export function isPostfixUnaryExpression(node: Node): node is PostfixUnaryExpression { - return node.kind === SyntaxKind.PostfixUnaryExpression; - } - - export function isBinaryExpression(node: Node): node is BinaryExpression { - return node.kind === SyntaxKind.BinaryExpression; - } - - export function isConditionalExpression(node: Node): node is ConditionalExpression { - return node.kind === SyntaxKind.ConditionalExpression; - } - - export function isTemplateExpression(node: Node): node is TemplateExpression { - return node.kind === SyntaxKind.TemplateExpression; - } - - export function isYieldExpression(node: Node): node is YieldExpression { - return node.kind === SyntaxKind.YieldExpression; - } - - export function isSpreadElement(node: Node): node is SpreadElement { - return node.kind === SyntaxKind.SpreadElement; - } - - export function isClassExpression(node: Node): node is ClassExpression { - return node.kind === SyntaxKind.ClassExpression; - } - - export function isOmittedExpression(node: Node): node is OmittedExpression { - return node.kind === SyntaxKind.OmittedExpression; - } - - export function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments { - return node.kind === SyntaxKind.ExpressionWithTypeArguments; - } - - export function isAsExpression(node: Node): node is AsExpression { - return node.kind === SyntaxKind.AsExpression; - } - - export function isNonNullExpression(node: Node): node is NonNullExpression { - return node.kind === SyntaxKind.NonNullExpression; - } - export function isNonNullChain(node: Node): node is NonNullChain { return isNonNullExpression(node) && !!(node.flags & NodeFlags.OptionalChain); } - export function isMetaProperty(node: Node): node is MetaProperty { - return node.kind === SyntaxKind.MetaProperty; - } - - // Misc - - export function isTemplateSpan(node: Node): node is TemplateSpan { - return node.kind === SyntaxKind.TemplateSpan; - } - - export function isSemicolonClassElement(node: Node): node is SemicolonClassElement { - return node.kind === SyntaxKind.SemicolonClassElement; - } - - // Block - - export function isBlock(node: Node): node is Block { - return node.kind === SyntaxKind.Block; - } - - export function isVariableStatement(node: Node): node is VariableStatement { - return node.kind === SyntaxKind.VariableStatement; - } - - export function isEmptyStatement(node: Node): node is EmptyStatement { - return node.kind === SyntaxKind.EmptyStatement; - } - - export function isExpressionStatement(node: Node): node is ExpressionStatement { - return node.kind === SyntaxKind.ExpressionStatement; - } - - export function isIfStatement(node: Node): node is IfStatement { - return node.kind === SyntaxKind.IfStatement; - } - - export function isDoStatement(node: Node): node is DoStatement { - return node.kind === SyntaxKind.DoStatement; - } - - export function isWhileStatement(node: Node): node is WhileStatement { - return node.kind === SyntaxKind.WhileStatement; - } - - export function isForStatement(node: Node): node is ForStatement { - return node.kind === SyntaxKind.ForStatement; - } - - export function isForInStatement(node: Node): node is ForInStatement { - return node.kind === SyntaxKind.ForInStatement; - } - - export function isForOfStatement(node: Node): node is ForOfStatement { - return node.kind === SyntaxKind.ForOfStatement; - } - - export function isContinueStatement(node: Node): node is ContinueStatement { - return node.kind === SyntaxKind.ContinueStatement; - } - - export function isBreakStatement(node: Node): node is BreakStatement { - return node.kind === SyntaxKind.BreakStatement; - } - export function isBreakOrContinueStatement(node: Node): node is BreakOrContinueStatement { return node.kind === SyntaxKind.BreakStatement || node.kind === SyntaxKind.ContinueStatement; } - export function isReturnStatement(node: Node): node is ReturnStatement { - return node.kind === SyntaxKind.ReturnStatement; - } - - export function isWithStatement(node: Node): node is WithStatement { - return node.kind === SyntaxKind.WithStatement; - } - - export function isSwitchStatement(node: Node): node is SwitchStatement { - return node.kind === SyntaxKind.SwitchStatement; - } - - export function isLabeledStatement(node: Node): node is LabeledStatement { - return node.kind === SyntaxKind.LabeledStatement; - } - - export function isThrowStatement(node: Node): node is ThrowStatement { - return node.kind === SyntaxKind.ThrowStatement; - } - - export function isTryStatement(node: Node): node is TryStatement { - return node.kind === SyntaxKind.TryStatement; - } - - export function isDebuggerStatement(node: Node): node is DebuggerStatement { - return node.kind === SyntaxKind.DebuggerStatement; - } - - export function isVariableDeclaration(node: Node): node is VariableDeclaration { - return node.kind === SyntaxKind.VariableDeclaration; - } - - export function isVariableDeclarationList(node: Node): node is VariableDeclarationList { - return node.kind === SyntaxKind.VariableDeclarationList; - } - - export function isFunctionDeclaration(node: Node): node is FunctionDeclaration { - return node.kind === SyntaxKind.FunctionDeclaration; - } - - export function isClassDeclaration(node: Node): node is ClassDeclaration { - return node.kind === SyntaxKind.ClassDeclaration; - } - - export function isInterfaceDeclaration(node: Node): node is InterfaceDeclaration { - return node.kind === SyntaxKind.InterfaceDeclaration; - } - - export function isTypeAliasDeclaration(node: Node): node is TypeAliasDeclaration { - return node.kind === SyntaxKind.TypeAliasDeclaration; - } - - export function isEnumDeclaration(node: Node): node is EnumDeclaration { - return node.kind === SyntaxKind.EnumDeclaration; - } - - export function isModuleDeclaration(node: Node): node is ModuleDeclaration { - return node.kind === SyntaxKind.ModuleDeclaration; - } - - export function isModuleBlock(node: Node): node is ModuleBlock { - return node.kind === SyntaxKind.ModuleBlock; - } - - export function isCaseBlock(node: Node): node is CaseBlock { - return node.kind === SyntaxKind.CaseBlock; - } - - export function isNamespaceExportDeclaration(node: Node): node is NamespaceExportDeclaration { - return node.kind === SyntaxKind.NamespaceExportDeclaration; - } - - export function isImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration { - return node.kind === SyntaxKind.ImportEqualsDeclaration; - } - - export function isImportDeclaration(node: Node): node is ImportDeclaration { - return node.kind === SyntaxKind.ImportDeclaration; - } - - export function isImportClause(node: Node): node is ImportClause { - return node.kind === SyntaxKind.ImportClause; - } - - export function isNamespaceImport(node: Node): node is NamespaceImport { - return node.kind === SyntaxKind.NamespaceImport; - } - - export function isNamespaceExport(node: Node): node is NamespaceExport { - return node.kind === SyntaxKind.NamespaceExport; - } - export function isNamedExportBindings(node: Node): node is NamedExportBindings { return node.kind === SyntaxKind.NamespaceExport || node.kind === SyntaxKind.NamedExports; } - export function isNamedImports(node: Node): node is NamedImports { - return node.kind === SyntaxKind.NamedImports; - } - - export function isImportSpecifier(node: Node): node is ImportSpecifier { - return node.kind === SyntaxKind.ImportSpecifier; - } - - export function isExportAssignment(node: Node): node is ExportAssignment { - return node.kind === SyntaxKind.ExportAssignment; - } - - export function isExportDeclaration(node: Node): node is ExportDeclaration { - return node.kind === SyntaxKind.ExportDeclaration; - } - - export function isNamedExports(node: Node): node is NamedExports { - return node.kind === SyntaxKind.NamedExports; - } - - export function isExportSpecifier(node: Node): node is ExportSpecifier { - return node.kind === SyntaxKind.ExportSpecifier; - } - - export function isMissingDeclaration(node: Node): node is MissingDeclaration { - return node.kind === SyntaxKind.MissingDeclaration; - } - - // Module References - - export function isExternalModuleReference(node: Node): node is ExternalModuleReference { - return node.kind === SyntaxKind.ExternalModuleReference; - } - - // JSX - - export function isJsxElement(node: Node): node is JsxElement { - return node.kind === SyntaxKind.JsxElement; - } - - export function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement { - return node.kind === SyntaxKind.JsxSelfClosingElement; - } - - export function isJsxOpeningElement(node: Node): node is JsxOpeningElement { - return node.kind === SyntaxKind.JsxOpeningElement; - } - - export function isJsxClosingElement(node: Node): node is JsxClosingElement { - return node.kind === SyntaxKind.JsxClosingElement; - } - - export function isJsxFragment(node: Node): node is JsxFragment { - return node.kind === SyntaxKind.JsxFragment; - } - - export function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment { - return node.kind === SyntaxKind.JsxOpeningFragment; - } - - export function isJsxClosingFragment(node: Node): node is JsxClosingFragment { - return node.kind === SyntaxKind.JsxClosingFragment; - } - - export function isJsxAttribute(node: Node): node is JsxAttribute { - return node.kind === SyntaxKind.JsxAttribute; - } - - export function isJsxAttributes(node: Node): node is JsxAttributes { - return node.kind === SyntaxKind.JsxAttributes; - } - - export function isJsxSpreadAttribute(node: Node): node is JsxSpreadAttribute { - return node.kind === SyntaxKind.JsxSpreadAttribute; - } - - export function isJsxExpression(node: Node): node is JsxExpression { - return node.kind === SyntaxKind.JsxExpression; - } - - // Clauses - - export function isCaseClause(node: Node): node is CaseClause { - return node.kind === SyntaxKind.CaseClause; - } - - export function isDefaultClause(node: Node): node is DefaultClause { - return node.kind === SyntaxKind.DefaultClause; - } - - export function isHeritageClause(node: Node): node is HeritageClause { - return node.kind === SyntaxKind.HeritageClause; - } - - export function isCatchClause(node: Node): node is CatchClause { - return node.kind === SyntaxKind.CatchClause; - } - - // Property assignments - - export function isPropertyAssignment(node: Node): node is PropertyAssignment { - return node.kind === SyntaxKind.PropertyAssignment; - } - - export function isShorthandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment { - return node.kind === SyntaxKind.ShorthandPropertyAssignment; - } - - export function isSpreadAssignment(node: Node): node is SpreadAssignment { - return node.kind === SyntaxKind.SpreadAssignment; - } - - // Enum - - export function isEnumMember(node: Node): node is EnumMember { - return node.kind === SyntaxKind.EnumMember; - } - - // Top-level nodes - export function isSourceFile(node: Node): node is SourceFile { - return node.kind === SyntaxKind.SourceFile; - } - - export function isBundle(node: Node): node is Bundle { - return node.kind === SyntaxKind.Bundle; - } - - export function isUnparsedSource(node: Node): node is UnparsedSource { - return node.kind === SyntaxKind.UnparsedSource; - } - - export function isUnparsedPrepend(node: Node): node is UnparsedPrepend { - return node.kind === SyntaxKind.UnparsedPrepend; - } - export function isUnparsedTextLike(node: Node): node is UnparsedTextLike { switch (node.kind) { case SyntaxKind.UnparsedText: @@ -1599,124 +993,10 @@ namespace ts { node.kind === SyntaxKind.UnparsedSyntheticReference; } - // JSDoc - - export function isJSDocTypeExpression(node: Node): node is JSDocTypeExpression { - return node.kind === SyntaxKind.JSDocTypeExpression; - } - - export function isJSDocAllType(node: Node): node is JSDocAllType { - return node.kind === SyntaxKind.JSDocAllType; - } - - export function isJSDocUnknownType(node: Node): node is JSDocUnknownType { - return node.kind === SyntaxKind.JSDocUnknownType; - } - - export function isJSDocNullableType(node: Node): node is JSDocNullableType { - return node.kind === SyntaxKind.JSDocNullableType; - } - - export function isJSDocNonNullableType(node: Node): node is JSDocNonNullableType { - return node.kind === SyntaxKind.JSDocNonNullableType; - } - - export function isJSDocOptionalType(node: Node): node is JSDocOptionalType { - return node.kind === SyntaxKind.JSDocOptionalType; - } - - export function isJSDocFunctionType(node: Node): node is JSDocFunctionType { - return node.kind === SyntaxKind.JSDocFunctionType; - } - - export function isJSDocVariadicType(node: Node): node is JSDocVariadicType { - return node.kind === SyntaxKind.JSDocVariadicType; - } - - export function isJSDoc(node: Node): node is JSDoc { - return node.kind === SyntaxKind.JSDocComment; - } - - export function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag { - return node.kind === SyntaxKind.JSDocAuthorTag; - } - - export function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag { - return node.kind === SyntaxKind.JSDocAugmentsTag; - } - - export function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag { - return node.kind === SyntaxKind.JSDocImplementsTag; - } - - export function isJSDocClassTag(node: Node): node is JSDocClassTag { - return node.kind === SyntaxKind.JSDocClassTag; - } - - export function isJSDocPublicTag(node: Node): node is JSDocPublicTag { - return node.kind === SyntaxKind.JSDocPublicTag; - } - - export function isJSDocPrivateTag(node: Node): node is JSDocPrivateTag { - return node.kind === SyntaxKind.JSDocPrivateTag; - } - - export function isJSDocProtectedTag(node: Node): node is JSDocProtectedTag { - return node.kind === SyntaxKind.JSDocProtectedTag; - } - - export function isJSDocReadonlyTag(node: Node): node is JSDocReadonlyTag { - return node.kind === SyntaxKind.JSDocReadonlyTag; - } - - export function isJSDocEnumTag(node: Node): node is JSDocEnumTag { - return node.kind === SyntaxKind.JSDocEnumTag; - } - - export function isJSDocThisTag(node: Node): node is JSDocThisTag { - return node.kind === SyntaxKind.JSDocThisTag; - } - - export function isJSDocParameterTag(node: Node): node is JSDocParameterTag { - return node.kind === SyntaxKind.JSDocParameterTag; - } - - export function isJSDocReturnTag(node: Node): node is JSDocReturnTag { - return node.kind === SyntaxKind.JSDocReturnTag; - } - - export function isJSDocTypeTag(node: Node): node is JSDocTypeTag { - return node.kind === SyntaxKind.JSDocTypeTag; - } - - export function isJSDocTemplateTag(node: Node): node is JSDocTemplateTag { - return node.kind === SyntaxKind.JSDocTemplateTag; - } - - export function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag { - return node.kind === SyntaxKind.JSDocTypedefTag; - } - - export function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag { - return node.kind === SyntaxKind.JSDocPropertyTag; - } - export function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag { return node.kind === SyntaxKind.JSDocPropertyTag || node.kind === SyntaxKind.JSDocParameterTag; } - export function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral { - return node.kind === SyntaxKind.JSDocTypeLiteral; - } - - export function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag { - return node.kind === SyntaxKind.JSDocCallbackTag; - } - - export function isJSDocSignature(node: Node): node is JSDocSignature { - return node.kind === SyntaxKind.JSDocSignature; - } - // #endregion // #region @@ -1724,11 +1004,6 @@ namespace ts { // // All node tests in the following list should *not* reference parent pointers so that // they may be used with transformations. - /* @internal */ - export function isSyntaxList(n: Node): n is SyntaxList { - return n.kind === SyntaxKind.SyntaxList; - } - /* @internal */ export function isNode(node: Node) { return isNodeKind(node.kind); @@ -1758,7 +1033,7 @@ namespace ts { // Literals /* @internal */ - export function isLiteralKind(kind: SyntaxKind): boolean { + export function isLiteralKind(kind: SyntaxKind): kind is LiteralToken["kind"] { return SyntaxKind.FirstLiteralToken <= kind && kind <= SyntaxKind.LastLiteralToken; } @@ -1769,11 +1044,10 @@ namespace ts { // Pseudo-literals /* @internal */ - export function isTemplateLiteralKind(kind: SyntaxKind): boolean { + export function isTemplateLiteralKind(kind: SyntaxKind): kind is TemplateLiteralToken["kind"] { return SyntaxKind.FirstTemplateToken <= kind && kind <= SyntaxKind.LastTemplateToken; } - export type TemplateLiteralToken = NoSubstitutionTemplateLiteral | TemplateHead | TemplateMiddle | TemplateTail; export function isTemplateLiteralToken(node: Node): node is TemplateLiteralToken { return isTemplateLiteralKind(node.kind); } @@ -2234,21 +1508,6 @@ namespace ts { || kind === SyntaxKind.AsExpression; } - /* @internal */ - export function isPartiallyEmittedExpression(node: Node): node is PartiallyEmittedExpression { - return node.kind === SyntaxKind.PartiallyEmittedExpression; - } - - /* @internal */ - export function isNotEmittedStatement(node: Node): node is NotEmittedStatement { - return node.kind === SyntaxKind.NotEmittedStatement; - } - - /* @internal */ - export function isSyntheticReference(node: Node): node is SyntheticReferenceExpression { - return node.kind === SyntaxKind.SyntheticReferenceExpression; - } - /* @internal */ export function isNotEmittedOrPartiallyEmittedNode(node: Node): node is NotEmittedStatement | PartiallyEmittedExpression { return isNotEmittedStatement(node) @@ -2469,6 +1728,17 @@ namespace ts { return !isFunctionBlock(node); } + /** + * NOTE: This is similar to `isStatement` but does not access parent pointers. + */ + /* @internal */ + export function isStatementOrBlock(node: Node): node is Statement | Block { + const kind = node.kind; + return isStatementKindButNotDeclarationKind(kind) + || isDeclarationStatementKind(kind) + || kind === SyntaxKind.Block; + } + // Module references /* @internal */ diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts deleted file mode 100644 index f1144b3eb3530..0000000000000 --- a/src/compiler/visitor.ts +++ /dev/null @@ -1,706 +0,0 @@ -/* @internal */ -namespace ts { - function reduceNode(node: Node | undefined, f: (memo: T, node: Node) => T, initial: T) { - return node ? f(initial, node) : initial; - } - - function reduceNodeArray(nodes: NodeArray | undefined, f: (memo: T, nodes: NodeArray) => T, initial: T) { - return nodes ? f(initial, nodes) : initial; - } - - /** - * Similar to `reduceLeft`, performs a reduction against each child of a node. - * NOTE: Unlike `forEachChild`, this does *not* visit every node. - * - * @param node The node containing the children to reduce. - * @param initial The initial value to supply to the reduction. - * @param f The callback function - */ - export function reduceEachChild(node: Node | undefined, initial: T, cbNode: (memo: T, node: Node) => T, cbNodeArray?: (memo: T, nodes: NodeArray) => T): T { - if (node === undefined) { - return initial; - } - - const reduceNodes: (nodes: NodeArray | undefined, f: ((memo: T, node: Node) => T) | ((memo: T, node: NodeArray) => T), initial: T) => T = cbNodeArray ? reduceNodeArray : reduceLeft; - const cbNodes = cbNodeArray || cbNode; - const kind = node.kind; - - // No need to visit nodes with no children. - if ((kind > SyntaxKind.FirstToken && kind <= SyntaxKind.LastToken)) { - return initial; - } - - // We do not yet support types. - if ((kind >= SyntaxKind.TypePredicate && kind <= SyntaxKind.LiteralType)) { - return initial; - } - - let result = initial; - switch (node.kind) { - // Leaf nodes - case SyntaxKind.SemicolonClassElement: - case SyntaxKind.EmptyStatement: - case SyntaxKind.OmittedExpression: - case SyntaxKind.DebuggerStatement: - case SyntaxKind.NotEmittedStatement: - // No need to visit nodes with no children. - break; - - // Names - case SyntaxKind.QualifiedName: - result = reduceNode((node).left, cbNode, result); - result = reduceNode((node).right, cbNode, result); - break; - - case SyntaxKind.ComputedPropertyName: - result = reduceNode((node).expression, cbNode, result); - break; - - // Signature elements - case SyntaxKind.Parameter: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).initializer, cbNode, result); - break; - - case SyntaxKind.Decorator: - result = reduceNode((node).expression, cbNode, result); - break; - - // Type member - case SyntaxKind.PropertySignature: - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).questionToken, cbNode, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).initializer, cbNode, result); - break; - - case SyntaxKind.PropertyDeclaration: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).initializer, cbNode, result); - break; - - case SyntaxKind.MethodDeclaration: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNodes((node).typeParameters, cbNodes, result); - result = reduceNodes((node).parameters, cbNodes, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).body, cbNode, result); - break; - - case SyntaxKind.Constructor: - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNodes((node).parameters, cbNodes, result); - result = reduceNode((node).body, cbNode, result); - break; - - case SyntaxKind.GetAccessor: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNodes((node).parameters, cbNodes, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).body, cbNode, result); - break; - - case SyntaxKind.SetAccessor: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNodes((node).parameters, cbNodes, result); - result = reduceNode((node).body, cbNode, result); - break; - - // Binding patterns - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - result = reduceNodes((node).elements, cbNodes, result); - break; - - case SyntaxKind.BindingElement: - result = reduceNode((node).propertyName, cbNode, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).initializer, cbNode, result); - break; - - // Expression - case SyntaxKind.ArrayLiteralExpression: - result = reduceNodes((node).elements, cbNodes, result); - break; - - case SyntaxKind.ObjectLiteralExpression: - result = reduceNodes((node).properties, cbNodes, result); - break; - - case SyntaxKind.PropertyAccessExpression: - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).name, cbNode, result); - break; - - case SyntaxKind.ElementAccessExpression: - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).argumentExpression, cbNode, result); - break; - - case SyntaxKind.CallExpression: - result = reduceNode((node).expression, cbNode, result); - result = reduceNodes((node).typeArguments, cbNodes, result); - result = reduceNodes((node).arguments, cbNodes, result); - break; - - case SyntaxKind.NewExpression: - result = reduceNode((node).expression, cbNode, result); - result = reduceNodes((node).typeArguments, cbNodes, result); - result = reduceNodes((node).arguments, cbNodes, result); - break; - - case SyntaxKind.TaggedTemplateExpression: - result = reduceNode((node).tag, cbNode, result); - result = reduceNodes((node).typeArguments, cbNodes, result); - result = reduceNode((node).template, cbNode, result); - break; - - case SyntaxKind.TypeAssertionExpression: - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).expression, cbNode, result); - break; - - case SyntaxKind.FunctionExpression: - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNodes((node).typeParameters, cbNodes, result); - result = reduceNodes((node).parameters, cbNodes, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).body, cbNode, result); - break; - - case SyntaxKind.ArrowFunction: - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNodes((node).typeParameters, cbNodes, result); - result = reduceNodes((node).parameters, cbNodes, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).body, cbNode, result); - break; - - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.DeleteExpression: - case SyntaxKind.TypeOfExpression: - case SyntaxKind.VoidExpression: - case SyntaxKind.AwaitExpression: - case SyntaxKind.YieldExpression: - case SyntaxKind.SpreadElement: - case SyntaxKind.NonNullExpression: - result = reduceNode((node).expression, cbNode, result); - break; - - case SyntaxKind.PrefixUnaryExpression: - case SyntaxKind.PostfixUnaryExpression: - result = reduceNode((node).operand, cbNode, result); - break; - - case SyntaxKind.BinaryExpression: - result = reduceNode((node).left, cbNode, result); - result = reduceNode((node).right, cbNode, result); - break; - - case SyntaxKind.ConditionalExpression: - result = reduceNode((node).condition, cbNode, result); - result = reduceNode((node).whenTrue, cbNode, result); - result = reduceNode((node).whenFalse, cbNode, result); - break; - - case SyntaxKind.TemplateExpression: - result = reduceNode((node).head, cbNode, result); - result = reduceNodes((node).templateSpans, cbNodes, result); - break; - - case SyntaxKind.ClassExpression: - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNodes((node).typeParameters, cbNodes, result); - result = reduceNodes((node).heritageClauses, cbNodes, result); - result = reduceNodes((node).members, cbNodes, result); - break; - - case SyntaxKind.ExpressionWithTypeArguments: - result = reduceNode((node).expression, cbNode, result); - result = reduceNodes((node).typeArguments, cbNodes, result); - break; - - case SyntaxKind.AsExpression: - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).type, cbNode, result); - break; - - // Misc - case SyntaxKind.TemplateSpan: - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).literal, cbNode, result); - break; - - // Element - case SyntaxKind.Block: - result = reduceNodes((node).statements, cbNodes, result); - break; - - case SyntaxKind.VariableStatement: - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).declarationList, cbNode, result); - break; - - case SyntaxKind.ExpressionStatement: - result = reduceNode((node).expression, cbNode, result); - break; - - case SyntaxKind.IfStatement: - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).thenStatement, cbNode, result); - result = reduceNode((node).elseStatement, cbNode, result); - break; - - case SyntaxKind.DoStatement: - result = reduceNode((node).statement, cbNode, result); - result = reduceNode((node).expression, cbNode, result); - break; - - case SyntaxKind.WhileStatement: - case SyntaxKind.WithStatement: - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).statement, cbNode, result); - break; - - case SyntaxKind.ForStatement: - result = reduceNode((node).initializer, cbNode, result); - result = reduceNode((node).condition, cbNode, result); - result = reduceNode((node).incrementor, cbNode, result); - result = reduceNode((node).statement, cbNode, result); - break; - - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - result = reduceNode((node).initializer, cbNode, result); - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).statement, cbNode, result); - break; - - case SyntaxKind.ReturnStatement: - case SyntaxKind.ThrowStatement: - result = reduceNode((node).expression, cbNode, result); - break; - - case SyntaxKind.SwitchStatement: - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).caseBlock, cbNode, result); - break; - - case SyntaxKind.LabeledStatement: - result = reduceNode((node).label, cbNode, result); - result = reduceNode((node).statement, cbNode, result); - break; - - case SyntaxKind.TryStatement: - result = reduceNode((node).tryBlock, cbNode, result); - result = reduceNode((node).catchClause, cbNode, result); - result = reduceNode((node).finallyBlock, cbNode, result); - break; - - case SyntaxKind.VariableDeclaration: - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).initializer, cbNode, result); - break; - - case SyntaxKind.VariableDeclarationList: - result = reduceNodes((node).declarations, cbNodes, result); - break; - - case SyntaxKind.FunctionDeclaration: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNodes((node).typeParameters, cbNodes, result); - result = reduceNodes((node).parameters, cbNodes, result); - result = reduceNode((node).type, cbNode, result); - result = reduceNode((node).body, cbNode, result); - break; - - case SyntaxKind.ClassDeclaration: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNodes((node).typeParameters, cbNodes, result); - result = reduceNodes((node).heritageClauses, cbNodes, result); - result = reduceNodes((node).members, cbNodes, result); - break; - - case SyntaxKind.EnumDeclaration: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNodes((node).members, cbNodes, result); - break; - - case SyntaxKind.ModuleDeclaration: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).body, cbNode, result); - break; - - case SyntaxKind.ModuleBlock: - result = reduceNodes((node).statements, cbNodes, result); - break; - - case SyntaxKind.CaseBlock: - result = reduceNodes((node).clauses, cbNodes, result); - break; - - case SyntaxKind.ImportEqualsDeclaration: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).moduleReference, cbNode, result); - break; - - case SyntaxKind.ImportDeclaration: - result = reduceNodes((node).decorators, cbNodes, result); - result = reduceNodes((node).modifiers, cbNodes, result); - result = reduceNode((node).importClause, cbNode, result); - result = reduceNode((node).moduleSpecifier, cbNode, result); - break; - - case SyntaxKind.ImportClause: - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).namedBindings, cbNode, result); - break; - - case SyntaxKind.NamespaceImport: - result = reduceNode((node).name, cbNode, result); - break; - - case SyntaxKind.NamespaceExport: - result = reduceNode((node).name, cbNode, result); - break; - - case SyntaxKind.NamedImports: - case SyntaxKind.NamedExports: - result = reduceNodes((node).elements, cbNodes, result); - break; - - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - result = reduceNode((node).propertyName, cbNode, result); - result = reduceNode((node).name, cbNode, result); - break; - - case SyntaxKind.ExportAssignment: - result = reduceLeft((node).decorators, cbNode, result); - result = reduceLeft((node).modifiers, cbNode, result); - result = reduceNode((node).expression, cbNode, result); - break; - - case SyntaxKind.ExportDeclaration: - result = reduceLeft((node).decorators, cbNode, result); - result = reduceLeft((node).modifiers, cbNode, result); - result = reduceNode((node).exportClause, cbNode, result); - result = reduceNode((node).moduleSpecifier, cbNode, result); - break; - - // Module references - case SyntaxKind.ExternalModuleReference: - result = reduceNode((node).expression, cbNode, result); - break; - - // JSX - case SyntaxKind.JsxElement: - result = reduceNode((node).openingElement, cbNode, result); - result = reduceLeft((node).children, cbNode, result); - result = reduceNode((node).closingElement, cbNode, result); - break; - - case SyntaxKind.JsxFragment: - result = reduceNode((node).openingFragment, cbNode, result); - result = reduceLeft((node).children, cbNode, result); - result = reduceNode((node).closingFragment, cbNode, result); - break; - - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxOpeningElement: - result = reduceNode((node).tagName, cbNode, result); - result = reduceNodes((node).typeArguments, cbNode, result); - result = reduceNode((node).attributes, cbNode, result); - break; - - case SyntaxKind.JsxAttributes: - result = reduceNodes((node).properties, cbNodes, result); - break; - - case SyntaxKind.JsxClosingElement: - result = reduceNode((node).tagName, cbNode, result); - break; - - case SyntaxKind.JsxAttribute: - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).initializer, cbNode, result); - break; - - case SyntaxKind.JsxSpreadAttribute: - result = reduceNode((node).expression, cbNode, result); - break; - - case SyntaxKind.JsxExpression: - result = reduceNode((node).expression, cbNode, result); - break; - - // Clauses - case SyntaxKind.CaseClause: - result = reduceNode((node).expression, cbNode, result); - // falls through - - case SyntaxKind.DefaultClause: - result = reduceNodes((node).statements, cbNodes, result); - break; - - case SyntaxKind.HeritageClause: - result = reduceNodes((node).types, cbNodes, result); - break; - - case SyntaxKind.CatchClause: - result = reduceNode((node).variableDeclaration, cbNode, result); - result = reduceNode((node).block, cbNode, result); - break; - - // Property assignments - case SyntaxKind.PropertyAssignment: - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).initializer, cbNode, result); - break; - - case SyntaxKind.ShorthandPropertyAssignment: - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).objectAssignmentInitializer, cbNode, result); - break; - - case SyntaxKind.SpreadAssignment: - result = reduceNode((node).expression, cbNode, result); - break; - - // Enum - case SyntaxKind.EnumMember: - result = reduceNode((node).name, cbNode, result); - result = reduceNode((node).initializer, cbNode, result); - break; - - // Top-level nodes - case SyntaxKind.SourceFile: - result = reduceNodes((node).statements, cbNodes, result); - break; - - // Transformation nodes - case SyntaxKind.PartiallyEmittedExpression: - result = reduceNode((node).expression, cbNode, result); - break; - - case SyntaxKind.CommaListExpression: - result = reduceNodes((node).elements, cbNodes, result); - break; - - default: - break; - } - - return result; - } - - function findSpanEnd(array: readonly T[], test: (value: T) => boolean, start: number) { - let i = start; - while (i < array.length && test(array[i])) { - i++; - } - return i; - } - - /** - * Merges generated lexical declarations into a new statement list. - */ - export function mergeLexicalEnvironment(statements: NodeArray, declarations: readonly Statement[] | undefined): NodeArray; - /** - * Appends generated lexical declarations to an array of statements. - */ - export function mergeLexicalEnvironment(statements: Statement[], declarations: readonly Statement[] | undefined): Statement[]; - export function mergeLexicalEnvironment(statements: Statement[] | NodeArray, declarations: readonly Statement[] | undefined) { - if (!some(declarations)) { - return statements; - } - - // When we merge new lexical statements into an existing statement list, we merge them in the following manner: - // - // Given: - // - // | Left | Right | - // |------------------------------------|-------------------------------------| - // | [standard prologues (left)] | [standard prologues (right)] | - // | [hoisted functions (left)] | [hoisted functions (right)] | - // | [hoisted variables (left)] | [hoisted variables (right)] | - // | [lexical init statements (left)] | [lexical init statements (right)] | - // | [other statements (left)] | | - // - // The resulting statement list will be: - // - // | Result | - // |-------------------------------------| - // | [standard prologues (right)] | - // | [standard prologues (left)] | - // | [hoisted functions (right)] | - // | [hoisted functions (left)] | - // | [hoisted variables (right)] | - // | [hoisted variables (left)] | - // | [lexical init statements (right)] | - // | [lexical init statements (left)] | - // | [other statements (left)] | - // - // NOTE: It is expected that new lexical init statements must be evaluated before existing lexical init statements, - // as the prior transformation may depend on the evaluation of the lexical init statements to be in the correct state. - - // find standard prologues on left in the following order: standard directives, hoisted functions, hoisted variables, other custom - const leftStandardPrologueEnd = findSpanEnd(statements, isPrologueDirective, 0); - const leftHoistedFunctionsEnd = findSpanEnd(statements, isHoistedFunction, leftStandardPrologueEnd); - const leftHoistedVariablesEnd = findSpanEnd(statements, isHoistedVariableStatement, leftHoistedFunctionsEnd); - - // find standard prologues on right in the following order: standard directives, hoisted functions, hoisted variables, other custom - const rightStandardPrologueEnd = findSpanEnd(declarations, isPrologueDirective, 0); - const rightHoistedFunctionsEnd = findSpanEnd(declarations, isHoistedFunction, rightStandardPrologueEnd); - const rightHoistedVariablesEnd = findSpanEnd(declarations, isHoistedVariableStatement, rightHoistedFunctionsEnd); - const rightCustomPrologueEnd = findSpanEnd(declarations, isCustomPrologue, rightHoistedVariablesEnd); - Debug.assert(rightCustomPrologueEnd === declarations.length, "Expected declarations to be valid standard or custom prologues"); - - // splice prologues from the right into the left. We do this in reverse order - // so that we don't need to recompute the index on the left when we insert items. - const left = isNodeArray(statements) ? statements.slice() : statements; - - // splice other custom prologues from right into left - if (rightCustomPrologueEnd > rightHoistedVariablesEnd) { - left.splice(leftHoistedVariablesEnd, 0, ...declarations.slice(rightHoistedVariablesEnd, rightCustomPrologueEnd)); - } - - // splice hoisted variables from right into left - if (rightHoistedVariablesEnd > rightHoistedFunctionsEnd) { - left.splice(leftHoistedFunctionsEnd, 0, ...declarations.slice(rightHoistedFunctionsEnd, rightHoistedVariablesEnd)); - } - - // splice hoisted functions from right into left - if (rightHoistedFunctionsEnd > rightStandardPrologueEnd) { - left.splice(leftStandardPrologueEnd, 0, ...declarations.slice(rightStandardPrologueEnd, rightHoistedFunctionsEnd)); - } - - // splice standard prologues from right into left (that are not already in left) - if (rightStandardPrologueEnd > 0) { - if (leftStandardPrologueEnd === 0) { - left.splice(0, 0, ...declarations.slice(0, rightStandardPrologueEnd)); - } - else { - const leftPrologues = createMap(); - for (let i = 0; i < leftStandardPrologueEnd; i++) { - const leftPrologue = statements[i] as PrologueDirective; - leftPrologues.set(leftPrologue.expression.text, true); - } - for (let i = rightStandardPrologueEnd - 1; i >= 0; i--) { - const rightPrologue = declarations[i] as PrologueDirective; - if (!leftPrologues.has(rightPrologue.expression.text)) { - left.unshift(rightPrologue); - } - } - } - } - - if (isNodeArray(statements)) { - return setTextRange(createNodeArray(left, statements.hasTrailingComma), statements); - } - - return statements; - } - - /** - * Lifts a NodeArray containing only Statement nodes to a block. - * - * @param nodes The NodeArray. - */ - export function liftToBlock(nodes: readonly Node[]): Statement { - Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block."); - return singleOrUndefined(nodes) || createBlock(>nodes); - } - - /** - * Aggregates the TransformFlags for a Node and its subtree. - */ - export function aggregateTransformFlags(node: T): T { - aggregateTransformFlagsForNode(node); - return node; - } - - /** - * Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are - * computed first, then the transform flags for the current node are computed from the subtree - * flags and the state of the current node. Finally, the transform flags of the node are - * returned, excluding any flags that should not be included in its parent node's subtree - * flags. - */ - function aggregateTransformFlagsForNode(node: Node): TransformFlags { - if (node === undefined) { - return TransformFlags.None; - } - if (node.transformFlags & TransformFlags.HasComputedFlags) { - return node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind); - } - const subtreeFlags = aggregateTransformFlagsForSubtree(node); - return computeTransformFlagsForNode(node, subtreeFlags); - } - - function aggregateTransformFlagsForNodeArray(nodes: NodeArray): TransformFlags { - if (nodes === undefined) { - return TransformFlags.None; - } - let subtreeFlags = TransformFlags.None; - let nodeArrayFlags = TransformFlags.None; - for (const node of nodes) { - subtreeFlags |= aggregateTransformFlagsForNode(node); - nodeArrayFlags |= node.transformFlags & ~TransformFlags.HasComputedFlags; - } - nodes.transformFlags = nodeArrayFlags | TransformFlags.HasComputedFlags; - return subtreeFlags; - } - - /** - * Aggregates the transform flags for the subtree of a node. - */ - function aggregateTransformFlagsForSubtree(node: Node): TransformFlags { - // We do not transform ambient declarations or types, so there is no need to - // recursively aggregate transform flags. - if (hasSyntacticModifier(node, ModifierFlags.Ambient) || (isTypeNode(node) && node.kind !== SyntaxKind.ExpressionWithTypeArguments)) { - return TransformFlags.None; - } - - // Aggregate the transform flags of each child. - return reduceEachChild(node, TransformFlags.None, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes); - } - - /** - * Aggregates the TransformFlags of a child node with the TransformFlags of its - * siblings. - */ - function aggregateTransformFlagsForChildNode(transformFlags: TransformFlags, node: Node): TransformFlags { - return transformFlags | aggregateTransformFlagsForNode(node); - } - - function aggregateTransformFlagsForChildNodes(transformFlags: TransformFlags, nodes: NodeArray): TransformFlags { - return transformFlags | aggregateTransformFlagsForNodeArray(nodes); - } -} diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 544be6d6b4dd3..86651c8e433d0 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -9,7 +9,7 @@ namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - export function visitNode(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; + export function visitNode(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. @@ -26,7 +26,6 @@ namespace ts { return node; } - aggregateTransformFlags(node); const visited = visitor(node); if (visited === node) { return node; @@ -44,7 +43,6 @@ namespace ts { } Debug.assertNode(visitedNode, test); - aggregateTransformFlags(visitedNode!); return visitedNode; } @@ -57,7 +55,7 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; + export function visitNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. @@ -68,7 +66,7 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. @@ -79,12 +77,12 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined { + export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined { if (nodes === undefined || visitor === undefined) { return nodes; } - let updated: MutableNodeArray | undefined; + let updated: T[] | undefined; // Ensure start and count have valid values const length = nodes.length; @@ -96,61 +94,71 @@ namespace ts { count = length - start; } + let hasTrailingComma: boolean | undefined; + let pos = -1; + let end = -1; if (start > 0 || count < length) { // If we are not visiting all of the original nodes, we must always create a new array. // Since this is a fragment of a node array, we do not copy over the previous location // and will only copy over `hasTrailingComma` if we are including the last element. - updated = createNodeArray([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length); + updated = []; + hasTrailingComma = nodes.hasTrailingComma && start + count === length; } // Visit each original node. for (let i = 0; i < count; i++) { const node: T = nodes[i + start]; - aggregateTransformFlags(node); const visited = node !== undefined ? visitor(node) : undefined; if (updated !== undefined || visited === undefined || visited !== node) { if (updated === undefined) { // Ensure we have a copy of `nodes`, up to the current index. - updated = createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma); - setTextRange(updated, nodes); + updated = nodes.slice(0, i); + hasTrailingComma = nodes.hasTrailingComma; + pos = nodes.pos; + end = nodes.end; } if (visited) { if (isArray(visited)) { for (const visitedNode of visited) { - Debug.assertNode(visitedNode, test); - aggregateTransformFlags(visitedNode); + void Debug.assertNode(visitedNode, test); updated.push(visitedNode); } } else { - Debug.assertNode(visited, test); - aggregateTransformFlags(visited); + void Debug.assertNode(visited, test); updated.push(visited); } } } } - return updated || nodes; + if (updated) { + // TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory. + const updatedArray = factory.createNodeArray(updated, hasTrailingComma); + setTextRangePosEnd(updatedArray, pos, end); + return updatedArray; + } + + return nodes; } /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean) { + export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { context.startLexicalEnvironment(); - statements = visitNodes(statements, visitor, isStatement, start); - if (ensureUseStrict) statements = ts.ensureUseStrict(statements); // eslint-disable-line @typescript-eslint/no-unnecessary-qualifier - return mergeLexicalEnvironment(statements, context.endLexicalEnvironment()); + statements = nodesVisitor(statements, visitor, isStatement, start); + if (ensureUseStrict) statements = context.factory.ensureUseStrict(statements); + return factory.mergeLexicalEnvironment(statements, context.endLexicalEnvironment()); } /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray): NodeArray; - export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray | undefined): NodeArray | undefined; + export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { let updated: NodeArray | undefined; context.startLexicalEnvironment(); @@ -185,7 +193,7 @@ namespace ts { } } if (result) { - return setTextRange(createNodeArray(result, parameters.hasTrailingComma), parameters); + return setTextRange(context.factory.createNodeArray(result, parameters.hasTrailingComma), parameters); } return parameters; } @@ -200,49 +208,54 @@ namespace ts { } function addDefaultValueAssignmentForBindingPattern(parameter: ParameterDeclaration, context: TransformationContext) { + const { factory } = context; context.addInitializationStatement( - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( parameter.name, + /*exclamationToken*/ undefined, parameter.type, parameter.initializer ? - createConditional( - createStrictEquality( - getGeneratedNameForNode(parameter), - createVoidZero() + factory.createConditionalExpression( + factory.createStrictEquality( + factory.getGeneratedNameForNode(parameter), + factory.createVoidZero() ), + /*questionToken*/ undefined, parameter.initializer, - getGeneratedNameForNode(parameter) + /*colonToken*/ undefined, + factory.getGeneratedNameForNode(parameter) ) : - getGeneratedNameForNode(parameter) + factory.getGeneratedNameForNode(parameter) ), ]) ) ); - return updateParameter(parameter, + return factory.updateParameterDeclaration(parameter, parameter.decorators, parameter.modifiers, parameter.dotDotDotToken, - getGeneratedNameForNode(parameter), + factory.getGeneratedNameForNode(parameter), parameter.questionToken, parameter.type, /*initializer*/ undefined); } function addDefaultValueAssignmentForInitializer(parameter: ParameterDeclaration, name: Identifier, initializer: Expression, context: TransformationContext) { + const factory = context.factory; context.addInitializationStatement( - createIf( - createTypeCheck(getSynthesizedClone(name), "undefined"), + factory.createIfStatement( + factory.createTypeCheck(factory.cloneNode(name), "undefined"), setEmitFlags( setTextRange( - createBlock([ - createExpressionStatement( + factory.createBlock([ + factory.createExpressionStatement( setEmitFlags( setTextRange( - createAssignment( - setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap), + factory.createAssignment( + setEmitFlags(factory.cloneNode(name), EmitFlags.NoSourceMap), setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer) | EmitFlags.NoComments) ), parameter @@ -257,7 +270,7 @@ namespace ts { ) ) ); - return updateParameter(parameter, + return factory.updateParameterDeclaration(parameter, parameter.decorators, parameter.modifiers, parameter.dotDotDotToken, @@ -282,14 +295,20 @@ namespace ts { * environment and merging hoisted declarations upon completion. */ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; - export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext): ConciseBody | undefined { + /* @internal*/ export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal*/ export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal*/ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): ConciseBody; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): ConciseBody | undefined { context.resumeLexicalEnvironment(); - const updated = visitNode(node, visitor, isConciseBody); + const updated = nodeVisitor(node, visitor, isConciseBody); const declarations = context.endLexicalEnvironment(); if (some(declarations)) { - const block = convertToFunctionBody(updated); - const statements = mergeLexicalEnvironment(block.statements, declarations); - return updateBlock(block, statements); + if (!updated) { + return context.factory.createBlock(declarations); + } + const block = context.factory.converters.convertToFunctionBlock(updated); + const statements = factory.mergeLexicalEnvironment(block.statements, declarations); + return context.factory.updateBlock(block, statements); } return updated; } @@ -302,7 +321,6 @@ namespace ts { * @param context A lexical environment context for the visitor. */ export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; - /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -311,8 +329,9 @@ namespace ts { * @param context A lexical environment context for the visitor. */ export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; - - export function visitEachChild(node: Node | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor): Node | undefined { + /* @internal */ + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitEachChild(node: Node | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): Node | undefined { if (node === undefined) { return undefined; } @@ -324,201 +343,203 @@ namespace ts { return node; } + const factory = context.factory; switch (kind) { // Names case SyntaxKind.Identifier: - return updateIdentifier(node, nodesVisitor((node).typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration)); + return factory.updateIdentifier(node, + nodesVisitor((node).typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration)); case SyntaxKind.QualifiedName: - return updateQualifiedName(node, - visitNode((node).left, visitor, isEntityName), - visitNode((node).right, visitor, isIdentifier)); + return factory.updateQualifiedName(node, + nodeVisitor((node).left, visitor, isEntityName), + nodeVisitor((node).right, visitor, isIdentifier)); case SyntaxKind.ComputedPropertyName: - return updateComputedPropertyName(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateComputedPropertyName(node, + nodeVisitor((node).expression, visitor, isExpression)); // Signature elements case SyntaxKind.TypeParameter: - return updateTypeParameterDeclaration(node, - visitNode((node).name, visitor, isIdentifier), - visitNode((node).constraint, visitor, isTypeNode), - visitNode((node).default, visitor, isTypeNode)); + return factory.updateTypeParameterDeclaration(node, + nodeVisitor((node).name, visitor, isIdentifier), + nodeVisitor((node).constraint, visitor, isTypeNode), + nodeVisitor((node).default, visitor, isTypeNode)); case SyntaxKind.Parameter: - return updateParameter(node, + return factory.updateParameterDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).dotDotDotToken, tokenVisitor, isToken), - visitNode((node).name, visitor, isBindingName), - visitNode((node).questionToken, tokenVisitor, isToken), - visitNode((node).type, visitor, isTypeNode), - visitNode((node).initializer, visitor, isExpression)); + nodeVisitor((node).dotDotDotToken, tokenVisitor, isToken), + nodeVisitor((node).name, visitor, isBindingName), + nodeVisitor((node).questionToken, tokenVisitor, isToken), + nodeVisitor((node).type, visitor, isTypeNode), + nodeVisitor((node).initializer, visitor, isExpression)); case SyntaxKind.Decorator: - return updateDecorator(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateDecorator(node, + nodeVisitor((node).expression, visitor, isExpression)); // Type elements case SyntaxKind.PropertySignature: - return updatePropertySignature((node), + return factory.updatePropertySignature((node), nodesVisitor((node).modifiers, visitor, isToken), - visitNode((node).name, visitor, isPropertyName), - visitNode((node).questionToken, tokenVisitor, isToken), - visitNode((node).type, visitor, isTypeNode), - visitNode((node).initializer, visitor, isExpression)); + nodeVisitor((node).name, visitor, isPropertyName), + nodeVisitor((node).questionToken, tokenVisitor, isToken), + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.PropertyDeclaration: - return updateProperty(node, + return factory.updatePropertyDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isPropertyName), + nodeVisitor((node).name, visitor, isPropertyName), // QuestionToken and ExclamationToken is uniqued in Property Declaration and the signature of 'updateProperty' is that too - visitNode((node).questionToken || (node).exclamationToken, tokenVisitor, isToken), - visitNode((node).type, visitor, isTypeNode), - visitNode((node).initializer, visitor, isExpression)); + nodeVisitor((node).questionToken || (node).exclamationToken, tokenVisitor, isToken), + nodeVisitor((node).type, visitor, isTypeNode), + nodeVisitor((node).initializer, visitor, isExpression)); case SyntaxKind.MethodSignature: - return updateMethodSignature(node, + return factory.updateMethodSignature(node, + nodesVisitor((node).modifiers, visitor, isModifier), + nodeVisitor((node).name, visitor, isPropertyName), + nodeVisitor((node).questionToken, tokenVisitor, isToken), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode), - visitNode((node).name, visitor, isPropertyName), - visitNode((node).questionToken, tokenVisitor, isToken)); + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.MethodDeclaration: - return updateMethod(node, + return factory.updateMethodDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).asteriskToken, tokenVisitor, isToken), - visitNode((node).name, visitor, isPropertyName), - visitNode((node).questionToken, tokenVisitor, isToken), + nodeVisitor((node).asteriskToken, tokenVisitor, isToken), + nodeVisitor((node).name, visitor, isPropertyName), + nodeVisitor((node).questionToken, tokenVisitor, isToken), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode), - visitFunctionBody((node).body!, visitor, context)); + nodeVisitor((node).type, visitor, isTypeNode), + visitFunctionBody((node).body!, visitor, context, nodeVisitor)); case SyntaxKind.Constructor: - return updateConstructor(node, + return factory.updateConstructorDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitFunctionBody((node).body!, visitor, context)); + visitFunctionBody((node).body!, visitor, context, nodeVisitor)); case SyntaxKind.GetAccessor: - return updateGetAccessor(node, + return factory.updateGetAccessorDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isPropertyName), + nodeVisitor((node).name, visitor, isPropertyName), visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode), - visitFunctionBody((node).body!, visitor, context)); + nodeVisitor((node).type, visitor, isTypeNode), + visitFunctionBody((node).body!, visitor, context, nodeVisitor)); case SyntaxKind.SetAccessor: - return updateSetAccessor(node, + return factory.updateSetAccessorDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isPropertyName), + nodeVisitor((node).name, visitor, isPropertyName), visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitFunctionBody((node).body!, visitor, context)); + visitFunctionBody((node).body!, visitor, context, nodeVisitor)); case SyntaxKind.CallSignature: - return updateCallSignature(node, + return factory.updateCallSignature(node, nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.ConstructSignature: - return updateConstructSignature(node, + return factory.updateConstructSignature(node, nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.IndexSignature: - return updateIndexSignature(node, + return factory.updateIndexSignature(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); + nodeVisitor((node).type, visitor, isTypeNode)); // Types case SyntaxKind.TypePredicate: - return updateTypePredicateNodeWithModifier(node, - visitNode((node).assertsModifier, visitor), - visitNode((node).parameterName, visitor), - visitNode((node).type, visitor, isTypeNode)); + return factory.updateTypePredicateNode(node, + nodeVisitor((node).assertsModifier, visitor), + nodeVisitor((node).parameterName, visitor), + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.TypeReference: - return updateTypeReferenceNode(node, - visitNode((node).typeName, visitor, isEntityName), + return factory.updateTypeReferenceNode(node, + nodeVisitor((node).typeName, visitor, isEntityName), nodesVisitor((node).typeArguments, visitor, isTypeNode)); case SyntaxKind.FunctionType: - return updateFunctionTypeNode(node, + return factory.updateFunctionTypeNode(node, nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.ConstructorType: - return updateConstructorTypeNode(node, + return factory.updateConstructorTypeNode(node, nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.TypeQuery: - return updateTypeQueryNode((node), - visitNode((node).exprName, visitor, isEntityName)); + return factory.updateTypeQueryNode((node), + nodeVisitor((node).exprName, visitor, isEntityName)); case SyntaxKind.TypeLiteral: - return updateTypeLiteralNode((node), + return factory.updateTypeLiteralNode((node), nodesVisitor((node).members, visitor, isTypeElement)); case SyntaxKind.ArrayType: - return updateArrayTypeNode(node, - visitNode((node).elementType, visitor, isTypeNode)); + return factory.updateArrayTypeNode(node, + nodeVisitor((node).elementType, visitor, isTypeNode)); case SyntaxKind.TupleType: - return updateTupleTypeNode((node), + return factory.updateTupleTypeNode((node), nodesVisitor((node).elements, visitor, isTypeNode)); case SyntaxKind.OptionalType: - return updateOptionalTypeNode((node), - visitNode((node).type, visitor, isTypeNode)); + return factory.updateOptionalTypeNode((node), + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.RestType: - return updateRestTypeNode((node), - visitNode((node).type, visitor, isTypeNode)); + return factory.updateRestTypeNode((node), + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.UnionType: - return updateUnionTypeNode(node, + return factory.updateUnionTypeNode(node, nodesVisitor((node).types, visitor, isTypeNode)); case SyntaxKind.IntersectionType: - return updateIntersectionTypeNode(node, + return factory.updateIntersectionTypeNode(node, nodesVisitor((node).types, visitor, isTypeNode)); case SyntaxKind.ConditionalType: - return updateConditionalTypeNode(node, - visitNode((node).checkType, visitor, isTypeNode), - visitNode((node).extendsType, visitor, isTypeNode), - visitNode((node).trueType, visitor, isTypeNode), - visitNode((node).falseType, visitor, isTypeNode)); + return factory.updateConditionalTypeNode(node, + nodeVisitor((node).checkType, visitor, isTypeNode), + nodeVisitor((node).extendsType, visitor, isTypeNode), + nodeVisitor((node).trueType, visitor, isTypeNode), + nodeVisitor((node).falseType, visitor, isTypeNode)); case SyntaxKind.InferType: - return updateInferTypeNode(node, - visitNode((node).typeParameter, visitor, isTypeParameterDeclaration)); + return factory.updateInferTypeNode(node, + nodeVisitor((node).typeParameter, visitor, isTypeParameterDeclaration)); case SyntaxKind.ImportType: - return updateImportTypeNode(node, - visitNode((node).argument, visitor, isTypeNode), - visitNode((node).qualifier, visitor, isEntityName), + return factory.updateImportTypeNode(node, + nodeVisitor((node).argument, visitor, isTypeNode), + nodeVisitor((node).qualifier, visitor, isEntityName), visitNodes((node).typeArguments, visitor, isTypeNode), (node).isTypeOf ); case SyntaxKind.NamedTupleMember: - return updateNamedTupleMember(node, + return factory.updateNamedTupleMember(node, visitNode((node).dotDotDotToken, visitor, isToken), visitNode((node).name, visitor, isIdentifier), visitNode((node).questionToken, visitor, isToken), @@ -526,537 +547,542 @@ namespace ts { ); case SyntaxKind.ParenthesizedType: - return updateParenthesizedType(node, - visitNode((node).type, visitor, isTypeNode)); + return factory.updateParenthesizedType(node, + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.TypeOperator: - return updateTypeOperatorNode(node, - visitNode((node).type, visitor, isTypeNode)); + return factory.updateTypeOperatorNode(node, + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.IndexedAccessType: - return updateIndexedAccessTypeNode((node), - visitNode((node).objectType, visitor, isTypeNode), - visitNode((node).indexType, visitor, isTypeNode)); + return factory.updateIndexedAccessTypeNode((node), + nodeVisitor((node).objectType, visitor, isTypeNode), + nodeVisitor((node).indexType, visitor, isTypeNode)); case SyntaxKind.MappedType: - return updateMappedTypeNode((node), - visitNode((node).readonlyToken, tokenVisitor, isToken), - visitNode((node).typeParameter, visitor, isTypeParameterDeclaration), - visitNode((node).questionToken, tokenVisitor, isToken), - visitNode((node).type, visitor, isTypeNode)); + return factory.updateMappedTypeNode((node), + nodeVisitor((node).readonlyToken, tokenVisitor, isToken), + nodeVisitor((node).typeParameter, visitor, isTypeParameterDeclaration), + nodeVisitor((node).questionToken, tokenVisitor, isToken), + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.LiteralType: - return updateLiteralTypeNode(node, - visitNode((node).literal, visitor, isExpression)); + return factory.updateLiteralTypeNode(node, + nodeVisitor((node).literal, visitor, isExpression)); // Binding patterns case SyntaxKind.ObjectBindingPattern: - return updateObjectBindingPattern(node, + return factory.updateObjectBindingPattern(node, nodesVisitor((node).elements, visitor, isBindingElement)); case SyntaxKind.ArrayBindingPattern: - return updateArrayBindingPattern(node, + return factory.updateArrayBindingPattern(node, nodesVisitor((node).elements, visitor, isArrayBindingElement)); case SyntaxKind.BindingElement: - return updateBindingElement(node, - visitNode((node).dotDotDotToken, tokenVisitor, isToken), - visitNode((node).propertyName, visitor, isPropertyName), - visitNode((node).name, visitor, isBindingName), - visitNode((node).initializer, visitor, isExpression)); + return factory.updateBindingElement(node, + nodeVisitor((node).dotDotDotToken, tokenVisitor, isToken), + nodeVisitor((node).propertyName, visitor, isPropertyName), + nodeVisitor((node).name, visitor, isBindingName), + nodeVisitor((node).initializer, visitor, isExpression)); // Expression case SyntaxKind.ArrayLiteralExpression: - return updateArrayLiteral(node, + return factory.updateArrayLiteralExpression(node, nodesVisitor((node).elements, visitor, isExpression)); case SyntaxKind.ObjectLiteralExpression: - return updateObjectLiteral(node, + return factory.updateObjectLiteralExpression(node, nodesVisitor((node).properties, visitor, isObjectLiteralElementLike)); case SyntaxKind.PropertyAccessExpression: if (node.flags & NodeFlags.OptionalChain) { - return updatePropertyAccessChain(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).questionDotToken, tokenVisitor, isToken), - visitNode((node).name, visitor, isIdentifier)); + return factory.updatePropertyAccessChain(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).questionDotToken, tokenVisitor, isToken), + nodeVisitor((node).name, visitor, isIdentifier)); } - return updatePropertyAccess(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).name, visitor, isIdentifierOrPrivateIdentifier)); + return factory.updatePropertyAccessExpression(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).name, visitor, isIdentifierOrPrivateIdentifier)); case SyntaxKind.ElementAccessExpression: if (node.flags & NodeFlags.OptionalChain) { - return updateElementAccessChain(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).questionDotToken, tokenVisitor, isToken), - visitNode((node).argumentExpression, visitor, isExpression)); + return factory.updateElementAccessChain(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).questionDotToken, tokenVisitor, isToken), + nodeVisitor((node).argumentExpression, visitor, isExpression)); } - return updateElementAccess(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).argumentExpression, visitor, isExpression)); + return factory.updateElementAccessExpression(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).argumentExpression, visitor, isExpression)); case SyntaxKind.CallExpression: if (node.flags & NodeFlags.OptionalChain) { - return updateCallChain(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).questionDotToken, tokenVisitor, isToken), + return factory.updateCallChain(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).questionDotToken, tokenVisitor, isToken), nodesVisitor((node).typeArguments, visitor, isTypeNode), nodesVisitor((node).arguments, visitor, isExpression)); } - return updateCall(node, - visitNode((node).expression, visitor, isExpression), + return factory.updateCallExpression(node, + nodeVisitor((node).expression, visitor, isExpression), nodesVisitor((node).typeArguments, visitor, isTypeNode), nodesVisitor((node).arguments, visitor, isExpression)); case SyntaxKind.NewExpression: - return updateNew(node, - visitNode((node).expression, visitor, isExpression), + return factory.updateNewExpression(node, + nodeVisitor((node).expression, visitor, isExpression), nodesVisitor((node).typeArguments, visitor, isTypeNode), nodesVisitor((node).arguments, visitor, isExpression)); case SyntaxKind.TaggedTemplateExpression: - return updateTaggedTemplate(node, - visitNode((node).tag, visitor, isExpression), + return factory.updateTaggedTemplateExpression(node, + nodeVisitor((node).tag, visitor, isExpression), visitNodes((node).typeArguments, visitor, isExpression), - visitNode((node).template, visitor, isTemplateLiteral)); + nodeVisitor((node).template, visitor, isTemplateLiteral)); case SyntaxKind.TypeAssertionExpression: - return updateTypeAssertion(node, - visitNode((node).type, visitor, isTypeNode), - visitNode((node).expression, visitor, isExpression)); + return factory.updateTypeAssertion(node, + nodeVisitor((node).type, visitor, isTypeNode), + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.ParenthesizedExpression: - return updateParen(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateParenthesizedExpression(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.FunctionExpression: - return updateFunctionExpression(node, + return factory.updateFunctionExpression(node, nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).asteriskToken, tokenVisitor, isToken), - visitNode((node).name, visitor, isIdentifier), + nodeVisitor((node).asteriskToken, tokenVisitor, isToken), + nodeVisitor((node).name, visitor, isIdentifier), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode), - visitFunctionBody((node).body, visitor, context)); + nodeVisitor((node).type, visitor, isTypeNode), + visitFunctionBody((node).body, visitor, context, nodeVisitor)); case SyntaxKind.ArrowFunction: - return updateArrowFunction(node, + return factory.updateArrowFunction(node, nodesVisitor((node).modifiers, visitor, isModifier), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode), - visitNode((node).equalsGreaterThanToken, tokenVisitor, isToken), - visitFunctionBody((node).body, visitor, context)); + nodeVisitor((node).type, visitor, isTypeNode), + nodeVisitor((node).equalsGreaterThanToken, tokenVisitor, isToken), + visitFunctionBody((node).body, visitor, context, nodeVisitor)); case SyntaxKind.DeleteExpression: - return updateDelete(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateDeleteExpression(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.TypeOfExpression: - return updateTypeOf(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateTypeOfExpression(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.VoidExpression: - return updateVoid(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateVoidExpression(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.AwaitExpression: - return updateAwait(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateAwaitExpression(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.PrefixUnaryExpression: - return updatePrefix(node, - visitNode((node).operand, visitor, isExpression)); + return factory.updatePrefixUnaryExpression(node, + nodeVisitor((node).operand, visitor, isExpression)); case SyntaxKind.PostfixUnaryExpression: - return updatePostfix(node, - visitNode((node).operand, visitor, isExpression)); + return factory.updatePostfixUnaryExpression(node, + nodeVisitor((node).operand, visitor, isExpression)); case SyntaxKind.BinaryExpression: - return updateBinary(node, - visitNode((node).left, visitor, isExpression), - visitNode((node).right, visitor, isExpression), - visitNode((node).operatorToken, tokenVisitor, isToken)); + return factory.updateBinaryExpression(node, + nodeVisitor((node).left, visitor, isExpression), + nodeVisitor((node).operatorToken, tokenVisitor, isToken), + nodeVisitor((node).right, visitor, isExpression)); case SyntaxKind.ConditionalExpression: - return updateConditional(node, - visitNode((node).condition, visitor, isExpression), - visitNode((node).questionToken, tokenVisitor, isToken), - visitNode((node).whenTrue, visitor, isExpression), - visitNode((node).colonToken, tokenVisitor, isToken), - visitNode((node).whenFalse, visitor, isExpression)); + return factory.updateConditionalExpression(node, + nodeVisitor((node).condition, visitor, isExpression), + nodeVisitor((node).questionToken, tokenVisitor, isToken), + nodeVisitor((node).whenTrue, visitor, isExpression), + nodeVisitor((node).colonToken, tokenVisitor, isToken), + nodeVisitor((node).whenFalse, visitor, isExpression)); case SyntaxKind.TemplateExpression: - return updateTemplateExpression(node, - visitNode((node).head, visitor, isTemplateHead), + return factory.updateTemplateExpression(node, + nodeVisitor((node).head, visitor, isTemplateHead), nodesVisitor((node).templateSpans, visitor, isTemplateSpan)); case SyntaxKind.YieldExpression: - return updateYield(node, - visitNode((node).asteriskToken, tokenVisitor, isToken), - visitNode((node).expression, visitor, isExpression)); + return factory.updateYieldExpression(node, + nodeVisitor((node).asteriskToken, tokenVisitor, isToken), + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.SpreadElement: - return updateSpread(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateSpreadElement(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.ClassExpression: - return updateClassExpression(node, + return factory.updateClassExpression(node, + nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isIdentifier), + nodeVisitor((node).name, visitor, isIdentifier), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).heritageClauses, visitor, isHeritageClause), nodesVisitor((node).members, visitor, isClassElement)); case SyntaxKind.ExpressionWithTypeArguments: - return updateExpressionWithTypeArguments(node, - nodesVisitor((node).typeArguments, visitor, isTypeNode), - visitNode((node).expression, visitor, isExpression)); + return factory.updateExpressionWithTypeArguments(node, + nodeVisitor((node).expression, visitor, isExpression), + nodesVisitor((node).typeArguments, visitor, isTypeNode)); case SyntaxKind.AsExpression: - return updateAsExpression(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).type, visitor, isTypeNode)); + return factory.updateAsExpression(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.NonNullExpression: - return updateNonNullExpression(node, - visitNode((node).expression, visitor, isExpression)); + if (node.flags & NodeFlags.OptionalChain) { + return factory.updateNonNullChain(node, + nodeVisitor((node).expression, visitor, isExpression)); + } + return factory.updateNonNullExpression(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.MetaProperty: - return updateMetaProperty(node, - visitNode((node).name, visitor, isIdentifier)); + return factory.updateMetaProperty(node, + nodeVisitor((node).name, visitor, isIdentifier)); // Misc case SyntaxKind.TemplateSpan: - return updateTemplateSpan(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).literal, visitor, isTemplateMiddleOrTemplateTail)); + return factory.updateTemplateSpan(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).literal, visitor, isTemplateMiddleOrTemplateTail)); // Element case SyntaxKind.Block: - return updateBlock(node, + return factory.updateBlock(node, nodesVisitor((node).statements, visitor, isStatement)); case SyntaxKind.VariableStatement: - return updateVariableStatement(node, + return factory.updateVariableStatement(node, nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).declarationList, visitor, isVariableDeclarationList)); + nodeVisitor((node).declarationList, visitor, isVariableDeclarationList)); case SyntaxKind.ExpressionStatement: - return updateExpressionStatement(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateExpressionStatement(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.IfStatement: - return updateIf(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).thenStatement, visitor, isStatement, liftToBlock), - visitNode((node).elseStatement, visitor, isStatement, liftToBlock)); + return factory.updateIfStatement(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).thenStatement, visitor, isStatement, factory.liftToBlock), + nodeVisitor((node).elseStatement, visitor, isStatement, factory.liftToBlock)); case SyntaxKind.DoStatement: - return updateDo(node, - visitNode((node).statement, visitor, isStatement, liftToBlock), - visitNode((node).expression, visitor, isExpression)); + return factory.updateDoStatement(node, + nodeVisitor((node).statement, visitor, isStatement, factory.liftToBlock), + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.WhileStatement: - return updateWhile(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).statement, visitor, isStatement, liftToBlock)); + return factory.updateWhileStatement(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).statement, visitor, isStatement, factory.liftToBlock)); case SyntaxKind.ForStatement: - return updateFor(node, - visitNode((node).initializer, visitor, isForInitializer), - visitNode((node).condition, visitor, isExpression), - visitNode((node).incrementor, visitor, isExpression), - visitNode((node).statement, visitor, isStatement, liftToBlock)); + return factory.updateForStatement(node, + nodeVisitor((node).initializer, visitor, isForInitializer), + nodeVisitor((node).condition, visitor, isExpression), + nodeVisitor((node).incrementor, visitor, isExpression), + nodeVisitor((node).statement, visitor, isStatement, factory.liftToBlock)); case SyntaxKind.ForInStatement: - return updateForIn(node, - visitNode((node).initializer, visitor, isForInitializer), - visitNode((node).expression, visitor, isExpression), - visitNode((node).statement, visitor, isStatement, liftToBlock)); + return factory.updateForInStatement(node, + nodeVisitor((node).initializer, visitor, isForInitializer), + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).statement, visitor, isStatement, factory.liftToBlock)); case SyntaxKind.ForOfStatement: - return updateForOf(node, - visitNode((node).awaitModifier, tokenVisitor, isToken), - visitNode((node).initializer, visitor, isForInitializer), - visitNode((node).expression, visitor, isExpression), - visitNode((node).statement, visitor, isStatement, liftToBlock)); + return factory.updateForOfStatement(node, + nodeVisitor((node).awaitModifier, tokenVisitor, isToken), + nodeVisitor((node).initializer, visitor, isForInitializer), + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).statement, visitor, isStatement, factory.liftToBlock)); case SyntaxKind.ContinueStatement: - return updateContinue(node, - visitNode((node).label, visitor, isIdentifier)); + return factory.updateContinueStatement(node, + nodeVisitor((node).label, visitor, isIdentifier)); case SyntaxKind.BreakStatement: - return updateBreak(node, - visitNode((node).label, visitor, isIdentifier)); + return factory.updateBreakStatement(node, + nodeVisitor((node).label, visitor, isIdentifier)); case SyntaxKind.ReturnStatement: - return updateReturn(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateReturnStatement(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.WithStatement: - return updateWith(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).statement, visitor, isStatement, liftToBlock)); + return factory.updateWithStatement(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).statement, visitor, isStatement, factory.liftToBlock)); case SyntaxKind.SwitchStatement: - return updateSwitch(node, - visitNode((node).expression, visitor, isExpression), - visitNode((node).caseBlock, visitor, isCaseBlock)); + return factory.updateSwitchStatement(node, + nodeVisitor((node).expression, visitor, isExpression), + nodeVisitor((node).caseBlock, visitor, isCaseBlock)); case SyntaxKind.LabeledStatement: - return updateLabel(node, - visitNode((node).label, visitor, isIdentifier), - visitNode((node).statement, visitor, isStatement, liftToBlock)); + return factory.updateLabeledStatement(node, + nodeVisitor((node).label, visitor, isIdentifier), + nodeVisitor((node).statement, visitor, isStatement, factory.liftToBlock)); case SyntaxKind.ThrowStatement: - return updateThrow(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateThrowStatement(node, + nodeVisitor((node).expression!, visitor, isExpression)); // expression could be `undefined` due to invalid parse. case SyntaxKind.TryStatement: - return updateTry(node, - visitNode((node).tryBlock, visitor, isBlock), - visitNode((node).catchClause, visitor, isCatchClause), - visitNode((node).finallyBlock, visitor, isBlock)); + return factory.updateTryStatement(node, + nodeVisitor((node).tryBlock, visitor, isBlock), + nodeVisitor((node).catchClause, visitor, isCatchClause), + nodeVisitor((node).finallyBlock, visitor, isBlock)); case SyntaxKind.VariableDeclaration: - return updateTypeScriptVariableDeclaration(node, - visitNode((node).name, visitor, isBindingName), - visitNode((node).exclamationToken, tokenVisitor, isToken), - visitNode((node).type, visitor, isTypeNode), - visitNode((node).initializer, visitor, isExpression)); + return factory.updateVariableDeclaration(node, + nodeVisitor((node).name, visitor, isBindingName), + nodeVisitor((node).exclamationToken, tokenVisitor, isToken), + nodeVisitor((node).type, visitor, isTypeNode), + nodeVisitor((node).initializer, visitor, isExpression)); case SyntaxKind.VariableDeclarationList: - return updateVariableDeclarationList(node, + return factory.updateVariableDeclarationList(node, nodesVisitor((node).declarations, visitor, isVariableDeclaration)); case SyntaxKind.FunctionDeclaration: - return updateFunctionDeclaration(node, + return factory.updateFunctionDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).asteriskToken, tokenVisitor, isToken), - visitNode((node).name, visitor, isIdentifier), + nodeVisitor((node).asteriskToken, tokenVisitor, isToken), + nodeVisitor((node).name, visitor, isIdentifier), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode), - visitFunctionBody((node).body, visitor, context)); + nodeVisitor((node).type, visitor, isTypeNode), + visitFunctionBody((node).body, visitor, context, nodeVisitor)); case SyntaxKind.ClassDeclaration: - return updateClassDeclaration(node, + return factory.updateClassDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isIdentifier), + nodeVisitor((node).name, visitor, isIdentifier), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).heritageClauses, visitor, isHeritageClause), nodesVisitor((node).members, visitor, isClassElement)); case SyntaxKind.InterfaceDeclaration: - return updateInterfaceDeclaration(node, + return factory.updateInterfaceDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isIdentifier), + nodeVisitor((node).name, visitor, isIdentifier), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).heritageClauses, visitor, isHeritageClause), nodesVisitor((node).members, visitor, isTypeElement)); case SyntaxKind.TypeAliasDeclaration: - return updateTypeAliasDeclaration(node, + return factory.updateTypeAliasDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isIdentifier), + nodeVisitor((node).name, visitor, isIdentifier), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); + nodeVisitor((node).type, visitor, isTypeNode)); case SyntaxKind.EnumDeclaration: - return updateEnumDeclaration(node, + return factory.updateEnumDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isIdentifier), + nodeVisitor((node).name, visitor, isIdentifier), nodesVisitor((node).members, visitor, isEnumMember)); case SyntaxKind.ModuleDeclaration: - return updateModuleDeclaration(node, + return factory.updateModuleDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isIdentifier), - visitNode((node).body, visitor, isModuleBody)); + nodeVisitor((node).name, visitor, isIdentifier), + nodeVisitor((node).body, visitor, isModuleBody)); case SyntaxKind.ModuleBlock: - return updateModuleBlock(node, + return factory.updateModuleBlock(node, nodesVisitor((node).statements, visitor, isStatement)); case SyntaxKind.CaseBlock: - return updateCaseBlock(node, + return factory.updateCaseBlock(node, nodesVisitor((node).clauses, visitor, isCaseOrDefaultClause)); case SyntaxKind.NamespaceExportDeclaration: - return updateNamespaceExportDeclaration(node, - visitNode((node).name, visitor, isIdentifier)); + return factory.updateNamespaceExportDeclaration(node, + nodeVisitor((node).name, visitor, isIdentifier)); case SyntaxKind.ImportEqualsDeclaration: - return updateImportEqualsDeclaration(node, + return factory.updateImportEqualsDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).name, visitor, isIdentifier), - visitNode((node).moduleReference, visitor, isModuleReference)); + nodeVisitor((node).name, visitor, isIdentifier), + nodeVisitor((node).moduleReference, visitor, isModuleReference)); case SyntaxKind.ImportDeclaration: - return updateImportDeclaration(node, + return factory.updateImportDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).importClause, visitor, isImportClause), - visitNode((node).moduleSpecifier, visitor, isExpression)); + nodeVisitor((node).importClause, visitor, isImportClause), + nodeVisitor((node).moduleSpecifier, visitor, isExpression)); case SyntaxKind.ImportClause: - return updateImportClause(node, - visitNode((node).name, visitor, isIdentifier), - visitNode((node).namedBindings, visitor, isNamedImportBindings), - (node as ImportClause).isTypeOnly); + return factory.updateImportClause(node, + (node as ImportClause).isTypeOnly, + nodeVisitor((node).name, visitor, isIdentifier), + nodeVisitor((node).namedBindings, visitor, isNamedImportBindings)); case SyntaxKind.NamespaceImport: - return updateNamespaceImport(node, - visitNode((node).name, visitor, isIdentifier)); + return factory.updateNamespaceImport(node, + nodeVisitor((node).name, visitor, isIdentifier)); case SyntaxKind.NamespaceExport: - return updateNamespaceExport(node, - visitNode((node).name, visitor, isIdentifier)); + return factory.updateNamespaceExport(node, + nodeVisitor((node).name, visitor, isIdentifier)); case SyntaxKind.NamedImports: - return updateNamedImports(node, + return factory.updateNamedImports(node, nodesVisitor((node).elements, visitor, isImportSpecifier)); case SyntaxKind.ImportSpecifier: - return updateImportSpecifier(node, - visitNode((node).propertyName, visitor, isIdentifier), - visitNode((node).name, visitor, isIdentifier)); + return factory.updateImportSpecifier(node, + nodeVisitor((node).propertyName, visitor, isIdentifier), + nodeVisitor((node).name, visitor, isIdentifier)); case SyntaxKind.ExportAssignment: - return updateExportAssignment(node, + return factory.updateExportAssignment(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).expression, visitor, isExpression)); + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.ExportDeclaration: - return updateExportDeclaration(node, + return factory.updateExportDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).exportClause, visitor, isNamedExportBindings), - visitNode((node).moduleSpecifier, visitor, isExpression), - (node as ExportDeclaration).isTypeOnly); + (node as ExportDeclaration).isTypeOnly, + nodeVisitor((node).exportClause, visitor, isNamedExportBindings), + nodeVisitor((node).moduleSpecifier, visitor, isExpression)); case SyntaxKind.NamedExports: - return updateNamedExports(node, + return factory.updateNamedExports(node, nodesVisitor((node).elements, visitor, isExportSpecifier)); case SyntaxKind.ExportSpecifier: - return updateExportSpecifier(node, - visitNode((node).propertyName, visitor, isIdentifier), - visitNode((node).name, visitor, isIdentifier)); + return factory.updateExportSpecifier(node, + nodeVisitor((node).propertyName, visitor, isIdentifier), + nodeVisitor((node).name, visitor, isIdentifier)); // Module references case SyntaxKind.ExternalModuleReference: - return updateExternalModuleReference(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateExternalModuleReference(node, + nodeVisitor((node).expression, visitor, isExpression)); // JSX case SyntaxKind.JsxElement: - return updateJsxElement(node, - visitNode((node).openingElement, visitor, isJsxOpeningElement), + return factory.updateJsxElement(node, + nodeVisitor((node).openingElement, visitor, isJsxOpeningElement), nodesVisitor((node).children, visitor, isJsxChild), - visitNode((node).closingElement, visitor, isJsxClosingElement)); + nodeVisitor((node).closingElement, visitor, isJsxClosingElement)); case SyntaxKind.JsxSelfClosingElement: - return updateJsxSelfClosingElement(node, - visitNode((node).tagName, visitor, isJsxTagNameExpression), + return factory.updateJsxSelfClosingElement(node, + nodeVisitor((node).tagName, visitor, isJsxTagNameExpression), nodesVisitor((node).typeArguments, visitor, isTypeNode), - visitNode((node).attributes, visitor, isJsxAttributes)); + nodeVisitor((node).attributes, visitor, isJsxAttributes)); case SyntaxKind.JsxOpeningElement: - return updateJsxOpeningElement(node, - visitNode((node).tagName, visitor, isJsxTagNameExpression), + return factory.updateJsxOpeningElement(node, + nodeVisitor((node).tagName, visitor, isJsxTagNameExpression), nodesVisitor((node).typeArguments, visitor, isTypeNode), - visitNode((node).attributes, visitor, isJsxAttributes)); + nodeVisitor((node).attributes, visitor, isJsxAttributes)); case SyntaxKind.JsxClosingElement: - return updateJsxClosingElement(node, - visitNode((node).tagName, visitor, isJsxTagNameExpression)); + return factory.updateJsxClosingElement(node, + nodeVisitor((node).tagName, visitor, isJsxTagNameExpression)); case SyntaxKind.JsxFragment: - return updateJsxFragment(node, - visitNode((node).openingFragment, visitor, isJsxOpeningFragment), + return factory.updateJsxFragment(node, + nodeVisitor((node).openingFragment, visitor, isJsxOpeningFragment), nodesVisitor((node).children, visitor, isJsxChild), - visitNode((node).closingFragment, visitor, isJsxClosingFragment)); + nodeVisitor((node).closingFragment, visitor, isJsxClosingFragment)); case SyntaxKind.JsxAttribute: - return updateJsxAttribute(node, - visitNode((node).name, visitor, isIdentifier), - visitNode((node).initializer, visitor, isStringLiteralOrJsxExpression)); + return factory.updateJsxAttribute(node, + nodeVisitor((node).name, visitor, isIdentifier), + nodeVisitor((node).initializer, visitor, isStringLiteralOrJsxExpression)); case SyntaxKind.JsxAttributes: - return updateJsxAttributes(node, + return factory.updateJsxAttributes(node, nodesVisitor((node).properties, visitor, isJsxAttributeLike)); case SyntaxKind.JsxSpreadAttribute: - return updateJsxSpreadAttribute(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateJsxSpreadAttribute(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.JsxExpression: - return updateJsxExpression(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateJsxExpression(node, + nodeVisitor((node).expression, visitor, isExpression)); // Clauses case SyntaxKind.CaseClause: - return updateCaseClause(node, - visitNode((node).expression, visitor, isExpression), + return factory.updateCaseClause(node, + nodeVisitor((node).expression, visitor, isExpression), nodesVisitor((node).statements, visitor, isStatement)); case SyntaxKind.DefaultClause: - return updateDefaultClause(node, + return factory.updateDefaultClause(node, nodesVisitor((node).statements, visitor, isStatement)); case SyntaxKind.HeritageClause: - return updateHeritageClause(node, + return factory.updateHeritageClause(node, nodesVisitor((node).types, visitor, isExpressionWithTypeArguments)); case SyntaxKind.CatchClause: - return updateCatchClause(node, - visitNode((node).variableDeclaration, visitor, isVariableDeclaration), - visitNode((node).block, visitor, isBlock)); + return factory.updateCatchClause(node, + nodeVisitor((node).variableDeclaration, visitor, isVariableDeclaration), + nodeVisitor((node).block, visitor, isBlock)); // Property assignments case SyntaxKind.PropertyAssignment: - return updatePropertyAssignment(node, - visitNode((node).name, visitor, isPropertyName), - visitNode((node).initializer, visitor, isExpression)); + return factory.updatePropertyAssignment(node, + nodeVisitor((node).name, visitor, isPropertyName), + nodeVisitor((node).initializer, visitor, isExpression)); case SyntaxKind.ShorthandPropertyAssignment: - return updateShorthandPropertyAssignment(node, - visitNode((node).name, visitor, isIdentifier), - visitNode((node).objectAssignmentInitializer, visitor, isExpression)); + return factory.updateShorthandPropertyAssignment(node, + nodeVisitor((node).name, visitor, isIdentifier), + nodeVisitor((node).objectAssignmentInitializer, visitor, isExpression)); case SyntaxKind.SpreadAssignment: - return updateSpreadAssignment(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updateSpreadAssignment(node, + nodeVisitor((node).expression, visitor, isExpression)); // Enum case SyntaxKind.EnumMember: - return updateEnumMember(node, - visitNode((node).name, visitor, isPropertyName), - visitNode((node).initializer, visitor, isExpression)); + return factory.updateEnumMember(node, + nodeVisitor((node).name, visitor, isPropertyName), + nodeVisitor((node).initializer, visitor, isExpression)); // Top-level nodes case SyntaxKind.SourceFile: - return updateSourceFileNode(node, + return factory.updateSourceFile(node, visitLexicalEnvironment((node).statements, visitor, context)); // Transformation nodes case SyntaxKind.PartiallyEmittedExpression: - return updatePartiallyEmittedExpression(node, - visitNode((node).expression, visitor, isExpression)); + return factory.updatePartiallyEmittedExpression(node, + nodeVisitor((node).expression, visitor, isExpression)); case SyntaxKind.CommaListExpression: - return updateCommaList(node, + return factory.updateCommaListExpression(node, nodesVisitor((node).elements, visitor, isExpression)); default: diff --git a/src/harness/harnessGlobals.ts b/src/harness/harnessGlobals.ts index ace692ba536d8..63a85309aaa0a 100644 --- a/src/harness/harnessGlobals.ts +++ b/src/harness/harnessGlobals.ts @@ -3,6 +3,7 @@ // this will work in the browser via browserify declare var assert: typeof _chai.assert; +declare var expect: typeof _chai.expect; var _chai: typeof import("chai") = require("chai"); globalThis.assert = _chai.assert; { @@ -28,6 +29,7 @@ globalThis.assert = _chai.assert; } }; } +globalThis.expect = _chai.expect; /* eslint-enable no-var */ // empty ts namespace so this file is included in the `ts.ts` namespace file generated by the module swapover // This way, everything that ends up importing `ts` downstream also imports this file and picks up its augmentation diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 353238c32a879..5782b3b448810 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1986,9 +1986,6 @@ namespace ts.server { const configFileContent = tryReadFile(configFilename, fileName => this.host.readFile(fileName)); const result = parseJsonText(configFilename, isString(configFileContent) ? configFileContent : ""); - if (!result.endOfFileToken) { - result.endOfFileToken = { kind: SyntaxKind.EndOfFileToken }; - } const configFileErrors = result.parseDiagnostics as Diagnostic[]; if (!isString(configFileContent)) configFileErrors.push(configFileContent); const parsedCommandLine = parseJsonSourceFileConfigFileContent( diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 7144a28eebfbf..d10f67e0e941e 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -685,7 +685,7 @@ namespace ts { const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) { // TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]` - docCommentAndDiagnostics.jsDoc.parent = token as HasJSDoc; + setParent(docCommentAndDiagnostics.jsDoc, token as HasJSDoc); classifyJSDocComment(docCommentAndDiagnostics.jsDoc); return; } diff --git a/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts b/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts index a6c91e5915181..3351ef9e5a3a7 100644 --- a/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts +++ b/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts @@ -14,10 +14,10 @@ namespace ts.codefix { function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) { const token = getTokenAtPosition(sourceFile, pos); - const assertion = Debug.checkDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)), "Expected to find an assertion expression"); + const assertion = Debug.checkDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertionExpression(n)), "Expected to find an assertion expression"); const replacement = isAsExpression(assertion) - ? createAsExpression(assertion.expression, createKeywordTypeNode(SyntaxKind.UnknownKeyword)) - : createTypeAssertion(createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression); + ? factory.createAsExpression(assertion.expression, factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword)) + : factory.createTypeAssertion(factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression); changeTracker.replaceNode(sourceFile, assertion.expression, replacement); } } diff --git a/src/services/codefixes/addEmptyExportDeclaration.ts b/src/services/codefixes/addEmptyExportDeclaration.ts index 2b4c32cd11ab5..96b7a81e17bb8 100644 --- a/src/services/codefixes/addEmptyExportDeclaration.ts +++ b/src/services/codefixes/addEmptyExportDeclaration.ts @@ -5,12 +5,12 @@ namespace ts.codefix { getCodeActions: context => { const { sourceFile } = context; const changes = textChanges.ChangeTracker.with(context, changes => { - const exportDeclaration = createExportDeclaration( + const exportDeclaration = factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports([]), - /*moduleSpecifier*/ undefined, - /*isTypeOnly*/ false + /*isTypeOnly*/ false, + factory.createNamedExports([]), + /*moduleSpecifier*/ undefined ); changes.insertNodeAtEndOfScope(sourceFile, sourceFile, exportDeclaration); }); diff --git a/src/services/codefixes/addMissingAsync.ts b/src/services/codefixes/addMissingAsync.ts index 2f2ceba35703e..2c3e57082309f 100644 --- a/src/services/codefixes/addMissingAsync.ts +++ b/src/services/codefixes/addMissingAsync.ts @@ -52,9 +52,9 @@ namespace ts.codefix { } } fixedDeclarations?.set(getNodeId(insertionSite).toString(), true); - const cloneWithModifier = getSynthesizedDeepClone(insertionSite, /*includeTrivia*/ true); - cloneWithModifier.modifiers = createNodeArray(createModifiersFromModifierFlags(getSyntacticModifierFlags(insertionSite) | ModifierFlags.Async)); - cloneWithModifier.modifierFlagsCache = 0; + const cloneWithModifier = factory.updateModifiers( + getSynthesizedDeepClone(insertionSite, /*includeTrivia*/ true), + factory.createNodeArray(factory.createModifiersFromModifierFlags(getSyntacticModifierFlags(insertionSite) | ModifierFlags.Async))); changeTracker.replaceNode( sourceFile, insertionSite, diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts index 89c6e6d267fb9..fc7c25d3f7db9 100644 --- a/src/services/codefixes/addMissingAwait.ts +++ b/src/services/codefixes/addMissingAwait.ts @@ -244,7 +244,7 @@ namespace ts.codefix { } } const type = checker.getTypeAtLocation(side); - const newNode = checker.getPromisedTypeOfPromise(type) ? createAwait(side) : side; + const newNode = checker.getPromisedTypeOfPromise(type) ? factory.createAwaitExpression(side) : side; changeTracker.replaceNode(sourceFile, side, newNode); } } @@ -258,7 +258,7 @@ namespace ts.codefix { changeTracker.replaceNode( sourceFile, insertionSite.parent.expression, - createParen(createAwait(insertionSite.parent.expression))); + factory.createParenthesizedExpression(factory.createAwaitExpression(insertionSite.parent.expression))); insertLeadingSemicolonIfNeeded(changeTracker, insertionSite.parent.expression, sourceFile); } else if (contains(callableConstructableErrorCodes, errorCode) && isCallOrNewExpression(insertionSite.parent)) { @@ -268,7 +268,7 @@ namespace ts.codefix { return; } } - changeTracker.replaceNode(sourceFile, insertionSite, createParen(createAwait(insertionSite))); + changeTracker.replaceNode(sourceFile, insertionSite, factory.createParenthesizedExpression(factory.createAwaitExpression(insertionSite))); insertLeadingSemicolonIfNeeded(changeTracker, insertionSite, sourceFile); } else { @@ -278,7 +278,7 @@ namespace ts.codefix { return; } } - changeTracker.replaceNode(sourceFile, insertionSite, createAwait(insertionSite)); + changeTracker.replaceNode(sourceFile, insertionSite, factory.createAwaitExpression(insertionSite)); } } diff --git a/src/services/codefixes/addMissingInvocationForDecorator.ts b/src/services/codefixes/addMissingInvocationForDecorator.ts index 25100870623db..e772b4a82f267 100644 --- a/src/services/codefixes/addMissingInvocationForDecorator.ts +++ b/src/services/codefixes/addMissingInvocationForDecorator.ts @@ -16,7 +16,7 @@ namespace ts.codefix { const token = getTokenAtPosition(sourceFile, pos); const decorator = findAncestor(token, isDecorator)!; Debug.assert(!!decorator, "Expected position to be owned by a decorator."); - const replacement = createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined); + const replacement = factory.createCallExpression(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined); changeTracker.replaceNode(sourceFile, decorator.expression, replacement); } } diff --git a/src/services/codefixes/addNameToNamelessParameter.ts b/src/services/codefixes/addNameToNamelessParameter.ts index 3339f71900845..07bc1bea7e3c6 100644 --- a/src/services/codefixes/addNameToNamelessParameter.ts +++ b/src/services/codefixes/addNameToNamelessParameter.ts @@ -24,13 +24,13 @@ namespace ts.codefix { const i = param.parent.parameters.indexOf(param); Debug.assert(!param.type, "Tried to add a parameter name to a parameter that already had one."); Debug.assert(i > -1, "Parameter not found in parent parameter list."); - const replacement = createParameter( + const replacement = factory.createParameterDeclaration( /*decorators*/ undefined, param.modifiers, param.dotDotDotToken, "arg" + i, param.questionToken, - createTypeReferenceNode(token, /*typeArguments*/ undefined), + factory.createTypeReferenceNode(token, /*typeArguments*/ undefined), param.initializer); changeTracker.replaceNode(sourceFile, token, replacement); } diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index 55d2544a5ca05..274902c1041bb 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -46,14 +46,14 @@ namespace ts.codefix { if (typeParameters.length) changes.insertTypeParameters(sourceFile, decl, typeParameters); } const needParens = isArrowFunction(decl) && !findChildOfKind(decl, SyntaxKind.OpenParenToken, sourceFile); - if (needParens) changes.insertNodeBefore(sourceFile, first(decl.parameters), createToken(SyntaxKind.OpenParenToken)); + if (needParens) changes.insertNodeBefore(sourceFile, first(decl.parameters), factory.createToken(SyntaxKind.OpenParenToken)); for (const param of decl.parameters) { if (!param.type) { const paramType = getJSDocType(param); if (paramType) changes.tryInsertTypeAnnotation(sourceFile, param, transformJSDocType(paramType)); } } - if (needParens) changes.insertNodeAfter(sourceFile, last(decl.parameters), createToken(SyntaxKind.CloseParenToken)); + if (needParens) changes.insertNodeAfter(sourceFile, last(decl.parameters), factory.createToken(SyntaxKind.CloseParenToken)); if (!decl.type) { const returnType = getJSDocReturnType(decl); if (returnType) changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(returnType)); @@ -77,7 +77,7 @@ namespace ts.codefix { switch (node.kind) { case SyntaxKind.JSDocAllType: case SyntaxKind.JSDocUnknownType: - return createTypeReferenceNode("any", emptyArray); + return factory.createTypeReferenceNode("any", emptyArray); case SyntaxKind.JSDocOptionalType: return transformJSDocOptionalType(node as JSDocOptionalType); case SyntaxKind.JSDocNonNullableType: @@ -91,34 +91,36 @@ namespace ts.codefix { case SyntaxKind.TypeReference: return transformJSDocTypeReference(node as TypeReferenceNode); default: - const visited = visitEachChild(node, transformJSDocType, /*context*/ undefined!); // TODO: GH#18217 + const visited = visitEachChild(node, transformJSDocType, nullTransformationContext); setEmitFlags(visited, EmitFlags.SingleLine); return visited; } } function transformJSDocOptionalType(node: JSDocOptionalType) { - return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("undefined", emptyArray)]); + return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType), factory.createTypeReferenceNode("undefined", emptyArray)]); } function transformJSDocNullableType(node: JSDocNullableType) { - return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("null", emptyArray)]); + return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType), factory.createTypeReferenceNode("null", emptyArray)]); } function transformJSDocVariadicType(node: JSDocVariadicType) { - return createArrayTypeNode(visitNode(node.type, transformJSDocType)); + return factory.createArrayTypeNode(visitNode(node.type, transformJSDocType)); } function transformJSDocFunctionType(node: JSDocFunctionType) { - return createFunctionTypeNode(emptyArray, node.parameters.map(transformJSDocParameter), node.type); + // TODO: This does not properly handle `function(new:C, string)` per https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System#the-javascript-type-language + // however we do handle it correctly in `serializeTypeForDeclaration` in checker.ts + return factory.createFunctionTypeNode(emptyArray, node.parameters.map(transformJSDocParameter), node.type ?? factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)); } function transformJSDocParameter(node: ParameterDeclaration) { const index = node.parent.parameters.indexOf(node); const isRest = node.type!.kind === SyntaxKind.JSDocVariadicType && index === node.parent.parameters.length - 1; // TODO: GH#18217 const name = node.name || (isRest ? "rest" : "arg" + index); - const dotdotdot = isRest ? createToken(SyntaxKind.DotDotDotToken) : node.dotDotDotToken; - return createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType), node.initializer); + const dotdotdot = isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : node.dotDotDotToken; + return factory.createParameterDeclaration(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType), node.initializer); } function transformJSDocTypeReference(node: TypeReferenceNode) { @@ -142,27 +144,27 @@ namespace ts.codefix { text = text[0].toUpperCase() + text.slice(1); break; } - name = createIdentifier(text); + name = factory.createIdentifier(text); if ((text === "Array" || text === "Promise") && !node.typeArguments) { - args = createNodeArray([createTypeReferenceNode("any", emptyArray)]); + args = factory.createNodeArray([factory.createTypeReferenceNode("any", emptyArray)]); } else { args = visitNodes(node.typeArguments, transformJSDocType); } } - return createTypeReferenceNode(name, args); + return factory.createTypeReferenceNode(name, args); } function transformJSDocIndexSignature(node: TypeReferenceNode) { - const index = createParameter( + const index = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, node.typeArguments![0].kind === SyntaxKind.NumberKeyword ? "n" : "s", /*questionToken*/ undefined, - createTypeReferenceNode(node.typeArguments![0].kind === SyntaxKind.NumberKeyword ? "number" : "string", []), + factory.createTypeReferenceNode(node.typeArguments![0].kind === SyntaxKind.NumberKeyword ? "number" : "string", []), /*initializer*/ undefined); - const indexSignature = createTypeLiteralNode([createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments![1])]); + const indexSignature = factory.createTypeLiteralNode([factory.createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments![1])]); setEmitFlags(indexSignature, EmitFlags.SingleLine); return indexSignature; } diff --git a/src/services/codefixes/convertFunctionToEs6Class.ts b/src/services/codefixes/convertFunctionToEs6Class.ts index 6c9f416071505..0ca2135307f95 100644 --- a/src/services/codefixes/convertFunctionToEs6Class.ts +++ b/src/services/codefixes/convertFunctionToEs6Class.ts @@ -93,7 +93,7 @@ namespace ts.codefix { } } else { - const memberElement = createClassElement(member, [createToken(SyntaxKind.StaticKeyword)]); + const memberElement = createClassElement(member, [factory.createToken(SyntaxKind.StaticKeyword)]); if (memberElement) { memberElements.push(...memberElement); } @@ -146,7 +146,7 @@ namespace ts.codefix { changes.delete(sourceFile, nodeToDelete); if (!assignmentExpr) { - members.push(createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, + members.push(factory.createPropertyDeclaration([], modifiers, symbol.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)); return members; } @@ -177,13 +177,13 @@ namespace ts.codefix { // Don't try to declare members in JavaScript files if (isSourceFileJS(sourceFile)) return members; if (!isPropertyAccessExpression(memberDeclaration)) return members; - const prop = createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, /*type*/ undefined, assignmentExpr); + const prop = factory.createPropertyDeclaration(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, /*type*/ undefined, assignmentExpr); copyLeadingComments(assignmentBinaryExpression.parent, prop, sourceFile); members.push(prop); return members; } - type MethodName = Parameters[3]; + type MethodName = Parameters[3]; function createFunctionLikeExpressionMember(members: readonly ClassElement[], expression: FunctionExpression | ArrowFunction, name: MethodName) { if (isFunctionExpression(expression)) return createFunctionExpressionMember(members, expression, name); @@ -192,8 +192,8 @@ namespace ts.codefix { function createFunctionExpressionMember(members: readonly ClassElement[], functionExpression: FunctionExpression, name: MethodName) { const fullModifiers = concatenate(modifiers, getModifierKindFromSource(functionExpression, SyntaxKind.AsyncKeyword)); - const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, name, /*questionToken*/ undefined, - /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body); + const method = factory.createMethodDeclaration(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, name, /*questionToken*/ undefined, + /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body); copyLeadingComments(assignmentBinaryExpression, method, sourceFile); return members.concat(method); } @@ -208,10 +208,10 @@ namespace ts.codefix { } // case 2: () => [1,2,3] else { - bodyBlock = createBlock([createReturn(arrowFunctionBody)]); + bodyBlock = factory.createBlock([factory.createReturnStatement(arrowFunctionBody)]); } const fullModifiers = concatenate(modifiers, getModifierKindFromSource(arrowFunction, SyntaxKind.AsyncKeyword)); - const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, name, /*questionToken*/ undefined, + const method = factory.createMethodDeclaration(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, name, /*questionToken*/ undefined, /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock); copyLeadingComments(assignmentBinaryExpression, method, sourceFile); return members.concat(method); @@ -231,11 +231,11 @@ namespace ts.codefix { const memberElements = createClassElementsFromSymbol(node.symbol); if (initializer.body) { - memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); + memberElements.unshift(factory.createConstructorDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); } const modifiers = getModifierKindFromSource(precedingNode!, SyntaxKind.ExportKeyword); - const cls = createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, + const cls = factory.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); // Don't call copyComments here because we'll already leave them in place return cls; @@ -244,11 +244,11 @@ namespace ts.codefix { function createClassFromFunctionDeclaration(node: FunctionDeclaration): ClassDeclaration { const memberElements = createClassElementsFromSymbol(ctorSymbol); if (node.body) { - memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); + memberElements.unshift(factory.createConstructorDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); } const modifiers = getModifierKindFromSource(node, SyntaxKind.ExportKeyword); - const cls = createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, + const cls = factory.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); // Don't call copyComments here because we'll already leave them in place return cls; diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 108acee68cfa1..72bc3cb2a956a 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -173,7 +173,7 @@ namespace ts.codefix { // so we push an entry for 'response'. if (lastCallSignature && !isFunctionLikeDeclaration(node.parent) && !synthNamesMap.has(symbolIdString)) { const firstParameter = firstOrUndefined(lastCallSignature.parameters); - const ident = firstParameter && isParameter(firstParameter.valueDeclaration) && tryCast(firstParameter.valueDeclaration.name, isIdentifier) || createOptimisticUniqueName("result"); + const ident = firstParameter && isParameter(firstParameter.valueDeclaration) && tryCast(firstParameter.valueDeclaration.name, isIdentifier) || factory.createUniqueName("result", GeneratedIdentifierFlags.Optimistic); const synthName = getNewNameIfConflict(ident, collidingSymbolMap); synthNamesMap.set(symbolIdString, synthName); collidingSymbolMap.add(ident.text, symbol); @@ -204,7 +204,7 @@ namespace ts.codefix { function getNewNameIfConflict(name: Identifier, originalNames: ReadonlyMap): SynthIdentifier { const numVarsSameName = (originalNames.get(name.text) || emptyArray).length; - const identifier = numVarsSameName === 0 ? name : createIdentifier(name.text + "_" + numVarsSameName); + const identifier = numVarsSameName === 0 ? name : factory.createIdentifier(name.text + "_" + numVarsSameName); return createSynthIdentifier(identifier); } @@ -258,7 +258,7 @@ namespace ts.codefix { }); } else { - possibleNameForVarDecl = createSynthIdentifier(createOptimisticUniqueName("result"), prevArgName.types); + possibleNameForVarDecl = createSynthIdentifier(factory.createUniqueName("result", GeneratedIdentifierFlags.Optimistic), prevArgName.types); } // We are about to write a 'let' variable declaration, but `transformExpression` for both @@ -267,11 +267,11 @@ namespace ts.codefix { possibleNameForVarDecl.hasBeenDeclared = true; } - const tryBlock = createBlock(transformExpression(node.expression, transformer, possibleNameForVarDecl)); + const tryBlock = factory.createBlock(transformExpression(node.expression, transformer, possibleNameForVarDecl)); const transformationBody = getTransformationBody(func, possibleNameForVarDecl, argName, node, transformer); const catchArg = argName ? isSynthIdentifier(argName) ? argName.identifier.text : argName.bindingPattern : "e"; - const catchVariableDeclaration = createVariableDeclaration(catchArg); - const catchClause = createCatchClause(catchVariableDeclaration, createBlock(transformationBody)); + const catchVariableDeclaration = factory.createVariableDeclaration(catchArg); + const catchClause = factory.createCatchClause(catchVariableDeclaration, factory.createBlock(transformationBody)); /* In order to avoid an implicit any, we will synthesize a type for the declaration using the unions of the types of both paths (try block and catch block) @@ -283,18 +283,18 @@ namespace ts.codefix { const typeArray: Type[] = possibleNameForVarDecl.types; const unionType = transformer.checker.getUnionType(typeArray, UnionReduction.Subtype); const unionTypeNode = transformer.isInJSFile ? undefined : transformer.checker.typeToTypeNode(unionType, /*enclosingDeclaration*/ undefined, /*flags*/ undefined); - const varDecl = [createVariableDeclaration(varDeclIdentifier, unionTypeNode)]; - varDeclList = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList(varDecl, NodeFlags.Let)); + const varDecl = [factory.createVariableDeclaration(varDeclIdentifier, /*exclamationToken*/ undefined, unionTypeNode)]; + varDeclList = factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList(varDecl, NodeFlags.Let)); } - const tryStatement = createTry(tryBlock, catchClause, /*finallyBlock*/ undefined); + const tryStatement = factory.createTryStatement(tryBlock, catchClause, /*finallyBlock*/ undefined); const destructuredResult = prevArgName && varDeclIdentifier && isSynthBindingPattern(prevArgName) - && createVariableStatement(/* modifiers */ undefined, createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepCloneWithRenames(prevArgName.bindingPattern), /* type */ undefined, varDeclIdentifier)], NodeFlags.Const)); + && factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(getSynthesizedDeepCloneWithRenames(prevArgName.bindingPattern), /*exclamationToken*/ undefined, /*type*/ undefined, varDeclIdentifier)], NodeFlags.Const)); return compact([varDeclList, tryStatement, destructuredResult]); } function createUniqueSynthName(prevArgName: SynthIdentifier): SynthIdentifier { - const renamedPrevArg = createOptimisticUniqueName(prevArgName.identifier.text); + const renamedPrevArg = factory.createUniqueName(prevArgName.identifier.text, GeneratedIdentifierFlags.Optimistic); return createSynthIdentifier(renamedPrevArg); } @@ -305,13 +305,13 @@ namespace ts.codefix { if (onRejected) { const onRejectedArgumentName = getArgBindingName(onRejected, transformer); - const tryBlock = createBlock(transformExpression(node.expression, transformer, onFulfilledArgumentName).concat(transformationBody)); + const tryBlock = factory.createBlock(transformExpression(node.expression, transformer, onFulfilledArgumentName).concat(transformationBody)); const transformationBody2 = getTransformationBody(onRejected, prevArgName, onRejectedArgumentName, node, transformer); const catchArg = onRejectedArgumentName ? isSynthIdentifier(onRejectedArgumentName) ? onRejectedArgumentName.identifier.text : onRejectedArgumentName.bindingPattern : "e"; - const catchVariableDeclaration = createVariableDeclaration(catchArg); - const catchClause = createCatchClause(catchVariableDeclaration, createBlock(transformationBody2)); + const catchVariableDeclaration = factory.createVariableDeclaration(catchArg); + const catchClause = factory.createCatchClause(catchVariableDeclaration, factory.createBlock(transformationBody2)); - return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined)]; + return [factory.createTryStatement(tryBlock, catchClause, /* finallyBlock */ undefined)]; } return transformExpression(node.expression, transformer, onFulfilledArgumentName).concat(transformationBody); @@ -322,29 +322,30 @@ namespace ts.codefix { */ function transformPromiseExpressionOfPropertyAccess(node: Expression, transformer: Transformer, prevArgName?: SynthBindingName): readonly Statement[] { if (shouldReturn(node, transformer)) { - return [createReturn(getSynthesizedDeepClone(node))]; + return [factory.createReturnStatement(getSynthesizedDeepClone(node))]; } - return createVariableOrAssignmentOrExpressionStatement(prevArgName, createAwait(node), /*typeAnnotation*/ undefined); + return createVariableOrAssignmentOrExpressionStatement(prevArgName, factory.createAwaitExpression(node), /*typeAnnotation*/ undefined); } function createVariableOrAssignmentOrExpressionStatement(variableName: SynthBindingName | undefined, rightHandSide: Expression, typeAnnotation: TypeNode | undefined): readonly Statement[] { if (!variableName || isEmptyBindingName(variableName)) { // if there's no argName to assign to, there still might be side effects - return [createExpressionStatement(rightHandSide)]; + return [factory.createExpressionStatement(rightHandSide)]; } if (isSynthIdentifier(variableName) && variableName.hasBeenDeclared) { // if the variable has already been declared, we don't need "let" or "const" - return [createExpressionStatement(createAssignment(getSynthesizedDeepClone(variableName.identifier), rightHandSide))]; + return [factory.createExpressionStatement(factory.createAssignment(getSynthesizedDeepClone(variableName.identifier), rightHandSide))]; } return [ - createVariableStatement( + factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( getSynthesizedDeepClone(getNode(variableName)), + /*exclamationToken*/ undefined, typeAnnotation, rightHandSide)], NodeFlags.Const))]; @@ -352,13 +353,13 @@ namespace ts.codefix { function maybeAnnotateAndReturn(expressionToReturn: Expression | undefined, typeAnnotation: TypeNode | undefined): readonly Statement[] { if (typeAnnotation && expressionToReturn) { - const name = createOptimisticUniqueName("result"); + const name = factory.createUniqueName("result", GeneratedIdentifierFlags.Optimistic); return [ ...createVariableOrAssignmentOrExpressionStatement(createSynthIdentifier(name), expressionToReturn, typeAnnotation), - createReturn(name) + factory.createReturnStatement(name) ]; } - return [createReturn(expressionToReturn)]; + return [factory.createReturnStatement(expressionToReturn)]; } // should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts @@ -373,7 +374,7 @@ namespace ts.codefix { break; } - const synthCall = createCall(getSynthesizedDeepClone(func as Identifier), /*typeArguments*/ undefined, isSynthIdentifier(argName) ? [argName.identifier] : []); + const synthCall = factory.createCallExpression(getSynthesizedDeepClone(func as Identifier), /*typeArguments*/ undefined, isSynthIdentifier(argName) ? [argName.identifier] : []); if (shouldReturn(parent, transformer)) { return maybeAnnotateAndReturn(synthCall, parent.typeArguments?.[0]); } @@ -385,7 +386,7 @@ namespace ts.codefix { return silentFail(); } const returnType = callSignatures[0].getReturnType(); - const varDeclOrAssignment = createVariableOrAssignmentOrExpressionStatement(prevArgName, createAwait(synthCall), parent.typeArguments?.[0]); + const varDeclOrAssignment = createVariableOrAssignmentOrExpressionStatement(prevArgName, factory.createAwaitExpression(synthCall), parent.typeArguments?.[0]); if (prevArgName) { prevArgName.types.push(returnType); } @@ -423,7 +424,7 @@ namespace ts.codefix { seenReturnStatement); } else { - const innerRetStmts = isFixablePromiseHandler(funcBody) ? [createReturn(funcBody)] : emptyArray; + const innerRetStmts = isFixablePromiseHandler(funcBody) ? [factory.createReturnStatement(funcBody)] : emptyArray; const innerCbBody = getInnerTransformationBody(transformer, innerRetStmts, prevArgName); if (innerCbBody.length > 0) { @@ -433,7 +434,7 @@ namespace ts.codefix { const type = transformer.checker.getTypeAtLocation(func); const returnType = getLastCallSignature(type, transformer.checker)!.getReturnType(); const rightHandSide = getSynthesizedDeepClone(funcBody); - const possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType) ? createAwait(rightHandSide) : rightHandSide; + const possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType) ? factory.createAwaitExpression(rightHandSide) : rightHandSide; if (!shouldReturn(parent, transformer)) { const transformedStatement = createVariableOrAssignmentOrExpressionStatement(prevArgName, possiblyAwaitedRightHandSide, /*typeAnnotation*/ undefined); if (prevArgName) { @@ -464,13 +465,13 @@ namespace ts.codefix { for (const stmt of stmts) { if (isReturnStatement(stmt)) { if (stmt.expression) { - const possiblyAwaitedExpression = isPromiseTypedExpression(stmt.expression, transformer.checker) ? createAwait(stmt.expression) : stmt.expression; + const possiblyAwaitedExpression = isPromiseTypedExpression(stmt.expression, transformer.checker) ? factory.createAwaitExpression(stmt.expression) : stmt.expression; if (prevArgName === undefined) { - ret.push(createExpressionStatement(possiblyAwaitedExpression)); + ret.push(factory.createExpressionStatement(possiblyAwaitedExpression)); } else { - ret.push(createVariableStatement(/*modifiers*/ undefined, - (createVariableDeclarationList([createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, possiblyAwaitedExpression)], NodeFlags.Const)))); + ret.push(factory.createVariableStatement(/*modifiers*/ undefined, + (factory.createVariableDeclarationList([factory.createVariableDeclaration(getNode(prevArgName), /*exclamationToken*/ undefined, /*type*/ undefined, possiblyAwaitedExpression)], NodeFlags.Const)))); } } } @@ -481,8 +482,8 @@ namespace ts.codefix { // if block has no return statement, need to define prevArgName as undefined to prevent undeclared variables if (!seenReturnStatement && prevArgName !== undefined) { - ret.push(createVariableStatement(/*modifiers*/ undefined, - (createVariableDeclarationList([createVariableDeclaration(getNode(prevArgName), /*type*/ undefined, createIdentifier("undefined"))], NodeFlags.Const)))); + ret.push(factory.createVariableStatement(/*modifiers*/ undefined, + (factory.createVariableDeclarationList([factory.createVariableDeclaration(getNode(prevArgName), /*exclamationToken*/ undefined, /*type*/ undefined, factory.createIdentifier("undefined"))], NodeFlags.Const)))); } return ret; diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index 3880f85bad08e..56648e7434856 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -31,7 +31,7 @@ namespace ts.codefix { break; case SyntaxKind.CallExpression: if (isRequireCall(importNode, /*checkArgumentIsStringLiteralLike*/ false)) { - changes.replaceNode(importingFile, importNode, createPropertyAccess(getSynthesizedDeepClone(importNode), "default")); + changes.replaceNode(importingFile, importNode, factory.createPropertyAccessExpression(getSynthesizedDeepClone(importNode), "default")); } break; } @@ -81,7 +81,7 @@ namespace ts.codefix { return; } const { text } = node.name; - changes.replaceNode(sourceFile, node, createIdentifier(exports.get(text) || text)); + changes.replaceNode(sourceFile, node, factory.createIdentifier(exports.get(text) || text)); }); } @@ -154,7 +154,7 @@ namespace ts.codefix { } } // Move it out to its own variable statement. (This will not be used if `!foundImport`) - return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags)); + return factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([decl], declarationList.flags)); }); if (foundImport) { // useNonAdjustedEndPosition to ensure we don't eat the newline after the statement. @@ -171,7 +171,7 @@ namespace ts.codefix { const tmp = makeUniqueName(propertyName, identifiers); return [ makeSingleImport(tmp, propertyName, moduleSpecifier, quotePreference), - makeConst(/*modifiers*/ undefined, name, createIdentifier(tmp)), + makeConst(/*modifiers*/ undefined, name, factory.createIdentifier(tmp)), ]; } case SyntaxKind.Identifier: @@ -237,7 +237,7 @@ namespace ts.codefix { case SyntaxKind.PropertyAssignment: return !isIdentifier(prop.name) ? undefined : convertExportsDotXEquals_replaceNode(prop.name.text, prop.initializer); case SyntaxKind.MethodDeclaration: - return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [createToken(SyntaxKind.ExportKeyword)], prop); + return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [factory.createToken(SyntaxKind.ExportKeyword)], prop); default: Debug.assertNever(prop, `Convert to ES6 got invalid prop kind ${(prop as ObjectLiteralElementLike).kind}`); } @@ -261,7 +261,7 @@ namespace ts.codefix { */ const newNodes = [ makeConst(/*modifiers*/ undefined, rename, assignment.right), - makeExportDeclaration([createExportSpecifier(rename, text)]), + makeExportDeclaration([factory.createExportSpecifier(rename, text)]), ]; changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes); } @@ -284,14 +284,14 @@ namespace ts.codefix { return makeExportDeclaration(/*exportClause*/ undefined, moduleSpecifier); } function reExportDefault(moduleSpecifier: string): ExportDeclaration { - return makeExportDeclaration([createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier); + return makeExportDeclaration([factory.createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier); } function convertExportsPropertyAssignment({ left, right, parent }: BinaryExpression & { left: PropertyAccessExpression }, sourceFile: SourceFile, changes: textChanges.ChangeTracker): void { const name = left.name.text; if ((isFunctionExpression(right) || isArrowFunction(right) || isClassExpression(right)) && (!right.name || right.name.text === name)) { // `exports.f = function() {}` -> `export function f() {}` -- Replace `exports.f = ` with `export `, and insert the name after `function`. - changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, createToken(SyntaxKind.ExportKeyword), { suffix: " " }); + changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, factory.createToken(SyntaxKind.ExportKeyword), { suffix: " " }); if (!right.name) changes.insertName(sourceFile, right, name); @@ -301,14 +301,14 @@ namespace ts.codefix { else { // `exports.f = function g() {}` -> `export const f = function g() {}` -- just replace `exports.` with `export const ` changes.replaceNodeRangeWithNodes(sourceFile, left.expression, findChildOfKind(left, SyntaxKind.DotToken, sourceFile)!, - [createToken(SyntaxKind.ExportKeyword), createToken(SyntaxKind.ConstKeyword)], + [factory.createToken(SyntaxKind.ExportKeyword), factory.createToken(SyntaxKind.ConstKeyword)], { joiner: " ", suffix: " " }); } } // TODO: GH#22492 this will cause an error if a change has been made inside the body of the node. function convertExportsDotXEquals_replaceNode(name: string | undefined, exported: Expression): Statement { - const modifiers = [createToken(SyntaxKind.ExportKeyword)]; + const modifiers = [factory.createToken(SyntaxKind.ExportKeyword)]; switch (exported.kind) { case SyntaxKind.FunctionExpression: { const { name: expressionName } = exported as FunctionExpression; @@ -331,7 +331,7 @@ namespace ts.codefix { function exportConst() { // `exports.x = 0;` --> `export const x = 0;` - return makeConst(modifiers, createIdentifier(name!), exported); // TODO: GH#18217 + return makeConst(modifiers, factory.createIdentifier(name!), exported); // TODO: GH#18217 } } @@ -370,8 +370,8 @@ namespace ts.codefix { */ const tmp = makeUniqueName(moduleSpecifierToValidIdentifier(moduleSpecifier.text, target), identifiers); return [ - makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, quotePreference), - makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), createIdentifier(tmp)), + makeImport(factory.createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, quotePreference), + makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), factory.createIdentifier(tmp)), ]; } case SyntaxKind.Identifier: @@ -407,7 +407,7 @@ namespace ts.codefix { idName = makeUniqueName(propertyName, identifiers); namedBindingsNames.set(propertyName, idName); } - changes.replaceNode(file, parent, createIdentifier(idName)); + changes.replaceNode(file, parent, factory.createIdentifier(idName)); } else { needDefaultImport = true; @@ -415,7 +415,7 @@ namespace ts.codefix { } const namedBindings = namedBindingsNames.size === 0 ? undefined : arrayFrom(mapIterator(namedBindingsNames.entries(), ([propertyName, idName]) => - createImportSpecifier(propertyName === idName ? undefined : createIdentifier(propertyName), createIdentifier(idName)))); + factory.createImportSpecifier(propertyName === idName ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(idName)))); if (!namedBindings) { // If it was unused, ensure that we at least import *something*. needDefaultImport = true; @@ -477,7 +477,7 @@ namespace ts.codefix { // Node helpers function functionExpressionToDeclaration(name: string | undefined, additionalModifiers: readonly Modifier[], fn: FunctionExpression | ArrowFunction | MethodDeclaration): FunctionDeclaration { - return createFunctionDeclaration( + return factory.createFunctionDeclaration( getSynthesizedDeepClones(fn.decorators), // TODO: GH#19915 Don't think this is even legal. concatenate(additionalModifiers, getSynthesizedDeepClones(fn.modifiers)), getSynthesizedDeepClone(fn.asteriskToken), @@ -485,11 +485,11 @@ namespace ts.codefix { getSynthesizedDeepClones(fn.typeParameters), getSynthesizedDeepClones(fn.parameters), getSynthesizedDeepClone(fn.type), - convertToFunctionBody(getSynthesizedDeepClone(fn.body!))); + factory.converters.convertToFunctionBlock(getSynthesizedDeepClone(fn.body!))); } function classExpressionToDeclaration(name: string | undefined, additionalModifiers: readonly Modifier[], cls: ClassExpression): ClassDeclaration { - return createClassDeclaration( + return factory.createClassDeclaration( getSynthesizedDeepClones(cls.decorators), // TODO: GH#19915 Don't think this is even legal. concatenate(additionalModifiers, getSynthesizedDeepClones(cls.modifiers)), name, @@ -500,27 +500,28 @@ namespace ts.codefix { function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: StringLiteralLike, quotePreference: QuotePreference): ImportDeclaration { return propertyName === "default" - ? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, quotePreference) + ? makeImport(factory.createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, quotePreference) : makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier, quotePreference); } function makeImportSpecifier(propertyName: string | undefined, name: string): ImportSpecifier { - return createImportSpecifier(propertyName !== undefined && propertyName !== name ? createIdentifier(propertyName) : undefined, createIdentifier(name)); + return factory.createImportSpecifier(propertyName !== undefined && propertyName !== name ? factory.createIdentifier(propertyName) : undefined, factory.createIdentifier(name)); } function makeConst(modifiers: readonly Modifier[] | undefined, name: string | BindingName, init: Expression): VariableStatement { - return createVariableStatement( + return factory.createVariableStatement( modifiers, - createVariableDeclarationList( - [createVariableDeclaration(name, /*type*/ undefined, init)], + factory.createVariableDeclarationList( + [factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, /*type*/ undefined, init)], NodeFlags.Const)); } function makeExportDeclaration(exportSpecifiers: ExportSpecifier[] | undefined, moduleSpecifier?: string): ExportDeclaration { - return createExportDeclaration( + return factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - exportSpecifiers && createNamedExports(exportSpecifiers), - moduleSpecifier === undefined ? undefined : createLiteral(moduleSpecifier)); + /*isTypeOnly*/ false, + exportSpecifiers && factory.createNamedExports(exportSpecifiers), + moduleSpecifier === undefined ? undefined : factory.createStringLiteral(moduleSpecifier)); } } diff --git a/src/services/codefixes/convertToMappedObjectType.ts b/src/services/codefixes/convertToMappedObjectType.ts index 04de31faabf67..600ef5a1fd86c 100644 --- a/src/services/codefixes/convertToMappedObjectType.ts +++ b/src/services/codefixes/convertToMappedObjectType.ts @@ -33,23 +33,23 @@ namespace ts.codefix { } function createTypeAliasFromInterface(declaration: FixableDeclaration, type: TypeNode): TypeAliasDeclaration { - return createTypeAliasDeclaration(declaration.decorators, declaration.modifiers, declaration.name, declaration.typeParameters, type); + return factory.createTypeAliasDeclaration(declaration.decorators, declaration.modifiers, declaration.name, declaration.typeParameters, type); } function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { indexSignature, container }: Info): void { const members = isInterfaceDeclaration(container) ? container.members : (container.type).members; const otherMembers = members.filter(member => !isIndexSignatureDeclaration(member)); const parameter = first(indexSignature.parameters); - const mappedTypeParameter = createTypeParameterDeclaration(cast(parameter.name, isIdentifier), parameter.type); - const mappedIntersectionType = createMappedTypeNode( - hasEffectiveReadonlyModifier(indexSignature) ? createModifier(SyntaxKind.ReadonlyKeyword) : undefined, + const mappedTypeParameter = factory.createTypeParameterDeclaration(cast(parameter.name, isIdentifier), parameter.type); + const mappedIntersectionType = factory.createMappedTypeNode( + hasEffectiveReadonlyModifier(indexSignature) ? factory.createModifier(SyntaxKind.ReadonlyKeyword) : undefined, mappedTypeParameter, indexSignature.questionToken, indexSignature.type); - const intersectionType = createIntersectionTypeNode([ + const intersectionType = factory.createIntersectionTypeNode([ ...getAllSuperTypeNodes(container), mappedIntersectionType, - ...(otherMembers.length ? [createTypeLiteralNode(otherMembers)] : emptyArray), + ...(otherMembers.length ? [factory.createTypeLiteralNode(otherMembers)] : emptyArray), ]); changes.replaceNode(sourceFile, container, createTypeAliasFromInterface(container, intersectionType)); } diff --git a/src/services/codefixes/convertToTypeOnlyExport.ts b/src/services/codefixes/convertToTypeOnlyExport.ts index 7adf4d1aacd67..35510249927a9 100644 --- a/src/services/codefixes/convertToTypeOnlyExport.ts +++ b/src/services/codefixes/convertToTypeOnlyExport.ts @@ -38,28 +38,28 @@ namespace ts.codefix { changes.replaceNode( context.sourceFile, exportDeclaration, - updateExportDeclaration( + factory.updateExportDeclaration( exportDeclaration, exportDeclaration.decorators, exportDeclaration.modifiers, + /*isTypeOnly*/ true, exportClause, - exportDeclaration.moduleSpecifier, - /*isTypeOnly*/ true)); + exportDeclaration.moduleSpecifier)); } else { - const valueExportDeclaration = updateExportDeclaration( + const valueExportDeclaration = factory.updateExportDeclaration( exportDeclaration, exportDeclaration.decorators, exportDeclaration.modifiers, - updateNamedExports(exportClause, filter(exportClause.elements, e => !contains(typeExportSpecifiers, e))), - exportDeclaration.moduleSpecifier, - /*isTypeOnly*/ false); - const typeExportDeclaration = createExportDeclaration( + /*isTypeOnly*/ false, + factory.updateNamedExports(exportClause, filter(exportClause.elements, e => !contains(typeExportSpecifiers, e))), + exportDeclaration.moduleSpecifier); + const typeExportDeclaration = factory.createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createNamedExports(typeExportSpecifiers), - exportDeclaration.moduleSpecifier, - /*isTypeOnly*/ true); + /*isTypeOnly*/ true, + factory.createNamedExports(typeExportSpecifiers), + exportDeclaration.moduleSpecifier); changes.replaceNode(context.sourceFile, exportDeclaration, valueExportDeclaration); changes.insertNodeAfter(context.sourceFile, exportDeclaration, typeExportDeclaration); diff --git a/src/services/codefixes/convertToTypeOnlyImport.ts b/src/services/codefixes/convertToTypeOnlyImport.ts index d434e1ffd3a1c..7079ee8d2ba22 100644 --- a/src/services/codefixes/convertToTypeOnlyImport.ts +++ b/src/services/codefixes/convertToTypeOnlyImport.ts @@ -38,14 +38,14 @@ namespace ts.codefix { // `import type foo, { Bar }` is not allowed, so move `foo` to new declaration if (importClause.name && importClause.namedBindings) { changes.deleteNodeRangeExcludingEnd(context.sourceFile, importClause.name, importDeclaration.importClause.namedBindings); - changes.insertNodeBefore(context.sourceFile, importDeclaration, updateImportDeclaration( + changes.insertNodeBefore(context.sourceFile, importDeclaration, factory.updateImportDeclaration( importDeclaration, /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause( + factory.createImportClause( + /*isTypeOnly*/ true, importClause.name, - /*namedBindings*/ undefined, - /*isTypeOnly*/ true), + /*namedBindings*/ undefined), importDeclaration.moduleSpecifier)); } } diff --git a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts index 02ccbfd1d64cc..d2462546c6220 100644 --- a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts +++ b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts @@ -28,9 +28,9 @@ namespace ts.codefix { function doChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, qualifiedName: QualifiedName): void { const rightText = qualifiedName.right.text; - const replacement = createIndexedAccessTypeNode( - createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined), - createLiteralTypeNode(createLiteral(rightText))); + const replacement = factory.createIndexedAccessTypeNode( + factory.createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined), + factory.createLiteralTypeNode(factory.createStringLiteral(rightText))); changeTracker.replaceNode(sourceFile, qualifiedName, replacement); } } diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index f39234cdf17d7..9d48f054226b9 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -167,11 +167,11 @@ namespace ts.codefix { return; } const className = classDeclaration.name!.getText(); - const staticInitialization = initializePropertyToUndefined(createIdentifier(className), tokenName); + const staticInitialization = initializePropertyToUndefined(factory.createIdentifier(className), tokenName); changeTracker.insertNodeAfter(declSourceFile, classDeclaration, staticInitialization); } else if (isPrivateIdentifier(token)) { - const property = createProperty( + const property = factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, tokenName, @@ -192,13 +192,13 @@ namespace ts.codefix { if (!classConstructor) { return; } - const propertyInitialization = initializePropertyToUndefined(createThis(), tokenName); + const propertyInitialization = initializePropertyToUndefined(factory.createThis(), tokenName); changeTracker.insertNodeAtConstructorEnd(declSourceFile, classConstructor, propertyInitialization); } } function initializePropertyToUndefined(obj: Expression, propertyName: string) { - return createStatement(createAssignment(createPropertyAccess(obj, propertyName), createIdentifier("undefined"))); + return factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(obj, propertyName), factory.createIdentifier("undefined"))); } function createActionsForAddMissingMemberInTypeScriptFile(context: CodeFixContext, { parentDeclaration, declSourceFile, modifierFlags, token }: ClassOrInterfaceInfo): CodeFixAction[] | undefined { @@ -232,13 +232,13 @@ namespace ts.codefix { const contextualType = checker.getContextualType(token.parent as Expression); typeNode = contextualType ? checker.typeToTypeNode(contextualType, /*enclosingDeclaration*/ undefined, /*flags*/ undefined) : undefined; } - return typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword); + return typeNode || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } function addPropertyDeclaration(changeTracker: textChanges.ChangeTracker, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, tokenName: string, typeNode: TypeNode, modifierFlags: ModifierFlags): void { - const property = createProperty( + const property = factory.createPropertyDeclaration( /*decorators*/ undefined, - /*modifiers*/ modifierFlags ? createNodeArray(createModifiersFromModifierFlags(modifierFlags)) : undefined, + /*modifiers*/ modifierFlags ? factory.createNodeArray(factory.createModifiersFromModifierFlags(modifierFlags)) : undefined, tokenName, /*questionToken*/ undefined, typeNode, @@ -265,8 +265,8 @@ namespace ts.codefix { function createAddIndexSignatureAction(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, tokenName: string, typeNode: TypeNode): CodeFixAction { // Index signatures cannot have the static modifier. - const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword); - const indexingParameter = createParameter( + const stringTypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword); + const indexingParameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -274,7 +274,7 @@ namespace ts.codefix { /*questionToken*/ undefined, stringTypeNode, /*initializer*/ undefined); - const indexSignature = createIndexSignature( + const indexSignature = factory.createIndexSignature( /*decorators*/ undefined, /*modifiers*/ undefined, [indexingParameter], @@ -338,8 +338,8 @@ namespace ts.codefix { return !!(type && type.flags & TypeFlags.StringLike); }); - const enumMember = createEnumMember(token, hasStringInitializer ? createStringLiteral(token.text) : undefined); - changes.replaceNode(enumDeclaration.getSourceFile(), enumDeclaration, updateEnumDeclaration( + const enumMember = factory.createEnumMember(token, hasStringInitializer ? factory.createStringLiteral(token.text) : undefined); + changes.replaceNode(enumDeclaration.getSourceFile(), enumDeclaration, factory.updateEnumDeclaration( enumDeclaration, enumDeclaration.decorators, enumDeclaration.modifiers, diff --git a/src/services/codefixes/fixAddMissingNewOperator.ts b/src/services/codefixes/fixAddMissingNewOperator.ts index 5acaf6eb82ede..cd8eb9c8c212c 100644 --- a/src/services/codefixes/fixAddMissingNewOperator.ts +++ b/src/services/codefixes/fixAddMissingNewOperator.ts @@ -16,7 +16,7 @@ namespace ts.codefix { function addMissingNewOperator(changes: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan): void { const call = cast(findAncestorMatchingSpan(sourceFile, span), isCallExpression); - const newExpression = createNew(call.expression, call.typeArguments, call.arguments); + const newExpression = factory.createNewExpression(call.expression, call.typeArguments, call.arguments); changes.replaceNode(sourceFile, call, newExpression); } diff --git a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts index b5d107398d837..e90bbad826861 100644 --- a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts +++ b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts @@ -25,7 +25,7 @@ namespace ts.codefix { } function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importType: ImportTypeNode) { - const newTypeNode = updateImportTypeNode(importType, importType.argument, importType.qualifier, importType.typeArguments, /* isTypeOf */ true); + const newTypeNode = factory.updateImportTypeNode(importType, importType.argument, importType.qualifier, importType.typeArguments, /* isTypeOf */ true); changes.replaceNode(sourceFile, importType, newTypeNode); } } diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index 7f9cfd8731511..f09b204de64b7 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -73,7 +73,7 @@ namespace ts.codefix { if (returnType) { const entityName = getEntityNameFromTypeNode(returnType); if (!entityName || entityName.kind !== SyntaxKind.Identifier || entityName.text !== "Promise") { - changes.replaceNode(sourceFile, returnType, createTypeReferenceNode("Promise", createNodeArray([returnType]))); + changes.replaceNode(sourceFile, returnType, factory.createTypeReferenceNode("Promise", factory.createNodeArray([returnType]))); } } changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, insertBefore); diff --git a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts index d8e58fcbe7a0d..b7941259ede90 100644 --- a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts +++ b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts @@ -22,7 +22,7 @@ namespace ts.codefix { } function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, ctr: ConstructorDeclaration) { - const superCall = createStatement(createCall(createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray)); + const superCall = factory.createExpressionStatement(factory.createCallExpression(factory.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray)); changes.insertNodeAtConstructorStart(sourceFile, ctr, superCall); } } diff --git a/src/services/codefixes/fixEnableExperimentalDecorators.ts b/src/services/codefixes/fixEnableExperimentalDecorators.ts index 8c8f6726b4392..13ff16945a477 100644 --- a/src/services/codefixes/fixEnableExperimentalDecorators.ts +++ b/src/services/codefixes/fixEnableExperimentalDecorators.ts @@ -26,6 +26,6 @@ namespace ts.codefix { }); function doChange(changeTracker: textChanges.ChangeTracker, configFile: TsConfigSourceFile) { - setJsonCompilerOptionValue(changeTracker, configFile, "experimentalDecorators", createTrue()); + setJsonCompilerOptionValue(changeTracker, configFile, "experimentalDecorators", factory.createTrue()); } } diff --git a/src/services/codefixes/fixEnableJsxFlag.ts b/src/services/codefixes/fixEnableJsxFlag.ts index d108505264623..f077880bc3c42 100644 --- a/src/services/codefixes/fixEnableJsxFlag.ts +++ b/src/services/codefixes/fixEnableJsxFlag.ts @@ -30,6 +30,6 @@ namespace ts.codefix { }); function doChange(changeTracker: textChanges.ChangeTracker, configFile: TsConfigSourceFile) { - setJsonCompilerOptionValue(changeTracker, configFile, "jsx", createStringLiteral("react")); + setJsonCompilerOptionValue(changeTracker, configFile, "jsx", factory.createStringLiteral("react")); } } diff --git a/src/services/codefixes/fixExpectedComma.ts b/src/services/codefixes/fixExpectedComma.ts index ffe0e2625352e..89aa32d8f4287 100644 --- a/src/services/codefixes/fixExpectedComma.ts +++ b/src/services/codefixes/fixExpectedComma.ts @@ -40,7 +40,7 @@ namespace ts.codefix { } function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { node }: Info): void { - const newNode = createNode(SyntaxKind.CommaToken); + const newNode = factory.createToken(SyntaxKind.CommaToken); changes.replaceNode(sourceFile, node, newNode); } } diff --git a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts index 1e2af29f63ed1..f8621e1f93d6f 100644 --- a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts +++ b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts @@ -27,7 +27,7 @@ namespace ts.codefix { } function doChanges(changes: textChanges.ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: readonly HeritageClause[]): void { - changes.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword)); + changes.replaceNode(sourceFile, extendsToken, factory.createToken(SyntaxKind.ImplementsKeyword)); // If there is already an implements clause, replace the implements keyword with a comma. if (heritageClauses.length === 2 && @@ -36,7 +36,7 @@ namespace ts.codefix { const implementsToken = heritageClauses[1].getFirstToken()!; const implementsFullStart = implementsToken.getFullStart(); - changes.replaceRange(sourceFile, { pos: implementsFullStart, end: implementsFullStart }, createToken(SyntaxKind.CommaToken)); + changes.replaceRange(sourceFile, { pos: implementsFullStart, end: implementsFullStart }, factory.createToken(SyntaxKind.CommaToken)); // Rough heuristic: delete trailing whitespace after keyword so that it's not excessive. // (Trailing because leading might be indentation, which is more sensitive.) diff --git a/src/services/codefixes/fixForgottenThisPropertyAccess.ts b/src/services/codefixes/fixForgottenThisPropertyAccess.ts index 7254ccc6d3139..067ce4b0b9e26 100644 --- a/src/services/codefixes/fixForgottenThisPropertyAccess.ts +++ b/src/services/codefixes/fixForgottenThisPropertyAccess.ts @@ -40,6 +40,6 @@ namespace ts.codefix { function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { node, className }: Info): void { // TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper suppressLeadingAndTrailingTrivia(node); - changes.replaceNode(sourceFile, node, createPropertyAccess(className ? createIdentifier(className) : createThis(), node)); + changes.replaceNode(sourceFile, node, factory.createPropertyAccessExpression(className ? factory.createIdentifier(className) : factory.createThis(), node)); } } diff --git a/src/services/codefixes/fixImplicitThis.ts b/src/services/codefixes/fixImplicitThis.ts index 891ebc319c813..bfff6fe21f10a 100644 --- a/src/services/codefixes/fixImplicitThis.ts +++ b/src/services/codefixes/fixImplicitThis.ts @@ -46,7 +46,7 @@ namespace ts.codefix { else { // `function f() {}` => `const f = () => {}` // `name` should be defined because we only do this in inner contexts, and name is only undefined for `export default function() {}`. - changes.replaceNode(sourceFile, fnKeyword, createToken(SyntaxKind.ConstKeyword)); + changes.replaceNode(sourceFile, fnKeyword, factory.createToken(SyntaxKind.ConstKeyword)); changes.insertText(sourceFile, name!.end, " = "); changes.insertText(sourceFile, body.pos, " =>"); return [Diagnostics.Convert_function_declaration_0_to_arrow_function, name!.text]; @@ -54,7 +54,7 @@ namespace ts.codefix { } // No outer 'this', add a @class tag if in a JS constructor function else if (isSourceFileJS(sourceFile) && isPropertyAccessExpression(token.parent) && isAssignmentExpression(token.parent.parent)) { - addJSDocTags(changes, sourceFile, fn, [createJSDocClassTag()]); + addJSDocTags(changes, sourceFile, fn, [factory.createJSDocClassTag(/*tagName*/ undefined)]); return Diagnostics.Add_class_tag; } } diff --git a/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts b/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts index f1c3d35160625..a806e19f654c2 100644 --- a/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts +++ b/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts @@ -37,11 +37,11 @@ namespace ts.codefix { } unwrappedType = (unwrappedType as OptionalTypeNode | RestTypeNode | ParenthesizedTypeNode).type; } - const updated = updateNamedTupleMember( + const updated = factory.updateNamedTupleMember( namedTupleMember, - namedTupleMember.dotDotDotToken || (sawRest ? createToken(SyntaxKind.DotDotDotToken) : undefined), + namedTupleMember.dotDotDotToken || (sawRest ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined), namedTupleMember.name, - namedTupleMember.questionToken || (sawOptional ? createToken(SyntaxKind.QuestionToken) : undefined), + namedTupleMember.questionToken || (sawOptional ? factory.createToken(SyntaxKind.QuestionToken) : undefined), unwrappedType ); if (updated === namedTupleMember) { diff --git a/src/services/codefixes/fixInvalidImportSyntax.ts b/src/services/codefixes/fixInvalidImportSyntax.ts index 5893a1e5e74a3..acc033df36fc7 100644 --- a/src/services/codefixes/fixInvalidImportSyntax.ts +++ b/src/services/codefixes/fixInvalidImportSyntax.ts @@ -13,11 +13,11 @@ namespace ts.codefix { if (getEmitModuleKind(opts) === ModuleKind.CommonJS) { // import Bluebird = require("bluebird"); - variations.push(createAction(context, sourceFile, node, createImportEqualsDeclaration( + variations.push(createAction(context, sourceFile, node, factory.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, namespace.name, - createExternalModuleReference(node.moduleSpecifier) + factory.createExternalModuleReference(node.moduleSpecifier) ))); } @@ -88,7 +88,7 @@ namespace ts.codefix { } if (isExpression(expr) && !(isNamedDeclaration(expr.parent) && expr.parent.name === expr)) { const sourceFile = context.sourceFile; - const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, expr, createPropertyAccess(expr, "default"), {})); + const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, expr, factory.createPropertyAccessExpression(expr, "default"), {})); fixes.push(createCodeFixActionWithoutFixAll(fixName, changes, Diagnostics.Use_synthetic_default_member)); } return fixes; diff --git a/src/services/codefixes/fixModuleAndTargetOptions.ts b/src/services/codefixes/fixModuleAndTargetOptions.ts index fe3eaebae9597..fce565814836a 100644 --- a/src/services/codefixes/fixModuleAndTargetOptions.ts +++ b/src/services/codefixes/fixModuleAndTargetOptions.ts @@ -14,7 +14,7 @@ namespace ts.codefix { const moduleOutOfRange = moduleKind >= ModuleKind.ES2015 && moduleKind < ModuleKind.ESNext; if (moduleOutOfRange) { const changes = textChanges.ChangeTracker.with(context, changes => { - setJsonCompilerOptionValue(changes, configFile, "module", createStringLiteral("esnext")); + setJsonCompilerOptionValue(changes, configFile, "module", factory.createStringLiteral("esnext")); }); codeFixes.push(createCodeFixActionWithoutFixAll("fixModuleOption", changes, [Diagnostics.Set_the_module_option_in_your_configuration_file_to_0, "esnext"])); } @@ -26,10 +26,10 @@ namespace ts.codefix { const configObject = getTsConfigObjectLiteralExpression(configFile); if (!configObject) return; - const options: [string, Expression][] = [["target", createStringLiteral("es2017")]]; + const options: [string, Expression][] = [["target", factory.createStringLiteral("es2017")]]; if (moduleKind === ModuleKind.CommonJS) { // Ensure we preserve the default module kind (commonjs), as targets >= ES2015 have a default module kind of es2015. - options.push(["module", createStringLiteral("commonjs")]); + options.push(["module", factory.createStringLiteral("commonjs")]); } setJsonCompilerOptionValues(tracker, configFile, options); diff --git a/src/services/codefixes/fixReturnTypeInAsyncFunction.ts b/src/services/codefixes/fixReturnTypeInAsyncFunction.ts index 4bb9162b32ffb..6d27b8030d574 100644 --- a/src/services/codefixes/fixReturnTypeInAsyncFunction.ts +++ b/src/services/codefixes/fixReturnTypeInAsyncFunction.ts @@ -59,6 +59,6 @@ namespace ts.codefix { } function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, returnTypeNode: TypeNode, promisedTypeNode: TypeNode): void { - changes.replaceNode(sourceFile, returnTypeNode, createTypeReferenceNode("Promise", [promisedTypeNode])); + changes.replaceNode(sourceFile, returnTypeNode, factory.createTypeReferenceNode("Promise", [promisedTypeNode])); } } diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index 05ed9424b740d..b90c16c390826 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -67,14 +67,14 @@ namespace ts.codefix { if (!isIdentifierText(suggestion, target) && isPropertyAccessExpression(node.parent)) { const valDecl = suggestedSymbol.valueDeclaration; if (isNamedDeclaration(valDecl) && isPrivateIdentifier(valDecl.name)) { - changes.replaceNode(sourceFile, node, createIdentifier(suggestion)); + changes.replaceNode(sourceFile, node, factory.createIdentifier(suggestion)); } else { - changes.replaceNode(sourceFile, node.parent, createElementAccess(node.parent.expression, createLiteral(suggestion))); + changes.replaceNode(sourceFile, node.parent, factory.createElementAccessExpression(node.parent.expression, factory.createStringLiteral(suggestion))); } } else { - changes.replaceNode(sourceFile, node, createIdentifier(suggestion)); + changes.replaceNode(sourceFile, node, factory.createIdentifier(suggestion)); } } diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts index a4b0134853a30..37cb7ffa74224 100644 --- a/src/services/codefixes/fixStrictClassInitialization.ts +++ b/src/services/codefixes/fixStrictClassInitialization.ts @@ -58,12 +58,12 @@ namespace ts.codefix { } function addDefiniteAssignmentAssertion(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void { - const property = updateProperty( + const property = factory.updatePropertyDeclaration( propertyDeclaration, propertyDeclaration.decorators, propertyDeclaration.modifiers, propertyDeclaration.name, - createToken(SyntaxKind.ExclamationToken), + factory.createToken(SyntaxKind.ExclamationToken), propertyDeclaration.type, propertyDeclaration.initializer ); @@ -76,10 +76,10 @@ namespace ts.codefix { } function addUndefinedType(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void { - const undefinedTypeNode = createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + const undefinedTypeNode = factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword); const type = propertyDeclaration.type!; // TODO: GH#18217 const types = isUnionTypeNode(type) ? type.types.concat(undefinedTypeNode) : [type, undefinedTypeNode]; - changeTracker.replaceNode(propertyDeclarationSourceFile, type, createUnionTypeNode(types)); + changeTracker.replaceNode(propertyDeclarationSourceFile, type, factory.createUnionTypeNode(types)); } function getActionForAddMissingInitializer(context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction | undefined { @@ -92,7 +92,7 @@ namespace ts.codefix { } function addInitializer(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration, initializer: Expression): void { - const property = updateProperty( + const property = factory.updatePropertyDeclaration( propertyDeclaration, propertyDeclaration.decorators, propertyDeclaration.modifiers, @@ -110,10 +110,16 @@ namespace ts.codefix { function getDefaultValueFromType(checker: TypeChecker, type: Type): Expression | undefined { if (type.flags & TypeFlags.BooleanLiteral) { - return (type === checker.getFalseType() || type === checker.getFalseType(/*fresh*/ true)) ? createFalse() : createTrue(); + return (type === checker.getFalseType() || type === checker.getFalseType(/*fresh*/ true)) ? factory.createFalse() : factory.createTrue(); } - else if (type.isLiteral()) { - return createLiteral(type.value); + else if (type.isStringLiteral()) { + return factory.createStringLiteral(type.value); + } + else if (type.isNumberLiteral()) { + return factory.createNumericLiteral(type.value); + } + else if (type.flags & TypeFlags.BigIntLiteral) { + return factory.createBigIntLiteral((type as BigIntLiteralType).value); } else if (type.isUnion()) { return firstDefined(type.types, t => getDefaultValueFromType(checker, t)); @@ -125,10 +131,10 @@ namespace ts.codefix { const constructorDeclaration = getFirstConstructorWithBody(classDeclaration); if (constructorDeclaration && constructorDeclaration.parameters.length) return undefined; - return createNew(createIdentifier(type.symbol.name), /*typeArguments*/ undefined, /*argumentsArray*/ undefined); + return factory.createNewExpression(factory.createIdentifier(type.symbol.name), /*typeArguments*/ undefined, /*argumentsArray*/ undefined); } else if (checker.isArrayLikeType(type)) { - return createArrayLiteral(); + return factory.createArrayLiteralExpression(); } return undefined; } diff --git a/src/services/codefixes/fixUnreachableCode.ts b/src/services/codefixes/fixUnreachableCode.ts index 2603345b27675..d4d53c4d27f95 100644 --- a/src/services/codefixes/fixUnreachableCode.ts +++ b/src/services/codefixes/fixUnreachableCode.ts @@ -35,7 +35,7 @@ namespace ts.codefix { break; } else { - changes.replaceNode(sourceFile, statement, createBlock(emptyArray)); + changes.replaceNode(sourceFile, statement, factory.createBlock(emptyArray)); } return; } diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index 7644c8df269d0..4aa099cb379f5 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -109,7 +109,7 @@ namespace ts.codefix { }); function changeInferToUnknown(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node): void { - changes.replaceNode(sourceFile, token.parent, createKeywordTypeNode(SyntaxKind.UnknownKeyword)); + changes.replaceNode(sourceFile, token.parent, factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword)); } function createDeleteFix(changes: FileTextChanges[], diag: DiagnosticAndArguments): CodeFixAction { @@ -153,11 +153,11 @@ namespace ts.codefix { token = cast(token.parent, isInferTypeNode).typeParameter.name; } if (isIdentifier(token) && canPrefix(token)) { - changes.replaceNode(sourceFile, token, createIdentifier(`_${token.text}`)); + changes.replaceNode(sourceFile, token, factory.createIdentifier(`_${token.text}`)); if (isParameter(token.parent)) { getJSDocParameterTags(token.parent).forEach((tag) => { if (isIdentifier(tag.name)) { - changes.replaceNode(sourceFile, tag.name, createIdentifier(`_${tag.name.text}`)); + changes.replaceNode(sourceFile, tag.name, factory.createIdentifier(`_${tag.name.text}`)); } }); } diff --git a/src/services/codefixes/generateAccessors.ts b/src/services/codefixes/generateAccessors.ts index 3c9e82e157cbb..75e3c9b9d24b2 100644 --- a/src/services/codefixes/generateAccessors.ts +++ b/src/services/codefixes/generateAccessors.ts @@ -74,16 +74,16 @@ namespace ts.codefix { } function createPropertyName(name: string, originalName: AcceptedNameType) { - return isIdentifier(originalName) ? createIdentifier(name) : createLiteral(name); + return isIdentifier(originalName) ? factory.createIdentifier(name) : factory.createStringLiteral(name); } function createAccessorAccessExpression(fieldName: AcceptedNameType, isStatic: boolean, container: ContainerDeclaration) { - const leftHead = isStatic ? (container).name! : createThis(); // TODO: GH#18217 - return isIdentifier(fieldName) ? createPropertyAccess(leftHead, fieldName) : createElementAccess(leftHead, createLiteral(fieldName)); + const leftHead = isStatic ? (container).name! : factory.createThis(); // TODO: GH#18217 + return isIdentifier(fieldName) ? factory.createPropertyAccessExpression(leftHead, fieldName) : factory.createElementAccessExpression(leftHead, factory.createStringLiteralFromNode(fieldName)); } function createModifiers(modifierFlags: ModifierFlags): ModifiersArray | undefined { - return modifierFlags ? createNodeArray(createModifiersFromModifierFlags(modifierFlags)) : undefined; + return modifierFlags ? factory.createNodeArray(factory.createModifiersFromModifierFlags(modifierFlags)) : undefined; } function prepareModifierFlagsForAccessor(modifierFlags: ModifierFlags): ModifierFlags { @@ -131,14 +131,14 @@ namespace ts.codefix { } function generateGetAccessor(fieldName: AcceptedNameType, accessorName: AcceptedNameType, type: TypeNode | undefined, modifiers: ModifiersArray | undefined, isStatic: boolean, container: ContainerDeclaration) { - return createGetAccessor( + return factory.createGetAccessorDeclaration( /*decorators*/ undefined, modifiers, accessorName, /*parameters*/ undefined!, // TODO: GH#18217 type, - createBlock([ - createReturn( + factory.createBlock([ + factory.createReturnStatement( createAccessorAccessExpression(fieldName, isStatic, container) ) ], /*multiLine*/ true) @@ -146,23 +146,23 @@ namespace ts.codefix { } function generateSetAccessor(fieldName: AcceptedNameType, accessorName: AcceptedNameType, type: TypeNode | undefined, modifiers: ModifiersArray | undefined, isStatic: boolean, container: ContainerDeclaration) { - return createSetAccessor( + return factory.createSetAccessorDeclaration( /*decorators*/ undefined, modifiers, accessorName, - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, - createIdentifier("value"), + factory.createIdentifier("value"), /*questionToken*/ undefined, type )], - createBlock([ - createStatement( - createAssignment( + factory.createBlock([ + factory.createExpressionStatement( + factory.createAssignment( createAccessorAccessExpression(fieldName, isStatic, container), - createIdentifier("value") + factory.createIdentifier("value") ) ) ], /*multiLine*/ true) @@ -170,7 +170,7 @@ namespace ts.codefix { } function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, fieldName: AcceptedNameType, modifiers: ModifiersArray | undefined) { - const property = updateProperty( + const property = factory.updatePropertyDeclaration( declaration, declaration.decorators, modifiers, @@ -183,7 +183,7 @@ namespace ts.codefix { } function updatePropertyAssignmentDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AcceptedNameType) { - const assignment = updatePropertyAssignment(declaration, fieldName, declaration.initializer); + const assignment = factory.updatePropertyAssignment(declaration, fieldName, declaration.initializer); changeTracker.replacePropertyAssignment(file, declaration, assignment); } @@ -196,7 +196,7 @@ namespace ts.codefix { } else { changeTracker.replaceNode(file, declaration, - updateParameter(declaration, declaration.decorators, modifiers, declaration.dotDotDotToken, cast(fieldName, isIdentifier), declaration.questionToken, declaration.type, declaration.initializer)); + factory.updateParameterDeclaration(declaration, declaration.decorators, modifiers, declaration.dotDotDotToken, cast(fieldName, isIdentifier), declaration.questionToken, declaration.type, declaration.initializer)); } } @@ -214,10 +214,10 @@ namespace ts.codefix { isStringLiteral(node.argumentExpression) && node.argumentExpression.text === originalName && isWriteAccess(node)) { - changeTracker.replaceNode(file, node.argumentExpression, createStringLiteral(fieldName)); + changeTracker.replaceNode(file, node.argumentExpression, factory.createStringLiteral(fieldName)); } if (isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword && node.name.text === originalName && isWriteAccess(node)) { - changeTracker.replaceNode(file, node.name, createIdentifier(fieldName)); + changeTracker.replaceNode(file, node.name, factory.createIdentifier(fieldName)); } if (!isFunctionLike(node) && !isClassLike(node)) { node.forEachChild(recur); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 7e879b96ba6d6..405a5db924bd6 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -41,7 +41,7 @@ namespace ts.codefix { const declaration = declarations[0]; const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName; const visibilityModifier = createVisibilityModifier(getEffectiveModifierFlags(declaration)); - const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined; + const modifiers = visibilityModifier ? factory.createNodeArray([visibilityModifier]) : undefined; const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); const optional = !!(symbol.flags & SymbolFlags.Optional); const ambient = !!(enclosingDeclaration.flags & NodeFlags.Ambient); @@ -58,11 +58,11 @@ namespace ts.codefix { importSymbols(importAdder, importableReference.symbols); } } - addClassElement(createProperty( - /*decorators*/undefined, + addClassElement(factory.createPropertyDeclaration( + /*decorators*/ undefined, modifiers, name, - optional ? createToken(SyntaxKind.QuestionToken) : undefined, + optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, typeNode, /*initializer*/ undefined)); break; @@ -82,7 +82,7 @@ namespace ts.codefix { } for (const accessor of orderedAccessors) { if (isGetAccessorDeclaration(accessor)) { - addClassElement(createGetAccessor( + addClassElement(factory.createGetAccessorDeclaration( /*decorators*/ undefined, modifiers, name, @@ -94,7 +94,7 @@ namespace ts.codefix { Debug.assertNode(accessor, isSetAccessorDeclaration, "The counterpart to a getter should be a setter"); const parameter = getSetAccessorValueParameter(accessor); const parameterName = parameter && isIdentifier(parameter.name) ? idText(parameter.name) : undefined; - addClassElement(createSetAccessor( + addClassElement(factory.createSetAccessorDeclaration( /*decorators*/ undefined, modifiers, name, @@ -167,49 +167,83 @@ namespace ts.codefix { return undefined; } + let typeParameters = signatureDeclaration.typeParameters; + let parameters = signatureDeclaration.parameters; + let type = signatureDeclaration.type; if (importAdder) { - if (signatureDeclaration.typeParameters) { - forEach(signatureDeclaration.typeParameters, (typeParameterDecl, i) => { + if (typeParameters) { + const newTypeParameters = sameMap(typeParameters, (typeParameterDecl, i) => { const typeParameter = signature.typeParameters![i]; - if (typeParameterDecl.constraint) { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeParameterDecl.constraint, typeParameter.constraint, scriptTarget); + let constraint = typeParameterDecl.constraint; + let defaultType = typeParameterDecl.default; + if (constraint) { + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(constraint, typeParameter.constraint, scriptTarget); if (importableReference) { - typeParameterDecl.constraint = importableReference.typeReference; + constraint = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); } } - if (typeParameterDecl.default) { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeParameterDecl.default, typeParameter.default, scriptTarget); + if (defaultType) { + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(defaultType, typeParameter.default, scriptTarget); if (importableReference) { - typeParameterDecl.default = importableReference.typeReference; + defaultType = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); } } + return factory.updateTypeParameterDeclaration( + typeParameterDecl, + typeParameterDecl.name, + constraint, + defaultType + ); }); + if (typeParameters !== newTypeParameters) { + typeParameters = setTextRange(factory.createNodeArray(newTypeParameters, typeParameters.hasTrailingComma), typeParameters); + } } - forEach(signatureDeclaration.parameters, (parameterDecl, i) => { + const newParameters = sameMap(parameters, (parameterDecl, i) => { const parameter = signature.parameters[i]; const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(parameterDecl.type, checker.getTypeAtLocation(parameter.valueDeclaration), scriptTarget); + let type = parameterDecl.type; if (importableReference) { - parameterDecl.type = importableReference.typeReference; + type = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); } + return factory.updateParameterDeclaration( + parameterDecl, + parameterDecl.decorators, + parameterDecl.modifiers, + parameterDecl.dotDotDotToken, + parameterDecl.name, + parameterDecl.questionToken, + type, + parameterDecl.initializer + ); }); - if (signatureDeclaration.type) { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(signatureDeclaration.type, signature.resolvedReturnType, scriptTarget); + if (parameters !== newParameters) { + parameters = setTextRange(factory.createNodeArray(newParameters, parameters.hasTrailingComma), parameters); + } + if (type) { + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(type, signature.resolvedReturnType, scriptTarget); if (importableReference) { - signatureDeclaration.type = importableReference.typeReference; + type = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); } } } - signatureDeclaration.decorators = undefined; - signatureDeclaration.modifiers = modifiers; - signatureDeclaration.name = name; - signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; - signatureDeclaration.body = body; - return signatureDeclaration; + return factory.updateMethodDeclaration( + signatureDeclaration, + /*decorators*/ undefined, + modifiers, + signatureDeclaration.asteriskToken, + name, + optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, + typeParameters, + parameters, + type, + body + ); } export function createMethodFromCallExpression( @@ -232,14 +266,14 @@ namespace ts.codefix { isIdentifier(arg) ? arg.text : isPropertyAccessExpression(arg) && isIdentifier(arg.name) ? arg.name.text : undefined); const contextualType = checker.getContextualType(call); const returnType = (inJs || !contextualType) ? undefined : checker.typeToTypeNode(contextualType, contextNode, /*flags*/ undefined, tracker); - return createMethod( + return factory.createMethodDeclaration( /*decorators*/ undefined, - /*modifiers*/ modifierFlags ? createNodeArray(createModifiersFromModifierFlags(modifierFlags)) : undefined, - /*asteriskToken*/ isYieldExpression(parent) ? createToken(SyntaxKind.AsteriskToken) : undefined, + /*modifiers*/ modifierFlags ? factory.createNodeArray(factory.createModifiersFromModifierFlags(modifierFlags)) : undefined, + /*asteriskToken*/ isYieldExpression(parent) ? factory.createToken(SyntaxKind.AsteriskToken) : undefined, methodName, /*questionToken*/ undefined, /*typeParameters*/ inJs ? undefined : map(typeArguments, (_, i) => - createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)), + factory.createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)), /*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs), /*type*/ returnType, body ? createStubbedMethodBody(context.preferences) : undefined); @@ -260,13 +294,13 @@ namespace ts.codefix { function createDummyParameters(argCount: number, names: (string | undefined)[] | undefined, types: (TypeNode | undefined)[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] { const parameters: ParameterDeclaration[] = []; for (let i = 0; i < argCount; i++) { - const newParameter = createParameter( + const newParameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ names && names[i] || `arg${i}`, - /*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined, - /*type*/ inJs ? undefined : types && types[i] || createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? factory.createToken(SyntaxKind.QuestionToken) : undefined, + /*type*/ inJs ? undefined : types && types[i] || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), /*initializer*/ undefined); parameters.push(newParameter); } @@ -302,13 +336,13 @@ namespace ts.codefix { const parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, /* types */ undefined, minArgumentCount, /*inJs*/ false); if (someSigHasRestParameter) { - const anyArrayType = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.AnyKeyword)); - const restParameter = createParameter( + const anyArrayType = factory.createArrayTypeNode(factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)); + const restParameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createToken(SyntaxKind.DotDotDotToken), + factory.createToken(SyntaxKind.DotDotDotToken), maxArgsParameterSymbolNames[maxNonRestArgs] || "rest", - /*questionToken*/ maxNonRestArgs >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined, + /*questionToken*/ maxNonRestArgs >= minArgumentCount ? factory.createToken(SyntaxKind.QuestionToken) : undefined, anyArrayType, /*initializer*/ undefined); parameters.push(restParameter); @@ -333,12 +367,12 @@ namespace ts.codefix { returnType: TypeNode | undefined, preferences: UserPreferences ): MethodDeclaration { - return createMethod( + return factory.createMethodDeclaration( /*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, name, - optional ? createToken(SyntaxKind.QuestionToken) : undefined, + optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, typeParameters, parameters, returnType, @@ -346,22 +380,22 @@ namespace ts.codefix { } function createStubbedMethodBody(preferences: UserPreferences): Block { - return createBlock( - [createThrow( - createNew( - createIdentifier("Error"), + return factory.createBlock( + [factory.createThrowStatement( + factory.createNewExpression( + factory.createIdentifier("Error"), /*typeArguments*/ undefined, // TODO Handle auto quote preference. - [createLiteral("Method not implemented.", /*isSingleQuote*/ preferences.quotePreference === "single")]))], + [factory.createStringLiteral("Method not implemented.", /*isSingleQuote*/ preferences.quotePreference === "single")]))], /*multiline*/ true); } function createVisibilityModifier(flags: ModifierFlags): Modifier | undefined { if (flags & ModifierFlags.Public) { - return createToken(SyntaxKind.PublicKeyword); + return factory.createToken(SyntaxKind.PublicKeyword); } else if (flags & ModifierFlags.Protected) { - return createToken(SyntaxKind.ProtectedKeyword); + return factory.createToken(SyntaxKind.ProtectedKeyword); } return undefined; } @@ -378,7 +412,7 @@ namespace ts.codefix { if (compilerOptionsProperty === undefined) { changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment( "compilerOptions", - createObjectLiteral(options.map(([optionName, optionValue]) => createJsonPropertyAssignment(optionName, optionValue)), /*multiLine*/ true))); + factory.createObjectLiteralExpression(options.map(([optionName, optionValue]) => createJsonPropertyAssignment(optionName, optionValue)), /*multiLine*/ true))); return; } @@ -408,7 +442,7 @@ namespace ts.codefix { } export function createJsonPropertyAssignment(name: string, initializer: Expression) { - return createPropertyAssignment(createStringLiteral(name), initializer); + return factory.createPropertyAssignment(factory.createStringLiteral(name), initializer); } export function findJsonProperty(obj: ObjectLiteralExpression, name: string): PropertyAssignment | undefined { @@ -426,7 +460,7 @@ namespace ts.codefix { const firstIdentifier = getFirstIdentifier(importTypeNode.qualifier); const name = getNameForExportedSymbol(firstIdentifier.symbol, scriptTarget); const qualifier = name !== firstIdentifier.text - ? replaceFirstIdentifierOfEntityName(importTypeNode.qualifier, createIdentifier(name)) + ? replaceFirstIdentifierOfEntityName(importTypeNode.qualifier, factory.createIdentifier(name)) : importTypeNode.qualifier; const symbols = [firstIdentifier.symbol]; @@ -446,7 +480,7 @@ namespace ts.codefix { return { symbols, - typeReference: createTypeReferenceNode(qualifier, typeArguments) + typeReference: factory.createTypeReferenceNode(qualifier, typeArguments) }; } } @@ -455,7 +489,7 @@ namespace ts.codefix { if (name.kind === SyntaxKind.Identifier) { return newIdentifier; } - return createQualifiedName(replaceFirstIdentifierOfEntityName(name.left, newIdentifier), name.right); + return factory.createQualifiedName(replaceFirstIdentifierOfEntityName(name.left, newIdentifier), name.right); } export function importSymbols(importAdder: ImportAdder, symbols: readonly Symbol[]) { diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 060d409eaa9e1..4de3035f09f8b 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -660,11 +660,11 @@ namespace ts.codefix { const convertTypeOnlyToRegular = !canUseTypeOnlyImport && clause.isTypeOnly; if (defaultImport) { Debug.assert(!clause.name, "Cannot add a default import to an import clause that already has one"); - changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), createIdentifier(defaultImport), { suffix: ", " }); + changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), factory.createIdentifier(defaultImport), { suffix: ", " }); } if (namedImports.length) { - const specifiers = namedImports.map(name => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(name))); + const specifiers = namedImports.map(name => factory.createImportSpecifier(/*propertyName*/ undefined, factory.createIdentifier(name))); if (clause.namedBindings && cast(clause.namedBindings, isNamedImports).elements.length) { for (const spec of specifiers) { changes.insertNodeInListAfter(sourceFile, last(cast(clause.namedBindings, isNamedImports).elements), spec); @@ -672,7 +672,7 @@ namespace ts.codefix { } else { if (specifiers.length) { - const namedImports = createNamedImports(specifiers); + const namedImports = factory.createNamedImports(specifiers); if (clause.namedBindings) { changes.replaceNode(sourceFile, clause.namedBindings, namedImports); } @@ -688,12 +688,12 @@ namespace ts.codefix { } function addElementToBindingPattern(bindingPattern: ObjectBindingPattern, name: string, propertyName: string | undefined) { - const element = createBindingElement(/*dotDotDotToken*/ undefined, propertyName, name); + const element = factory.createBindingElement(/*dotDotDotToken*/ undefined, propertyName, name); if (bindingPattern.elements.length) { changes.insertNodeInListAfter(sourceFile, last(bindingPattern.elements), element); } else { - changes.replaceNode(sourceFile, bindingPattern, createObjectBindingPattern([element])); + changes.replaceNode(sourceFile, bindingPattern, factory.createObjectBindingPattern([element])); } } } @@ -725,24 +725,24 @@ namespace ts.codefix { let statements: Statement | readonly Statement[] | undefined; if (imports.defaultImport !== undefined || imports.namedImports?.length) { statements = combine(statements, makeImport( - imports.defaultImport === undefined ? undefined : createIdentifier(imports.defaultImport), - imports.namedImports?.map(n => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(n))), moduleSpecifier, quotePreference, imports.typeOnly)); + imports.defaultImport === undefined ? undefined : factory.createIdentifier(imports.defaultImport), + imports.namedImports?.map(n => factory.createImportSpecifier(/*propertyName*/ undefined, factory.createIdentifier(n))), moduleSpecifier, quotePreference, imports.typeOnly)); } const { namespaceLikeImport, typeOnly } = imports; if (namespaceLikeImport) { const declaration = namespaceLikeImport.importKind === ImportKind.CommonJS - ? createImportEqualsDeclaration( + ? factory.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createIdentifier(namespaceLikeImport.name), - createExternalModuleReference(quotedModuleSpecifier)) - : createImportDeclaration( + factory.createIdentifier(namespaceLikeImport.name), + factory.createExternalModuleReference(quotedModuleSpecifier)) + : factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause( + factory.createImportClause( + typeOnly, /*name*/ undefined, - createNamespaceImport(createIdentifier(namespaceLikeImport.name)), - typeOnly), + factory.createNamespaceImport(factory.createIdentifier(namespaceLikeImport.name))), quotedModuleSpecifier); statements = combine(statements, declaration); } @@ -754,11 +754,11 @@ namespace ts.codefix { let statements: Statement | readonly Statement[] | undefined; // const { default: foo, bar, etc } = require('./mod'); if (imports.defaultImport || imports.namedImports?.length) { - const bindingElements = imports.namedImports?.map(name => createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name)) || []; + const bindingElements = imports.namedImports?.map(name => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name)) || []; if (imports.defaultImport) { - bindingElements.unshift(createBindingElement(/*dotDotDotToken*/ undefined, "default", imports.defaultImport)); + bindingElements.unshift(factory.createBindingElement(/*dotDotDotToken*/ undefined, "default", imports.defaultImport)); } - const declaration = createConstEqualsRequireDeclaration(createObjectBindingPattern(bindingElements), quotedModuleSpecifier); + const declaration = createConstEqualsRequireDeclaration(factory.createObjectBindingPattern(bindingElements), quotedModuleSpecifier); statements = combine(statements, declaration); } // const foo = require('./mod'); @@ -770,13 +770,14 @@ namespace ts.codefix { } function createConstEqualsRequireDeclaration(name: string | ObjectBindingPattern, quotedModuleSpecifier: StringLiteral): VariableStatement { - return createVariableStatement( + return factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([ - createVariableDeclaration( - typeof name === "string" ? createIdentifier(name) : name, + factory.createVariableDeclarationList([ + factory.createVariableDeclaration( + typeof name === "string" ? factory.createIdentifier(name) : name, + /*exclamationToken*/ undefined, /*type*/ undefined, - createCall(createIdentifier("require"), /*typeArguments*/ undefined, [quotedModuleSpecifier]))], + factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, [quotedModuleSpecifier]))], NodeFlags.Const)); } diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index bf6b918086041..bd5782d7a0fe5 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -128,7 +128,7 @@ namespace ts.codefix { const typeNode = getTypeNodeIfAccessible(type, parent, program, host); if (typeNode) { // Note that the codefix will never fire with an existing `@type` tag, so there is no need to merge tags - const typeTag = createJSDocTypeTag(createJSDocTypeExpression(typeNode), /*comment*/ ""); + const typeTag = factory.createJSDocTypeTag(/*tagName*/ undefined, factory.createJSDocTypeExpression(typeNode), /*comment*/ ""); addJSDocTags(changes, sourceFile, cast(parent.parent.parent, isExpressionStatement), [typeTag]); } importAdder.writeFixes(changes); @@ -239,13 +239,13 @@ namespace ts.codefix { } else { const needParens = isArrowFunction(containingFunction) && !findChildOfKind(containingFunction, SyntaxKind.OpenParenToken, sourceFile); - if (needParens) changes.insertNodeBefore(sourceFile, first(containingFunction.parameters), createToken(SyntaxKind.OpenParenToken)); + if (needParens) changes.insertNodeBefore(sourceFile, first(containingFunction.parameters), factory.createToken(SyntaxKind.OpenParenToken)); for (const { declaration, type } of parameterInferences) { if (declaration && !declaration.type && !declaration.initializer) { annotate(changes, importAdder, sourceFile, declaration, type, program, host); } } - if (needParens) changes.insertNodeAfter(sourceFile, last(containingFunction.parameters), createToken(SyntaxKind.CloseParenToken)); + if (needParens) changes.insertNodeAfter(sourceFile, last(containingFunction.parameters), factory.createToken(SyntaxKind.CloseParenToken)); } } @@ -270,7 +270,7 @@ namespace ts.codefix { function annotateJSDocThis(changes: textChanges.ChangeTracker, sourceFile: SourceFile, containingFunction: FunctionLike, typeNode: TypeNode) { addJSDocTags(changes, sourceFile, containingFunction, [ - createJSDocThisTag(createJSDocTypeExpression(typeNode)), + factory.createJSDocThisTag(/*tagName*/ undefined, factory.createJSDocTypeExpression(typeNode)), ]); } @@ -306,8 +306,8 @@ namespace ts.codefix { if (!parent) { return; } - const typeExpression = createJSDocTypeExpression(typeNode); - const typeTag = isGetAccessorDeclaration(declaration) ? createJSDocReturnTag(typeExpression, "") : createJSDocTypeTag(typeExpression, ""); + const typeExpression = factory.createJSDocTypeExpression(typeNode); + const typeTag = isGetAccessorDeclaration(declaration) ? factory.createJSDocReturnTag(/*tagName*/ undefined, typeExpression, "") : factory.createJSDocTypeTag(/*tagName*/ undefined, typeExpression, ""); addJSDocTags(changes, sourceFile, parent, [typeTag]); } else if (!tryReplaceImportTypeNodeWithAutoImport(typeNode, declaration, type, sourceFile, changes, importAdder, getEmitScriptTarget(program.getCompilerOptions()))) { @@ -344,9 +344,9 @@ namespace ts.codefix { if (param.initializer || getJSDocType(param) || !isIdentifier(param.name)) return; const typeNode = inference.type && getTypeNodeIfAccessible(inference.type, param, program, host); - const name = getSynthesizedClone(param.name); + const name = factory.cloneNode(param.name); setEmitFlags(name, EmitFlags.NoComments | EmitFlags.NoNestedComments); - return typeNode && createJSDocParameterTag(createJSDocTypeExpression(typeNode), name, /* isNameFirst */ false, !!inference.isOptional, ""); + return typeNode && factory.createJSDocParameterTag(/*tagName*/ undefined, name, /*isBracketed*/ !!inference.isOptional, factory.createJSDocTypeExpression(typeNode), /* isNameFirst */ false, ""); }); addJSDocTags(changes, sourceFile, signature, paramTags); } @@ -359,7 +359,7 @@ namespace ts.codefix { if (merged) oldTags[i] = merged; return !!merged; })); - const tag = createJSDocComment(comments.join("\n"), createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags])); + const tag = factory.createJSDocComment(comments.join("\n"), factory.createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags])); const jsDocNode = parent.kind === SyntaxKind.ArrowFunction ? getJsDocNodeForArrowFunction(parent) : parent; jsDocNode.jsDoc = parent.jsDoc; jsDocNode.jsDocCache = parent.jsDocCache; @@ -382,11 +382,11 @@ namespace ts.codefix { const oldParam = oldTag as JSDocParameterTag; const newParam = newTag as JSDocParameterTag; return isIdentifier(oldParam.name) && isIdentifier(newParam.name) && oldParam.name.escapedText === newParam.name.escapedText - ? createJSDocParameterTag(newParam.typeExpression, newParam.name, newParam.isNameFirst, newParam.isBracketed, oldParam.comment) + ? factory.createJSDocParameterTag(/*tagName*/ undefined, newParam.name, /*isBracketed*/ false, newParam.typeExpression, newParam.isNameFirst, oldParam.comment) : undefined; } case SyntaxKind.JSDocReturnTag: - return createJSDocReturnTag((newTag as JSDocReturnTag).typeExpression, oldTag.comment); + return factory.createJSDocReturnTag(/*tagName*/ undefined, (newTag as JSDocReturnTag).typeExpression, oldTag.comment); } } diff --git a/src/services/codefixes/requireInTs.ts b/src/services/codefixes/requireInTs.ts index ee53b3edaf486..f990f5cadb260 100644 --- a/src/services/codefixes/requireInTs.ts +++ b/src/services/codefixes/requireInTs.ts @@ -24,8 +24,8 @@ namespace ts.codefix { function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, info: Info) { const { allowSyntheticDefaults, defaultImportName, namedImports, statement, required } = info; changes.replaceNode(sourceFile, statement, defaultImportName && !allowSyntheticDefaults - ? createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, defaultImportName, createExternalModuleReference(required)) - : createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(defaultImportName, namedImports), required)); + ? factory.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, defaultImportName, factory.createExternalModuleReference(required)) + : factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, namedImports), required)); } interface Info { @@ -62,11 +62,11 @@ namespace ts.codefix { if (!isIdentifier(element.name) || element.initializer) { return undefined; } - importSpecifiers.push(createImportSpecifier(tryCast(element.propertyName, isIdentifier), element.name)); + importSpecifiers.push(factory.createImportSpecifier(tryCast(element.propertyName, isIdentifier), element.name)); } if (importSpecifiers.length) { - return createNamedImports(importSpecifiers); + return factory.createNamedImports(importSpecifiers); } } } diff --git a/src/services/codefixes/returnValueCorrect.ts b/src/services/codefixes/returnValueCorrect.ts index fb80e296a972b..54b782417af2c 100644 --- a/src/services/codefixes/returnValueCorrect.ts +++ b/src/services/codefixes/returnValueCorrect.ts @@ -72,11 +72,18 @@ namespace ts.codefix { }), }); + function createObjectTypeFromLabeledExpression(checker: TypeChecker, label: Identifier, expression: Expression) { + const member = checker.createSymbol(SymbolFlags.Property, label.escapedText); + member.type = checker.getTypeAtLocation(expression); + const members = createSymbolTable([member]); + return checker.createAnonymousType(/*symbol*/ undefined, members, [], [], /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + } + function getFixInfo(checker: TypeChecker, declaration: FunctionLikeDeclaration, expectType: Type, isFunctionType: boolean): Info | undefined { if (!declaration.body || !isBlock(declaration.body) || length(declaration.body.statements) !== 1) return undefined; const firstStatement = first(declaration.body.statements); - if (isExpressionStatement(firstStatement) && checkFixedAssignableTo(checker, declaration, firstStatement.expression, expectType, isFunctionType)) { + if (isExpressionStatement(firstStatement) && checkFixedAssignableTo(checker, declaration, checker.getTypeAtLocation(firstStatement.expression), expectType, isFunctionType)) { return { declaration, kind: ProblemKind.MissingReturnStatement, @@ -86,8 +93,9 @@ namespace ts.codefix { }; } else if (isLabeledStatement(firstStatement) && isExpressionStatement(firstStatement.statement)) { - const node = createObjectLiteral([createPropertyAssignment(firstStatement.label, firstStatement.statement.expression)]); - if (checkFixedAssignableTo(checker, declaration, node, expectType, isFunctionType)) { + const node = factory.createObjectLiteralExpression([factory.createPropertyAssignment(firstStatement.label, firstStatement.statement.expression)]); + const nodeType = createObjectTypeFromLabeledExpression(checker, firstStatement.label, firstStatement.statement.expression); + if (checkFixedAssignableTo(checker, declaration, nodeType, expectType, isFunctionType)) { return isArrowFunction(declaration) ? { declaration, kind: ProblemKind.MissingParentheses, @@ -106,8 +114,9 @@ namespace ts.codefix { else if (isBlock(firstStatement) && length(firstStatement.statements) === 1) { const firstBlockStatement = first(firstStatement.statements); if (isLabeledStatement(firstBlockStatement) && isExpressionStatement(firstBlockStatement.statement)) { - const node = createObjectLiteral([createPropertyAssignment(firstBlockStatement.label, firstBlockStatement.statement.expression)]); - if (checkFixedAssignableTo(checker, declaration, node, expectType, isFunctionType)) { + const node = factory.createObjectLiteralExpression([factory.createPropertyAssignment(firstBlockStatement.label, firstBlockStatement.statement.expression)]); + const nodeType = createObjectTypeFromLabeledExpression(checker, firstBlockStatement.label, firstBlockStatement.statement.expression); + if (checkFixedAssignableTo(checker, declaration, nodeType, expectType, isFunctionType)) { return { declaration, kind: ProblemKind.MissingReturnStatement, @@ -122,8 +131,35 @@ namespace ts.codefix { return undefined; } - function checkFixedAssignableTo(checker: TypeChecker, declaration: FunctionLikeDeclaration, expr: Expression, type: Type, isFunctionType: boolean) { - return checker.isTypeAssignableTo(checker.getTypeAtLocation(isFunctionType ? updateFunctionLikeBody(declaration, createBlock([createReturn(expr)])) : expr), type); + function checkFixedAssignableTo(checker: TypeChecker, declaration: FunctionLikeDeclaration, exprType: Type, type: Type, isFunctionType: boolean) { + if (isFunctionType) { + const sig = checker.getSignatureFromDeclaration(declaration); + if (sig) { + if (hasSyntacticModifier(declaration, ModifierFlags.Async)) { + exprType = checker.createPromiseType(exprType); + } + const newSig = checker.createSignature( + declaration, + sig.typeParameters, + sig.thisParameter, + sig.parameters, + exprType, + /*typePredicate*/ undefined, + sig.minArgumentCount, + sig.flags); + exprType = checker.createAnonymousType( + /*symbol*/ undefined, + createSymbolTable(), + [newSig], + [], + /*stringIndexInfo*/ undefined, + /*numberIndexInfo*/ undefined); + } + else { + exprType = checker.getAnyType(); + } + } + return checker.isTypeAssignableTo(exprType, type); } function getInfo(checker: TypeChecker, sourceFile: SourceFile, position: number, errorCode: number): Info | undefined { @@ -172,7 +208,7 @@ namespace ts.codefix { function addReturnStatement(changes: textChanges.ChangeTracker, sourceFile: SourceFile, expression: Expression, statement: Statement) { suppressLeadingAndTrailingTrivia(expression); const probablyNeedSemi = probablyUsesSemicolons(sourceFile); - changes.replaceNode(sourceFile, statement, createReturn(expression), { + changes.replaceNode(sourceFile, statement, factory.createReturnStatement(expression), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude, suffix: probablyNeedSemi ? ";" : undefined @@ -180,7 +216,7 @@ namespace ts.codefix { } function removeBlockBodyBrace(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: ArrowFunction, expression: Expression, commentSource: Node, withParen: boolean) { - const newBody = (withParen || needsParentheses(expression)) ? createParen(expression) : expression; + const newBody = (withParen || needsParentheses(expression)) ? factory.createParenthesizedExpression(expression) : expression; suppressLeadingAndTrailingTrivia(commentSource); copyComments(commentSource, newBody); @@ -188,7 +224,7 @@ namespace ts.codefix { } function wrapBlockWithParen(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: ArrowFunction, expression: Expression) { - changes.replaceNode(sourceFile, declaration.body, createParen(expression)); + changes.replaceNode(sourceFile, declaration.body, factory.createParenthesizedExpression(expression)); } function getActionForfixAddReturnStatement(context: CodeFixContext, expression: Expression, statement: Statement) { diff --git a/src/services/codefixes/splitTypeOnlyImport.ts b/src/services/codefixes/splitTypeOnlyImport.ts index 61f4a1c6f0344..321ab03d31d1d 100644 --- a/src/services/codefixes/splitTypeOnlyImport.ts +++ b/src/services/codefixes/splitTypeOnlyImport.ts @@ -27,17 +27,17 @@ namespace ts.codefix { return; } const importClause = Debug.checkDefined(importDeclaration.importClause); - changes.replaceNode(context.sourceFile, importDeclaration, updateImportDeclaration( + changes.replaceNode(context.sourceFile, importDeclaration, factory.updateImportDeclaration( importDeclaration, importDeclaration.decorators, importDeclaration.modifiers, - updateImportClause(importClause, importClause.name, /*namedBindings*/ undefined, importClause.isTypeOnly), + factory.updateImportClause(importClause, importClause.isTypeOnly, importClause.name, /*namedBindings*/ undefined), importDeclaration.moduleSpecifier)); - changes.insertNodeAfter(context.sourceFile, importDeclaration, createImportDeclaration( + changes.insertNodeAfter(context.sourceFile, importDeclaration, factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - updateImportClause(importClause, /*name*/ undefined, importClause.namedBindings, importClause.isTypeOnly), + factory.updateImportClause(importClause, importClause.isTypeOnly, /*name*/ undefined, importClause.namedBindings), importDeclaration.moduleSpecifier)); } } diff --git a/src/services/codefixes/useBigintLiteral.ts b/src/services/codefixes/useBigintLiteral.ts index 0749cc1a677b6..f521386f85e2f 100644 --- a/src/services/codefixes/useBigintLiteral.ts +++ b/src/services/codefixes/useBigintLiteral.ts @@ -28,6 +28,6 @@ namespace ts.codefix { // We use .getText to overcome parser inaccuracies: https://github.com/microsoft/TypeScript/issues/33298 const newText = numericLiteral.getText(sourceFile) + "n"; - changeTracker.replaceNode(sourceFile, numericLiteral, createBigIntLiteral(newText)); + changeTracker.replaceNode(sourceFile, numericLiteral, factory.createBigIntLiteral(newText)); } } diff --git a/src/services/codefixes/wrapJsxInFragment.ts b/src/services/codefixes/wrapJsxInFragment.ts index 243bbf778da76..c850d4113713e 100644 --- a/src/services/codefixes/wrapJsxInFragment.ts +++ b/src/services/codefixes/wrapJsxInFragment.ts @@ -40,7 +40,7 @@ namespace ts.codefix { function doChange(changeTracker: textChanges.ChangeTracker, sf: SourceFile, node: Node) { const jsx = flattenInvalidBinaryExpr(node); - if (jsx) changeTracker.replaceNode(sf, node, createJsxFragment(createJsxOpeningFragment(), jsx, createJsxJsxClosingFragment())); + if (jsx) changeTracker.replaceNode(sf, node, factory.createJsxFragment(factory.createJsxOpeningFragment(), jsx, factory.createJsxJsxClosingFragment())); } // The invalid syntax is constructed as // InvalidJsxTree :: One of diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 8c98b19c225b9..03803e6d3b3c0 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -65,7 +65,7 @@ namespace ts { // If there isn't some include for this, add a new one. if (getRegexFromPattern(Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(oldFileOrDirPath) && !getRegexFromPattern(Debug.checkDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) { - changeTracker.insertNodeAfter(configFile, last(property.initializer.elements), createStringLiteral(relativePath(newFileOrDirPath))); + changeTracker.insertNodeAfter(configFile, last(property.initializer.elements), factory.createStringLiteral(relativePath(newFileOrDirPath))); } } break; diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index be623e7911873..a8fc64e53905d 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -389,7 +389,7 @@ namespace ts.NavigationBar { const memberName = defineCall.arguments[1]; const [depth, classNameIdentifier] = startNestedNodes(node, className); startNode(node, classNameIdentifier); - startNode(node, setTextRange(createIdentifier(memberName.text), memberName)); + startNode(node, setTextRange(factory.createIdentifier(memberName.text), memberName)); addChildrenRecursively((node as CallExpression).arguments[2]); endNode(); endNode(); @@ -521,7 +521,7 @@ namespace ts.NavigationBar { if (ctorFunction !== undefined) { const ctorNode = setTextRange( - createConstructor(/* decorators */ undefined, /* modifiers */ undefined, [], /* body */ undefined), + factory.createConstructorDeclaration(/* decorators */ undefined, /* modifiers */ undefined, [], /* body */ undefined), ctorFunction); const ctor = emptyNavigationBarNode(ctorNode); ctor.indent = a.indent + 1; @@ -538,10 +538,10 @@ namespace ts.NavigationBar { } } - lastANode = a.node = setTextRange(createClassDeclaration( + lastANode = a.node = setTextRange(factory.createClassDeclaration( /* decorators */ undefined, /* modifiers */ undefined, - a.name as Identifier || createIdentifier("__class__"), + a.name as Identifier || factory.createIdentifier("__class__"), /* typeParameters */ undefined, /* heritageClauses */ undefined, [] @@ -566,10 +566,10 @@ namespace ts.NavigationBar { } else { if (!a.additionalNodes) a.additionalNodes = []; - a.additionalNodes.push(setTextRange(createClassDeclaration( + a.additionalNodes.push(setTextRange(factory.createClassDeclaration( /* decorators */ undefined, /* modifiers */ undefined, - a.name as Identifier || createIdentifier("__class__"), + a.name as Identifier || factory.createIdentifier("__class__"), /* typeParameters */ undefined, /* heritageClauses */ undefined, [] diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 1a394bc349bed..566b0ebdd7b76 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -116,7 +116,7 @@ namespace ts.OrganizeImports { const newElements = namedBindings.elements.filter(e => isDeclarationUsed(e.name)); if (newElements.length < namedBindings.elements.length) { namedBindings = newElements.length - ? updateNamedImports(namedBindings, newElements) + ? factory.updateNamedImports(namedBindings, newElements) : undefined; } } @@ -129,7 +129,7 @@ namespace ts.OrganizeImports { else if (hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier)) { // If we’re in a declaration file, it’s safe to remove the import clause from it if (sourceFile.isDeclarationFile) { - usedImports.push(createImportDeclaration( + usedImports.push(factory.createImportDeclaration( importDecl.decorators, importDecl.modifiers, /*importClause*/ undefined, @@ -217,7 +217,7 @@ namespace ts.OrganizeImports { else { for (const defaultImport of defaultImports) { newImportSpecifiers.push( - createImportSpecifier(createIdentifier("default"), defaultImport.importClause!.name!)); // TODO: GH#18217 + factory.createImportSpecifier(factory.createIdentifier("default"), defaultImport.importClause!.name!)); // TODO: GH#18217 } } @@ -232,10 +232,10 @@ namespace ts.OrganizeImports { const newNamedImports = sortedImportSpecifiers.length === 0 ? newDefaultImport ? undefined - : createNamedImports(emptyArray) + : factory.createNamedImports(emptyArray) : namedImports.length === 0 - ? createNamedImports(sortedImportSpecifiers) - : updateNamedImports(namedImports[0].importClause!.namedBindings as NamedImports, sortedImportSpecifiers); // TODO: GH#18217 + ? factory.createNamedImports(sortedImportSpecifiers) + : factory.updateNamedImports(namedImports[0].importClause!.namedBindings as NamedImports, sortedImportSpecifiers); // TODO: GH#18217 // Type-only imports are not allowed to mix default, namespace, and named imports in any combination. // We could rewrite a default import as a named import (`import { default as name }`), but we currently @@ -334,17 +334,17 @@ namespace ts.OrganizeImports { const exportDecl = exportGroup[0]; coalescedExports.push( - updateExportDeclaration( + factory.updateExportDeclaration( exportDecl, exportDecl.decorators, exportDecl.modifiers, + exportDecl.isTypeOnly, exportDecl.exportClause && ( isNamedExports(exportDecl.exportClause) ? - updateNamedExports(exportDecl.exportClause, sortedExportSpecifiers) : - updateNamespaceExport(exportDecl.exportClause, exportDecl.exportClause.name) + factory.updateNamedExports(exportDecl.exportClause, sortedExportSpecifiers) : + factory.updateNamespaceExport(exportDecl.exportClause, exportDecl.exportClause.name) ), - exportDecl.moduleSpecifier, - exportDecl.isTypeOnly)); + exportDecl.moduleSpecifier)); } return coalescedExports; @@ -386,11 +386,11 @@ namespace ts.OrganizeImports { name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { - return updateImportDeclaration( + return factory.updateImportDeclaration( importDeclaration, importDeclaration.decorators, importDeclaration.modifiers, - updateImportClause(importDeclaration.importClause!, name, namedBindings, importDeclaration.importClause!.isTypeOnly), // TODO: GH#18217 + factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.isTypeOnly, name, namedBindings), // TODO: GH#18217 importDeclaration.moduleSpecifier); } diff --git a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts index 5a11b862dd8d9..d451a10e2fdab 100644 --- a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts +++ b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts @@ -46,14 +46,14 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { let body: ConciseBody; if (actionName === addBracesActionName) { - const returnStatement = createReturn(expression); - body = createBlock([returnStatement], /* multiLine */ true); + const returnStatement = factory.createReturnStatement(expression); + body = factory.createBlock([returnStatement], /* multiLine */ true); suppressLeadingAndTrailingTrivia(body); copyLeadingComments(expression!, returnStatement, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ true); } else if (actionName === removeBracesActionName && returnStatement) { - const actualExpression = expression || createVoidZero(); - body = needsParentheses(actualExpression) ? createParen(actualExpression) : actualExpression; + const actualExpression = expression || factory.createVoidZero(); + body = needsParentheses(actualExpression) ? factory.createParenthesizedExpression(actualExpression) : actualExpression; suppressLeadingAndTrailingTrivia(body); copyTrailingAsLeadingComments(returnStatement, body, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); copyLeadingComments(returnStatement, body, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false); diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts index e469e2eccad89..6982d67f0d452 100644 --- a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts +++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts @@ -147,7 +147,7 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { function convertToBlock(body: ConciseBody): Block { if (isExpression(body)) { - return createBlock([createReturn(body)], /* multiLine */ true); + return factory.createBlock([factory.createReturnStatement(body)], /* multiLine */ true); } else { return body; @@ -168,7 +168,7 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { function getEditInfoForConvertToAnonymousFunction(context: RefactorContext, func: FunctionExpression | ArrowFunction): FileTextChanges[] { const { file } = context; const body = convertToBlock(func.body); - const newNode = createFunctionExpression(func.modifiers, func.asteriskToken, /* name */ undefined, func.typeParameters, func.parameters, func.type, body); + const newNode = factory.createFunctionExpression(func.modifiers, func.asteriskToken, /* name */ undefined, func.typeParameters, func.parameters, func.type, body); return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, func, newNode)); } @@ -178,7 +178,7 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { const { variableDeclaration, variableDeclarationList, statement, name } = variableInfo; suppressLeadingTrivia(statement); - const newNode = createFunctionDeclaration(func.decorators, statement.modifiers, func.asteriskToken, name, func.typeParameters, func.parameters, func.type, body); + const newNode = factory.createFunctionDeclaration(func.decorators, statement.modifiers, func.asteriskToken, name, func.typeParameters, func.parameters, func.type, body); if (variableDeclarationList.declarations.length === 1) { return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, statement, newNode)); @@ -206,7 +206,7 @@ namespace ts.refactor.convertArrowFunctionOrFunctionExpression { body = func.body; } - const newNode = createArrowFunction(func.modifiers, func.typeParameters, func.parameters, func.type, createToken(SyntaxKind.EqualsGreaterThanToken), body); + const newNode = factory.createArrowFunction(func.modifiers, func.typeParameters, func.parameters, func.type, factory.createToken(SyntaxKind.EqualsGreaterThanToken), body); return textChanges.ChangeTracker.with(context, t => t.replaceNode(file, func, newNode)); } diff --git a/src/services/refactors/convertExport.ts b/src/services/refactors/convertExport.ts index c79833db1ea6b..9bfcfb2f8263a 100644 --- a/src/services/refactors/convertExport.ts +++ b/src/services/refactors/convertExport.ts @@ -86,13 +86,13 @@ namespace ts.refactor { case SyntaxKind.FunctionDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: - changes.insertNodeAfter(exportingSourceFile, exportKeyword, createToken(SyntaxKind.DefaultKeyword)); + changes.insertNodeAfter(exportingSourceFile, exportKeyword, factory.createToken(SyntaxKind.DefaultKeyword)); break; case SyntaxKind.VariableStatement: // If 'x' isn't used in this file, `export const x = 0;` --> `export default 0;` if (!FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile)) { // We checked in `getInfo` that an initializer exists. - changes.replaceNode(exportingSourceFile, exportNode, createExportDefault(Debug.checkDefined(first(exportNode.declarationList.declarations).initializer, "Initializer was previously known to be present"))); + changes.replaceNode(exportingSourceFile, exportNode, factory.createExportDefault(Debug.checkDefined(first(exportNode.declarationList.declarations).initializer, "Initializer was previously known to be present"))); break; } // falls through @@ -101,7 +101,7 @@ namespace ts.refactor { case SyntaxKind.ModuleDeclaration: // `export type T = number;` -> `type T = number; export default T;` changes.deleteModifier(exportingSourceFile, exportKeyword); - changes.insertNodeAfter(exportingSourceFile, exportNode, createExportDefault(createIdentifier(exportName.text))); + changes.insertNodeAfter(exportingSourceFile, exportNode, factory.createExportDefault(factory.createIdentifier(exportName.text))); break; default: Debug.assertNever(exportNode, `Unexpected exportNode kind ${(exportNode as ExportToConvert).kind}`); @@ -128,7 +128,7 @@ namespace ts.refactor { switch (parent.kind) { case SyntaxKind.PropertyAccessExpression: // `a.default` --> `a.foo` - changes.replaceNode(importingSourceFile, ref, createIdentifier(exportName)); + changes.replaceNode(importingSourceFile, ref, factory.createIdentifier(exportName)); break; case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: { @@ -144,7 +144,7 @@ namespace ts.refactor { const { namedBindings } = clause; if (!namedBindings) { // `import foo from "./a";` --> `import { foo } from "./a";` - changes.replaceNode(importingSourceFile, ref, createNamedImports([spec])); + changes.replaceNode(importingSourceFile, ref, factory.createNamedImports([spec])); } else if (namedBindings.kind === SyntaxKind.NamespaceImport) { // `import foo, * as a from "./a";` --> `import * as a from ".a/"; import { foo } from "./a";` @@ -170,12 +170,12 @@ namespace ts.refactor { switch (parent.kind) { case SyntaxKind.PropertyAccessExpression: // `a.foo` --> `a.default` - changes.replaceNode(importingSourceFile, ref, createIdentifier("default")); + changes.replaceNode(importingSourceFile, ref, factory.createIdentifier("default")); break; case SyntaxKind.ImportSpecifier: { // `import { foo } from "./a";` --> `import foo from "./a";` // `import { foo as bar } from "./a";` --> `import bar from "./a";` - const defaultImport = createIdentifier(parent.name.text); + const defaultImport = factory.createIdentifier(parent.name.text); if (parent.parent.elements.length === 1) { changes.replaceNode(importingSourceFile, parent.parent, defaultImport); } @@ -200,10 +200,10 @@ namespace ts.refactor { } function makeImportSpecifier(propertyName: string, name: string): ImportSpecifier { - return createImportSpecifier(propertyName === name ? undefined : createIdentifier(propertyName), createIdentifier(name)); + return factory.createImportSpecifier(propertyName === name ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name)); } function makeExportSpecifier(propertyName: string, name: string): ExportSpecifier { - return createExportSpecifier(propertyName === name ? undefined : createIdentifier(propertyName), createIdentifier(name)); + return factory.createExportSpecifier(propertyName === name ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name)); } } diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index 1383aa18ddbd2..9d33f086aa844 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -69,12 +69,12 @@ namespace ts.refactor { if (importName === undefined) { exportNameToImportName.set(exportName, importName = conflictingNames.has(exportName) ? getUniqueName(exportName, sourceFile) : exportName); } - changes.replaceNode(sourceFile, propertyAccess, createIdentifier(importName)); + changes.replaceNode(sourceFile, propertyAccess, factory.createIdentifier(importName)); } const importSpecifiers: ImportSpecifier[] = []; exportNameToImportName.forEach((name, propertyName) => { - importSpecifiers.push(createImportSpecifier(name === propertyName ? undefined : createIdentifier(propertyName), createIdentifier(name))); + importSpecifiers.push(factory.createImportSpecifier(name === propertyName ? undefined : factory.createIdentifier(propertyName), factory.createIdentifier(name))); }); const importDecl = toConvert.parent.parent; @@ -83,7 +83,7 @@ namespace ts.refactor { changes.insertNodeAfter(sourceFile, importDecl, updateImport(importDecl, /*defaultImportName*/ undefined, importSpecifiers)); } else { - changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, usedAsNamespaceOrDefault ? createIdentifier(toConvert.name.text) : undefined, importSpecifiers)); + changes.replaceNode(sourceFile, importDecl, updateImport(importDecl, usedAsNamespaceOrDefault ? factory.createIdentifier(toConvert.name.text) : undefined, importSpecifiers)); } } @@ -102,13 +102,13 @@ namespace ts.refactor { for (const element of toConvert.elements) { const propertyName = (element.propertyName || element.name).text; FindAllReferences.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, id => { - const access = createPropertyAccess(createIdentifier(namespaceImportName), propertyName); + const access = factory.createPropertyAccessExpression(factory.createIdentifier(namespaceImportName), propertyName); if (isShorthandPropertyAssignment(id.parent)) { - changes.replaceNode(sourceFile, id.parent, createPropertyAssignment(id.text, access)); + changes.replaceNode(sourceFile, id.parent, factory.createPropertyAssignment(id.text, access)); } else if (isExportSpecifier(id.parent) && !id.parent.propertyName) { if (!neededNamedImports.some(n => n.name === element.name)) { - neededNamedImports.push(createImportSpecifier(element.propertyName && createIdentifier(element.propertyName.text), createIdentifier(element.name.text))); + neededNamedImports.push(factory.createImportSpecifier(element.propertyName && factory.createIdentifier(element.propertyName.text), factory.createIdentifier(element.name.text))); } } else { @@ -117,14 +117,14 @@ namespace ts.refactor { }); } - changes.replaceNode(sourceFile, toConvert, createNamespaceImport(createIdentifier(namespaceImportName))); + changes.replaceNode(sourceFile, toConvert, factory.createNamespaceImport(factory.createIdentifier(namespaceImportName))); if (neededNamedImports.length) { changes.insertNodeAfter(sourceFile, toConvert.parent.parent, updateImport(importDecl, /*defaultImportName*/ undefined, neededNamedImports)); } } function updateImport(old: ImportDeclaration, defaultImportName: Identifier | undefined, elements: readonly ImportSpecifier[] | undefined): ImportDeclaration { - return createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause(defaultImportName, elements && elements.length ? createNamedImports(elements) : undefined), old.moduleSpecifier); + return factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, + factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined), old.moduleSpecifier); } } diff --git a/src/services/refactors/convertOverloadListToSingleSignature.ts b/src/services/refactors/convertOverloadListToSingleSignature.ts index 3c747fb373678..fbcb6fece0cb4 100644 --- a/src/services/refactors/convertOverloadListToSingleSignature.ts +++ b/src/services/refactors/convertOverloadListToSingleSignature.ts @@ -31,18 +31,19 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { let updated = lastDeclaration; switch (lastDeclaration.kind) { case SyntaxKind.MethodSignature: { - updated = updateMethodSignature( + updated = factory.updateMethodSignature( lastDeclaration, + lastDeclaration.modifiers, + lastDeclaration.name, + lastDeclaration.questionToken, lastDeclaration.typeParameters, getNewParametersForCombinedSignature(signatureDecls), lastDeclaration.type, - lastDeclaration.name, - lastDeclaration.questionToken ); break; } case SyntaxKind.MethodDeclaration: { - updated = updateMethod( + updated = factory.updateMethodDeclaration( lastDeclaration, lastDeclaration.decorators, lastDeclaration.modifiers, @@ -57,7 +58,7 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { break; } case SyntaxKind.CallSignature: { - updated = updateCallSignature( + updated = factory.updateCallSignature( lastDeclaration, lastDeclaration.typeParameters, getNewParametersForCombinedSignature(signatureDecls), @@ -66,7 +67,7 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { break; } case SyntaxKind.Constructor: { - updated = updateConstructor( + updated = factory.updateConstructorDeclaration( lastDeclaration, lastDeclaration.decorators, lastDeclaration.modifiers, @@ -76,7 +77,7 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { break; } case SyntaxKind.ConstructSignature: { - updated = updateConstructSignature( + updated = factory.updateConstructSignature( lastDeclaration, lastDeclaration.typeParameters, getNewParametersForCombinedSignature(signatureDecls), @@ -85,7 +86,7 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { break; } case SyntaxKind.FunctionDeclaration: { - updated = updateFunctionDeclaration( + updated = factory.updateFunctionDeclaration( lastDeclaration, lastDeclaration.decorators, lastDeclaration.modifiers, @@ -117,30 +118,30 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction { // Trim away implementation signature arguments (they should already be compatible with overloads, but are likely less precise to guarantee compatability with the overloads) signatureDeclarations = signatureDeclarations.slice(0, signatureDeclarations.length - 1); } - return createNodeArray([ - createParameter( + return factory.createNodeArray([ + factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createToken(SyntaxKind.DotDotDotToken), + factory.createToken(SyntaxKind.DotDotDotToken), "args", /*questionToken*/ undefined, - createUnionTypeNode(map(signatureDeclarations, convertSignatureParametersToTuple)) + factory.createUnionTypeNode(map(signatureDeclarations, convertSignatureParametersToTuple)) ) ]); } function convertSignatureParametersToTuple(decl: MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorDeclaration | ConstructSignatureDeclaration | FunctionDeclaration): TupleTypeNode { const members = map(decl.parameters, convertParameterToNamedTupleMember); - return setEmitFlags(createTupleTypeNode(members), some(members, m => !!length(getSyntheticLeadingComments(m))) ? EmitFlags.None : EmitFlags.SingleLine); + return setEmitFlags(factory.createTupleTypeNode(members), some(members, m => !!length(getSyntheticLeadingComments(m))) ? EmitFlags.None : EmitFlags.SingleLine); } function convertParameterToNamedTupleMember(p: ParameterDeclaration): NamedTupleMember { Debug.assert(isIdentifier(p.name)); // This is checked during refactoring applicability checking - const result = setTextRange(createNamedTupleMember( + const result = setTextRange(factory.createNamedTupleMember( p.dotDotDotToken, p.name, p.questionToken, - p.type || createKeywordTypeNode(SyntaxKind.AnyKeyword) + p.type || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ), p); const parameterDocComment = p.symbol && p.symbol.getDocumentationComment(checker); if (parameterDocComment) { diff --git a/src/services/refactors/convertParamsToDestructuredObject.ts b/src/services/refactors/convertParamsToDestructuredObject.ts index dcb0d520f9f87..ec2277b5da8a7 100644 --- a/src/services/refactors/convertParamsToDestructuredObject.ts +++ b/src/services/refactors/convertParamsToDestructuredObject.ts @@ -356,16 +356,16 @@ namespace ts.refactor.convertParamsToDestructuredObject { function getRefactorableParameters(parameters: NodeArray): NodeArray { if (hasThisParameter(parameters)) { - parameters = createNodeArray(parameters.slice(1), parameters.hasTrailingComma); + parameters = factory.createNodeArray(parameters.slice(1), parameters.hasTrailingComma); } return parameters; } function createPropertyOrShorthandAssignment(name: string, initializer: Expression): PropertyAssignment | ShorthandPropertyAssignment { if (isIdentifier(initializer) && getTextOfIdentifierOrLiteral(initializer) === name) { - return createShorthandPropertyAssignment(name); + return factory.createShorthandPropertyAssignment(name); } - return createPropertyAssignment(name, initializer); + return factory.createPropertyAssignment(name, initializer); } function createNewArgument(functionDeclaration: ValidFunctionDeclaration, functionArguments: NodeArray): ObjectLiteralExpression { @@ -384,11 +384,11 @@ namespace ts.refactor.convertParamsToDestructuredObject { if (hasRestParameter && functionArguments.length >= parameters.length) { const restArguments = functionArguments.slice(parameters.length - 1); - const restProperty = createPropertyAssignment(getParameterName(last(parameters)), createArrayLiteral(restArguments)); + const restProperty = factory.createPropertyAssignment(getParameterName(last(parameters)), factory.createArrayLiteralExpression(restArguments)); properties.push(restProperty); } - const objectLiteral = createObjectLiteral(properties, /*multiLine*/ false); + const objectLiteral = factory.createObjectLiteralExpression(properties, /*multiLine*/ false); return objectLiteral; } @@ -396,16 +396,16 @@ namespace ts.refactor.convertParamsToDestructuredObject { const checker = program.getTypeChecker(); const refactorableParameters = getRefactorableParameters(functionDeclaration.parameters); const bindingElements = map(refactorableParameters, createBindingElementFromParameterDeclaration); - const objectParameterName = createObjectBindingPattern(bindingElements); + const objectParameterName = factory.createObjectBindingPattern(bindingElements); const objectParameterType = createParameterTypeNode(refactorableParameters); let objectInitializer: Expression | undefined; // If every parameter in the original function was optional, add an empty object initializer to the new object parameter if (every(refactorableParameters, isOptionalParameter)) { - objectInitializer = createObjectLiteral(); + objectInitializer = factory.createObjectLiteralExpression(); } - const objectParameter = createParameter( + const objectParameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -416,7 +416,7 @@ namespace ts.refactor.convertParamsToDestructuredObject { if (hasThisParameter(functionDeclaration.parameters)) { const thisParameter = functionDeclaration.parameters[0]; - const newThisParameter = createParameter( + const newThisParameter = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -431,16 +431,16 @@ namespace ts.refactor.convertParamsToDestructuredObject { copyComments(thisParameter.type, newThisParameter.type!); } - return createNodeArray([newThisParameter, objectParameter]); + return factory.createNodeArray([newThisParameter, objectParameter]); } - return createNodeArray([objectParameter]); + return factory.createNodeArray([objectParameter]); function createBindingElementFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): BindingElement { - const element = createBindingElement( + const element = factory.createBindingElement( /*dotDotDotToken*/ undefined, /*propertyName*/ undefined, getParameterName(parameterDeclaration), - isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? createArrayLiteral() : parameterDeclaration.initializer); + isRestParameter(parameterDeclaration) && isOptionalParameter(parameterDeclaration) ? factory.createArrayLiteralExpression() : parameterDeclaration.initializer); suppressLeadingAndTrailingTrivia(element); if (parameterDeclaration.initializer && element.initializer) { @@ -451,7 +451,7 @@ namespace ts.refactor.convertParamsToDestructuredObject { function createParameterTypeNode(parameters: NodeArray): TypeLiteralNode { const members = map(parameters, createPropertySignatureFromParameterDeclaration); - const typeNode = addEmitFlags(createTypeLiteralNode(members), EmitFlags.SingleLine); + const typeNode = addEmitFlags(factory.createTypeLiteralNode(members), EmitFlags.SingleLine); return typeNode; } @@ -461,12 +461,11 @@ namespace ts.refactor.convertParamsToDestructuredObject { parameterType = getTypeNode(parameterDeclaration); } - const propertySignature = createPropertySignature( + const propertySignature = factory.createPropertySignature( /*modifiers*/ undefined, getParameterName(parameterDeclaration), - isOptionalParameter(parameterDeclaration) ? createToken(SyntaxKind.QuestionToken) : parameterDeclaration.questionToken, - parameterType, - /*initializer*/ undefined); + isOptionalParameter(parameterDeclaration) ? factory.createToken(SyntaxKind.QuestionToken) : parameterDeclaration.questionToken, + parameterType); suppressLeadingAndTrailingTrivia(propertySignature); copyComments(parameterDeclaration.name, propertySignature.name); diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts index bfa398109e59a..ebcd13229ef7a 100644 --- a/src/services/refactors/convertStringOrTemplateLiteral.ts +++ b/src/services/refactors/convertStringOrTemplateLiteral.ts @@ -143,13 +143,13 @@ namespace ts.refactor.convertStringOrTemplateLiteral { const [begin, headText, headIndexes] = concatConsecutiveString(0, nodes); if (begin === nodes.length) { - const noSubstitutionTemplateLiteral = createNoSubstitutionTemplateLiteral(headText); + const noSubstitutionTemplateLiteral = factory.createNoSubstitutionTemplateLiteral(headText); copyCommentFromStringLiterals(headIndexes, noSubstitutionTemplateLiteral); return noSubstitutionTemplateLiteral; } const templateSpans: TemplateSpan[] = []; - const templateHead = createTemplateHead(headText); + const templateHead = factory.createTemplateHead(headText); copyCommentFromStringLiterals(headIndexes, templateHead); for (let i = begin; i < nodes.length; i++) { @@ -159,12 +159,12 @@ namespace ts.refactor.convertStringOrTemplateLiteral { const [newIndex, subsequentText, stringIndexes] = concatConsecutiveString(i + 1, nodes); i = newIndex - 1; - const templatePart = i === nodes.length - 1 ? createTemplateTail(subsequentText) : createTemplateMiddle(subsequentText); + const templatePart = i === nodes.length - 1 ? factory.createTemplateTail(subsequentText) : factory.createTemplateMiddle(subsequentText); copyCommentFromStringLiterals(stringIndexes, templatePart); - templateSpans.push(createTemplateSpan(currentNode, templatePart)); + templateSpans.push(factory.createTemplateSpan(currentNode, templatePart)); } - return createTemplateExpression(templateHead, templateSpans); + return factory.createTemplateExpression(templateHead, templateSpans); } // to copy comments following the opening & closing parentheses diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 7e08ed0c1aa2e..fcccf5a72a382 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -743,7 +743,7 @@ namespace ts.refactor.extractSymbol { const functionNameText = getUniqueName(isClassLike(scope) ? "newMethod" : "newFunction", file); const isJS = isInJSFile(scope); - const functionName = createIdentifier(functionNameText); + const functionName = factory.createIdentifier(functionNameText); let returnType: TypeNode | undefined; const parameters: ParameterDeclaration[] = []; @@ -758,7 +758,7 @@ namespace ts.refactor.extractSymbol { typeNode = codefix.typeToAutoImportableTypeNode(checker, importAdder, type, scope, scriptTarget, NodeBuilderFlags.NoTruncation); } - const paramDecl = createParameter( + const paramDecl = factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, @@ -770,7 +770,7 @@ namespace ts.refactor.extractSymbol { if (usage.usage === Usage.Write) { (writes || (writes = [])).push(usage); } - callArguments.push(createIdentifier(name)); + callArguments.push(factory.createIdentifier(name)); }); const typeParametersAndDeclarations = arrayFrom(typeParameterUsages.values()).map(type => ({ type, declaration: getFirstDeclaration(type) })); @@ -783,7 +783,7 @@ namespace ts.refactor.extractSymbol { // Strictly speaking, we should check whether each name actually binds to the appropriate type // parameter. In cases of shadowing, they may not. const callTypeArguments: readonly TypeNode[] | undefined = typeParameters !== undefined - ? typeParameters.map(decl => createTypeReferenceNode(decl.name, /*typeArguments*/ undefined)) + ? typeParameters.map(decl => factory.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined)) : undefined; // Provide explicit return types for contextually-typed functions @@ -800,17 +800,17 @@ namespace ts.refactor.extractSymbol { if (isClassLike(scope)) { // always create private method in TypeScript files - const modifiers: Modifier[] = isJS ? [] : [createToken(SyntaxKind.PrivateKeyword)]; + const modifiers: Modifier[] = isJS ? [] : [factory.createModifier(SyntaxKind.PrivateKeyword)]; if (range.facts & RangeFacts.InStaticRegion) { - modifiers.push(createToken(SyntaxKind.StaticKeyword)); + modifiers.push(factory.createModifier(SyntaxKind.StaticKeyword)); } if (range.facts & RangeFacts.IsAsyncFunction) { - modifiers.push(createToken(SyntaxKind.AsyncKeyword)); + modifiers.push(factory.createModifier(SyntaxKind.AsyncKeyword)); } - newFunction = createMethod( + newFunction = factory.createMethodDeclaration( /*decorators*/ undefined, modifiers.length ? modifiers : undefined, - range.facts & RangeFacts.IsGenerator ? createToken(SyntaxKind.AsteriskToken) : undefined, + range.facts & RangeFacts.IsGenerator ? factory.createToken(SyntaxKind.AsteriskToken) : undefined, functionName, /*questionToken*/ undefined, typeParameters, @@ -820,10 +820,10 @@ namespace ts.refactor.extractSymbol { ); } else { - newFunction = createFunctionDeclaration( + newFunction = factory.createFunctionDeclaration( /*decorators*/ undefined, - range.facts & RangeFacts.IsAsyncFunction ? [createToken(SyntaxKind.AsyncKeyword)] : undefined, - range.facts & RangeFacts.IsGenerator ? createToken(SyntaxKind.AsteriskToken) : undefined, + range.facts & RangeFacts.IsAsyncFunction ? [factory.createToken(SyntaxKind.AsyncKeyword)] : undefined, + range.facts & RangeFacts.IsGenerator ? factory.createToken(SyntaxKind.AsteriskToken) : undefined, functionName, typeParameters, parameters, @@ -847,15 +847,15 @@ namespace ts.refactor.extractSymbol { // replace range with function call const called = getCalledExpression(scope, range, functionNameText); - let call: Expression = createCall( + let call: Expression = factory.createCallExpression( called, callTypeArguments, // Note that no attempt is made to take advantage of type argument inference callArguments); if (range.facts & RangeFacts.IsGenerator) { - call = createYield(createToken(SyntaxKind.AsteriskToken), call); + call = factory.createYieldExpression(factory.createToken(SyntaxKind.AsteriskToken), call); } if (range.facts & RangeFacts.IsAsyncFunction) { - call = createAwait(call); + call = factory.createAwaitExpression(call); } if (exposedVariableDeclarations.length && !writes) { @@ -868,10 +868,10 @@ namespace ts.refactor.extractSymbol { if (exposedVariableDeclarations.length === 1) { // Declaring exactly one variable: let x = newFunction(); const variableDeclaration = exposedVariableDeclarations[0]; - newNodes.push(createVariableStatement( + newNodes.push(factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( - [createVariableDeclaration(getSynthesizedDeepClone(variableDeclaration.name), /*type*/ getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns + factory.createVariableDeclarationList( + [factory.createVariableDeclaration(getSynthesizedDeepClone(variableDeclaration.name), /*exclamationToken*/ undefined, /*type*/ getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns variableDeclaration.parent.flags))); } else { @@ -882,7 +882,7 @@ namespace ts.refactor.extractSymbol { let commonNodeFlags = exposedVariableDeclarations[0].parent.flags; let sawExplicitType = false; for (const variableDeclaration of exposedVariableDeclarations) { - bindingElements.push(createBindingElement( + bindingElements.push(factory.createBindingElement( /*dotDotDotToken*/ undefined, /*propertyName*/ undefined, /*name*/ getSynthesizedDeepClone(variableDeclaration.name))); @@ -893,26 +893,26 @@ namespace ts.refactor.extractSymbol { scope, NodeBuilderFlags.NoTruncation); - typeElements.push(createPropertySignature( + typeElements.push(factory.createPropertySignature( /*modifiers*/ undefined, /*name*/ variableDeclaration.symbol.name, /*questionToken*/ undefined, - /*type*/ variableType, - /*initializer*/ undefined)); + /*type*/ variableType)); sawExplicitType = sawExplicitType || variableDeclaration.type !== undefined; commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags; } - const typeLiteral: TypeLiteralNode | undefined = sawExplicitType ? createTypeLiteralNode(typeElements) : undefined; + const typeLiteral: TypeLiteralNode | undefined = sawExplicitType ? factory.createTypeLiteralNode(typeElements) : undefined; if (typeLiteral) { setEmitFlags(typeLiteral, EmitFlags.SingleLine); } - newNodes.push(createVariableStatement( + newNodes.push(factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( - [createVariableDeclaration( - createObjectBindingPattern(bindingElements), + factory.createVariableDeclarationList( + [factory.createVariableDeclaration( + factory.createObjectBindingPattern(bindingElements), + /*exclamationToken*/ undefined, /*type*/ typeLiteral, /*initializer*/call)], commonNodeFlags))); @@ -927,26 +927,26 @@ namespace ts.refactor.extractSymbol { flags = (flags & ~NodeFlags.Const) | NodeFlags.Let; } - newNodes.push(createVariableStatement( + newNodes.push(factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( - [createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], + factory.createVariableDeclarationList( + [factory.createVariableDeclaration(variableDeclaration.symbol.name, /*exclamationToken*/ undefined, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], flags))); } } if (returnValueProperty) { // has both writes and return, need to create variable declaration to hold return value; - newNodes.push(createVariableStatement( + newNodes.push(factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList( - [createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))], + factory.createVariableDeclarationList( + [factory.createVariableDeclaration(returnValueProperty, /*exclamationToken*/ undefined, getTypeDeepCloneUnionUndefined(returnType))], NodeFlags.Let))); } const assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (returnValueProperty) { - assignments.unshift(createShorthandPropertyAssignment(returnValueProperty)); + assignments.unshift(factory.createShorthandPropertyAssignment(returnValueProperty)); } // propagate writes back @@ -955,28 +955,28 @@ namespace ts.refactor.extractSymbol { // other assignments to make. Debug.assert(!returnValueProperty, "Shouldn't have returnValueProperty here"); - newNodes.push(createStatement(createAssignment(assignments[0].name, call))); + newNodes.push(factory.createExpressionStatement(factory.createAssignment(assignments[0].name, call))); if (range.facts & RangeFacts.HasReturn) { - newNodes.push(createReturn()); + newNodes.push(factory.createReturnStatement()); } } else { // emit e.g. // { a, b, __return } = newFunction(a, b); // return __return; - newNodes.push(createStatement(createAssignment(createObjectLiteral(assignments), call))); + newNodes.push(factory.createExpressionStatement(factory.createAssignment(factory.createObjectLiteralExpression(assignments), call))); if (returnValueProperty) { - newNodes.push(createReturn(createIdentifier(returnValueProperty))); + newNodes.push(factory.createReturnStatement(factory.createIdentifier(returnValueProperty))); } } } else { if (range.facts & RangeFacts.HasReturn) { - newNodes.push(createReturn(call)); + newNodes.push(factory.createReturnStatement(call)); } else if (isReadonlyArray(range.range)) { - newNodes.push(createStatement(call)); + newNodes.push(factory.createExpressionStatement(call)); } else { newNodes.push(call); @@ -1009,7 +1009,7 @@ namespace ts.refactor.extractSymbol { } return isUnionTypeNode(withoutParens) && find(withoutParens.types, t => t.kind === SyntaxKind.UndefinedKeyword) ? clone - : createUnionTypeNode([clone, createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); + : factory.createUnionTypeNode([clone, factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); } } @@ -1046,13 +1046,13 @@ namespace ts.refactor.extractSymbol { if (isClassLike(scope)) { Debug.assert(!isJS, "Cannot extract to a JS class"); // See CannotExtractToJSClass const modifiers: Modifier[] = []; - modifiers.push(createToken(SyntaxKind.PrivateKeyword)); + modifiers.push(factory.createModifier(SyntaxKind.PrivateKeyword)); if (rangeFacts & RangeFacts.InStaticRegion) { - modifiers.push(createToken(SyntaxKind.StaticKeyword)); + modifiers.push(factory.createModifier(SyntaxKind.StaticKeyword)); } - modifiers.push(createToken(SyntaxKind.ReadonlyKeyword)); + modifiers.push(factory.createModifier(SyntaxKind.ReadonlyKeyword)); - const newVariable = createProperty( + const newVariable = factory.createPropertyDeclaration( /*decorators*/ undefined, modifiers, localNameText, @@ -1060,11 +1060,11 @@ namespace ts.refactor.extractSymbol { variableType, initializer); - const localReference = createPropertyAccess( + const localReference = factory.createPropertyAccessExpression( rangeFacts & RangeFacts.InStaticRegion - ? createIdentifier(scope.name!.getText()) // TODO: GH#18217 - : createThis(), - createIdentifier(localNameText)); + ? factory.createIdentifier(scope.name!.getText()) // TODO: GH#18217 + : factory.createThis(), + factory.createIdentifier(localNameText)); // Declare const maxInsertionPos = node.pos; @@ -1075,7 +1075,7 @@ namespace ts.refactor.extractSymbol { changeTracker.replaceNode(context.file, node, localReference); } else { - const newVariableDeclaration = createVariableDeclaration(localNameText, variableType, initializer); + const newVariableDeclaration = factory.createVariableDeclaration(localNameText, /*exclamationToken*/ undefined, variableType, initializer); // If the node is part of an initializer in a list of variable declarations, insert a new // variable declaration into the list (in case it depends on earlier ones). @@ -1088,21 +1088,21 @@ namespace ts.refactor.extractSymbol { changeTracker.insertNodeBefore(context.file, oldVariableDeclaration, newVariableDeclaration); // Consume - const localReference = createIdentifier(localNameText); + const localReference = factory.createIdentifier(localNameText); changeTracker.replaceNode(context.file, node, localReference); } else if (node.parent.kind === SyntaxKind.ExpressionStatement && scope === findAncestor(node, isScope)) { // If the parent is an expression statement and the target scope is the immediately enclosing one, // replace the statement with the declaration. - const newVariableStatement = createVariableStatement( + const newVariableStatement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const)); + factory.createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const)); changeTracker.replaceNode(context.file, node.parent, newVariableStatement); } else { - const newVariableStatement = createVariableStatement( + const newVariableStatement = factory.createVariableStatement( /*modifiers*/ undefined, - createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const)); + factory.createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const)); // Declare const nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope); @@ -1119,11 +1119,11 @@ namespace ts.refactor.extractSymbol { changeTracker.delete(context.file, node.parent); } else { - let localReference: Expression = createIdentifier(localNameText); + let localReference: Expression = factory.createIdentifier(localNameText); // When extract to a new variable in JSX content, need to wrap a {} out of the new variable // or it will become a plain text if (isInJSXContent(node)) { - localReference = createJsxExpression(/*dotDotDotToken*/ undefined, localReference); + localReference = factory.createJsxExpression(/*dotDotDotToken*/ undefined, localReference); } changeTracker.replaceNode(context.file, node, localReference); } @@ -1166,7 +1166,7 @@ namespace ts.refactor.extractSymbol { const paramType = checker.getTypeAtLocation(p); if (paramType === checker.getAnyType()) hasAny = true; - parameters.push(updateParameter(p, + parameters.push(factory.updateParameterDeclaration(p, p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, p.type || checker.typeToTypeNode(paramType, scope, NodeBuilderFlags.NoTruncation), p.initializer)); } @@ -1177,7 +1177,7 @@ namespace ts.refactor.extractSymbol { if (hasAny) return { variableType, initializer }; variableType = undefined; if (isArrowFunction(initializer)) { - initializer = updateArrowFunction(initializer, node.modifiers, initializer.typeParameters, + initializer = factory.updateArrowFunction(initializer, node.modifiers, initializer.typeParameters, parameters, initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, NodeBuilderFlags.NoTruncation), initializer.equalsGreaterThanToken, @@ -1190,7 +1190,7 @@ namespace ts.refactor.extractSymbol { // Note: If this parameter was already there, it would have been previously updated with the type if not type was present if ((!firstParameter || (isIdentifier(firstParameter.name) && firstParameter.name.escapedText !== "this"))) { const thisType = checker.getTypeOfSymbolAtLocation(functionSignature.thisParameter, node); - parameters.splice(0, 0, createParameter( + parameters.splice(0, 0, factory.createParameterDeclaration( /* decorators */ undefined, /* modifiers */ undefined, /* dotDotDotToken */ undefined, @@ -1200,7 +1200,7 @@ namespace ts.refactor.extractSymbol { )); } } - initializer = updateFunctionExpression(initializer, node.modifiers, initializer.asteriskToken, + initializer = factory.updateFunctionExpression(initializer, node.modifiers, initializer.asteriskToken, initializer.name, initializer.typeParameters, parameters, initializer.type || checker.typeToTypeNode(functionSignature.getReturnType(), scope, NodeBuilderFlags.NoTruncation), @@ -1253,10 +1253,10 @@ namespace ts.refactor.extractSymbol { } function getCalledExpression(scope: Node, range: TargetRange, functionNameText: string): Expression { - const functionReference = createIdentifier(functionNameText); + const functionReference = factory.createIdentifier(functionNameText); if (isClassLike(scope)) { - const lhs = range.facts & RangeFacts.InStaticRegion ? createIdentifier(scope.name!.text) : createThis(); // TODO: GH#18217 - return createPropertyAccess(lhs, functionReference); + const lhs = range.facts & RangeFacts.InStaticRegion ? factory.createIdentifier(scope.name!.text) : factory.createThis(); // TODO: GH#18217 + return factory.createPropertyAccessExpression(lhs, functionReference); } else { return functionReference; @@ -1267,11 +1267,11 @@ namespace ts.refactor.extractSymbol { const hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0; if (isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) { // already block, no declarations or writes to propagate back, no substitutions - can use node as is - return { body: createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; + return { body: factory.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; } let returnValueProperty: string | undefined; let ignoreReturns = false; - const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : createReturn(body)]); + const statements = factory.createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : factory.createReturnStatement(body)]); // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions if (hasWritesOrVariableDeclarations || substitutions.size) { const rewrittenStatements = visitNodes(statements, visitor).slice(); @@ -1280,32 +1280,32 @@ namespace ts.refactor.extractSymbol { // it is ok to know that range has at least one return since it we only allow unconditional returns const assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (assignments.length === 1) { - rewrittenStatements.push(createReturn(assignments[0].name)); + rewrittenStatements.push(factory.createReturnStatement(assignments[0].name)); } else { - rewrittenStatements.push(createReturn(createObjectLiteral(assignments))); + rewrittenStatements.push(factory.createReturnStatement(factory.createObjectLiteralExpression(assignments))); } } - return { body: createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty }; + return { body: factory.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty }; } else { - return { body: createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; + return { body: factory.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; } function visitor(node: Node): VisitResult { - if (!ignoreReturns && node.kind === SyntaxKind.ReturnStatement && hasWritesOrVariableDeclarations) { + if (!ignoreReturns && isReturnStatement(node) && hasWritesOrVariableDeclarations) { const assignments: ObjectLiteralElementLike[] = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); - if ((node).expression) { + if (node.expression) { if (!returnValueProperty) { returnValueProperty = "__return"; } - assignments.unshift(createPropertyAssignment(returnValueProperty, visitNode((node).expression, visitor))); + assignments.unshift(factory.createPropertyAssignment(returnValueProperty, visitNode(node.expression, visitor))); } if (assignments.length === 1) { - return createReturn(assignments[0].name as Expression); + return factory.createReturnStatement(assignments[0].name as Expression); } else { - return createReturn(createObjectLiteral(assignments)); + return factory.createReturnStatement(factory.createObjectLiteralExpression(assignments)); } } else { @@ -1423,8 +1423,8 @@ namespace ts.refactor.extractSymbol { exposedVariableDeclarations: readonly VariableDeclaration[], writes: readonly UsageEntry[] | undefined ): ShorthandPropertyAssignment[] { - const variableAssignments = map(exposedVariableDeclarations, v => createShorthandPropertyAssignment(v.symbol.name)); - const writeAssignments = map(writes, w => createShorthandPropertyAssignment(w.symbol.name)); + const variableAssignments = map(exposedVariableDeclarations, v => factory.createShorthandPropertyAssignment(v.symbol.name)); + const writeAssignments = map(writes, w => factory.createShorthandPropertyAssignment(w.symbol.name)); // TODO: GH#18217 `variableAssignments` not possibly undefined! return variableAssignments === undefined @@ -1539,7 +1539,7 @@ namespace ts.refactor.extractSymbol { } const seenUsages = createMap(); - const target = isReadonlyArray(targetRange.range) ? createBlock(targetRange.range) : targetRange.range; + const target = isReadonlyArray(targetRange.range) ? factory.createBlock(targetRange.range) : targetRange.range; const unmodifiedNode = isReadonlyArray(targetRange.range) ? first(targetRange.range) : targetRange.range; const inGenericContext = isInGenericContext(unmodifiedNode); @@ -1836,15 +1836,15 @@ namespace ts.refactor.extractSymbol { } const decls = symbol.getDeclarations(); if (decls && decls.some(d => d.parent === scopeDecl)) { - return createIdentifier(symbol.name); + return factory.createIdentifier(symbol.name); } const prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); if (prefix === undefined) { return undefined; } return isTypeNode - ? createQualifiedName(prefix, createIdentifier(symbol.name)) - : createPropertyAccess(prefix, symbol.name); + ? factory.createQualifiedName(prefix, factory.createIdentifier(symbol.name)) + : factory.createPropertyAccessExpression(prefix, symbol.name); } } diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts index 491fec63bd016..4824958fe3395 100644 --- a/src/services/refactors/extractType.ts +++ b/src/services/refactors/extractType.ts @@ -159,21 +159,21 @@ namespace ts.refactor { function doTypeAliasChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: TypeAliasInfo) { const { firstStatement, selection, typeParameters } = info; - const newTypeNode = createTypeAliasDeclaration( + const newTypeNode = factory.createTypeAliasDeclaration( /* decorators */ undefined, /* modifiers */ undefined, name, - typeParameters.map(id => updateTypeParameterDeclaration(id, id.name, id.constraint, /* defaultType */ undefined)), + typeParameters.map(id => factory.updateTypeParameterDeclaration(id, id.name, id.constraint, /* defaultType */ undefined)), selection ); changes.insertNodeBefore(file, firstStatement, ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true); - changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined)))); + changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined)))); } function doInterfaceChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: InterfaceInfo) { const { firstStatement, selection, typeParameters, typeElements } = info; - const newTypeNode = createInterfaceDeclaration( + const newTypeNode = factory.createInterfaceDeclaration( /* decorators */ undefined, /* modifiers */ undefined, name, @@ -182,34 +182,30 @@ namespace ts.refactor { typeElements ); changes.insertNodeBefore(file, firstStatement, ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true); - changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined)))); + changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined)))); } function doTypedefChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: Info) { const { firstStatement, selection, typeParameters } = info; - const node = createNode(SyntaxKind.JSDocTypedefTag); - node.tagName = createIdentifier("typedef"); // TODO: jsdoc factory https://github.com/Microsoft/TypeScript/pull/29539 - node.fullName = createIdentifier(name); - node.name = node.fullName; - node.typeExpression = createJSDocTypeExpression(selection); + const node = factory.createJSDocTypedefTag( + factory.createIdentifier("typedef"), + factory.createJSDocTypeExpression(selection), + factory.createIdentifier(name)); const templates: JSDocTemplateTag[] = []; forEach(typeParameters, typeParameter => { const constraint = getEffectiveConstraintOfTypeParameter(typeParameter); - - const template = createNode(SyntaxKind.JSDocTemplateTag); - template.tagName = createIdentifier("template"); - template.constraint = constraint && cast(constraint, isJSDocTypeExpression); - - const parameter = createNode(SyntaxKind.TypeParameter); - parameter.name = typeParameter.name; - template.typeParameters = createNodeArray([parameter]); - + const parameter = factory.createTypeParameterDeclaration(typeParameter.name); + const template = factory.createJSDocTemplateTag( + factory.createIdentifier("template"), + constraint && cast(constraint, isJSDocTypeExpression), + [parameter] + ); templates.push(template); }); - changes.insertNodeBefore(file, firstStatement, createJSDocComment(/* comment */ undefined, createNodeArray(concatenate(templates, [node]))), /* blankLineBetween */ true); - changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined)))); + changes.insertNodeBefore(file, firstStatement, factory.createJSDocComment(/* comment */ undefined, factory.createNodeArray(concatenate(templates, [node]))), /* blankLineBetween */ true); + changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined)))); } } diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 7737a5cc8dfa4..f4984fe18bde9 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -103,7 +103,7 @@ namespace ts.refactor { const filesProp = cfgObject && find(cfgObject.properties, (prop): prop is PropertyAssignment => isPropertyAssignment(prop) && isStringLiteral(prop.name) && prop.name.text === "files"); if (filesProp && isArrayLiteralExpression(filesProp.initializer)) { - changes.insertNodeInListAfter(cfg, last(filesProp.initializer.elements), createLiteral(newFilePath), filesProp.initializer.elements); + changes.insertNodeInListAfter(cfg, last(filesProp.initializer.elements), factory.createStringLiteral(newFilePath), filesProp.initializer.elements); } } @@ -164,7 +164,7 @@ namespace ts.refactor { }; deleteUnusedImports(sourceFile, importNode, changes, shouldMove); // These will be changed to imports from the new file const newModuleSpecifier = combinePaths(getDirectoryPath(moduleSpecifierFromImport(importNode).text), newModuleName); - const newImportDeclaration = filterImport(importNode, createLiteral(newModuleSpecifier), shouldMove); + const newImportDeclaration = filterImport(importNode, factory.createStringLiteral(newModuleSpecifier), shouldMove); if (newImportDeclaration) changes.insertNodeAfter(sourceFile, statement, newImportDeclaration); const ns = getNamespaceLikeImport(importNode); @@ -212,25 +212,25 @@ namespace ts.refactor { if (toChange.length) { const newNamespaceName = needUniqueName ? getUniqueName(preferredNewNamespaceName, sourceFile) : preferredNewNamespaceName; for (const ref of toChange) { - changes.replaceNode(sourceFile, ref, createIdentifier(newNamespaceName)); + changes.replaceNode(sourceFile, ref, factory.createIdentifier(newNamespaceName)); } changes.insertNodeAfter(sourceFile, oldImportNode, updateNamespaceLikeImportNode(oldImportNode, newModuleName, newModuleSpecifier)); } } function updateNamespaceLikeImportNode(node: SupportedImport, newNamespaceName: string, newModuleSpecifier: string): Node { - const newNamespaceId = createIdentifier(newNamespaceName); - const newModuleString = createLiteral(newModuleSpecifier); + const newNamespaceId = factory.createIdentifier(newNamespaceName); + const newModuleString = factory.createStringLiteral(newModuleSpecifier); switch (node.kind) { case SyntaxKind.ImportDeclaration: - return createImportDeclaration( + return factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createImportClause(/*name*/ undefined, createNamespaceImport(newNamespaceId)), + factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamespaceImport(newNamespaceId)), newModuleString); case SyntaxKind.ImportEqualsDeclaration: - return createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newNamespaceId, createExternalModuleReference(newModuleString)); + return factory.createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newNamespaceId, factory.createExternalModuleReference(newModuleString)); case SyntaxKind.VariableDeclaration: - return createVariableDeclaration(newNamespaceId, /*type*/ undefined, createRequireCall(newModuleString)); + return factory.createVariableDeclaration(newNamespaceId, /*exclamationToken*/ undefined, /*type*/ undefined, createRequireCall(newModuleString)); default: return Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`); } @@ -274,7 +274,7 @@ namespace ts.refactor { const imports: string[] = []; newFileNeedExport.forEach(symbol => { if (symbol.escapedName === InternalSymbolName.Default) { - defaultImport = createIdentifier(symbolNameNoDefault(symbol)!); // TODO: GH#18217 + defaultImport = factory.createIdentifier(symbolNameNoDefault(symbol)!); // TODO: GH#18217 } else { imports.push(symbol.name); @@ -286,24 +286,24 @@ namespace ts.refactor { function makeImportOrRequire(defaultImport: Identifier | undefined, imports: readonly string[], path: string, useEs6Imports: boolean, quotePreference: QuotePreference): Statement | undefined { path = ensurePathIsNonModuleName(path); if (useEs6Imports) { - const specifiers = imports.map(i => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(i))); + const specifiers = imports.map(i => factory.createImportSpecifier(/*propertyName*/ undefined, factory.createIdentifier(i))); return makeImportIfNecessary(defaultImport, specifiers, path, quotePreference); } else { Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module. - const bindingElements = imports.map(i => createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i)); + const bindingElements = imports.map(i => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i)); return bindingElements.length - ? makeVariableStatement(createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(createLiteral(path))) + ? makeVariableStatement(factory.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(factory.createStringLiteral(path))) : undefined; } } function makeVariableStatement(name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined, flags: NodeFlags = NodeFlags.Const) { - return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([createVariableDeclaration(name, type, initializer)], flags)); + return factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, type, initializer)], flags)); } function createRequireCall(moduleSpecifier: StringLiteralLike): CallExpression { - return createCall(createIdentifier("require"), /*typeArguments*/ undefined, [moduleSpecifier]); + return factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, [moduleSpecifier]); } function addExports(sourceFile: SourceFile, toMove: readonly Statement[], needExport: ReadonlySymbolSet, useEs6Exports: boolean): readonly Statement[] { @@ -353,7 +353,7 @@ namespace ts.refactor { changes.replaceNode( sourceFile, importDecl.importClause, - updateImportClause(importDecl.importClause, name, /*namedBindings*/ undefined, importDecl.importClause.isTypeOnly) + factory.updateImportClause(importDecl.importClause, importDecl.importClause.isTypeOnly, name, /*namedBindings*/ undefined) ); } else if (namedBindings.kind === SyntaxKind.NamedImports) { @@ -556,7 +556,7 @@ namespace ts.refactor { const defaultImport = clause.name && keep(clause.name) ? clause.name : undefined; const namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep); return defaultImport || namedBindings - ? createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(defaultImport, namedBindings), moduleSpecifier) + ? factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImport, namedBindings), moduleSpecifier) : undefined; } case SyntaxKind.ImportEqualsDeclaration: @@ -575,7 +575,7 @@ namespace ts.refactor { } else { const newElements = namedBindings.elements.filter(e => keep(e.name)); - return newElements.length ? createNamedImports(newElements) : undefined; + return newElements.length ? factory.createNamedImports(newElements) : undefined; } } function filterBindingName(name: BindingName, keep: (name: Identifier) => boolean): BindingName | undefined { @@ -587,7 +587,7 @@ namespace ts.refactor { case SyntaxKind.ObjectBindingPattern: { // We can't handle nested destructurings or property names well here, so just copy them all. const newElements = name.elements.filter(prop => prop.propertyName || !isIdentifier(prop.name) || keep(prop.name)); - return newElements.length ? createObjectBindingPattern(newElements) : undefined; + return newElements.length ? factory.createObjectBindingPattern(newElements) : undefined; } } } @@ -748,24 +748,24 @@ namespace ts.refactor { return useEs6Exports ? [addEs6Export(decl)] : addCommonjsExport(decl); } function addEs6Export(d: TopLevelDeclarationStatement): TopLevelDeclarationStatement { - const modifiers = concatenate([createModifier(SyntaxKind.ExportKeyword)], d.modifiers); + const modifiers = concatenate([factory.createModifier(SyntaxKind.ExportKeyword)], d.modifiers); switch (d.kind) { case SyntaxKind.FunctionDeclaration: - return updateFunctionDeclaration(d, d.decorators, modifiers, d.asteriskToken, d.name, d.typeParameters, d.parameters, d.type, d.body); + return factory.updateFunctionDeclaration(d, d.decorators, modifiers, d.asteriskToken, d.name, d.typeParameters, d.parameters, d.type, d.body); case SyntaxKind.ClassDeclaration: - return updateClassDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members); + return factory.updateClassDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members); case SyntaxKind.VariableStatement: - return updateVariableStatement(d, modifiers, d.declarationList); + return factory.updateVariableStatement(d, modifiers, d.declarationList); case SyntaxKind.ModuleDeclaration: - return updateModuleDeclaration(d, d.decorators, modifiers, d.name, d.body); + return factory.updateModuleDeclaration(d, d.decorators, modifiers, d.name, d.body); case SyntaxKind.EnumDeclaration: - return updateEnumDeclaration(d, d.decorators, modifiers, d.name, d.members); + return factory.updateEnumDeclaration(d, d.decorators, modifiers, d.name, d.members); case SyntaxKind.TypeAliasDeclaration: - return updateTypeAliasDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.type); + return factory.updateTypeAliasDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.type); case SyntaxKind.InterfaceDeclaration: - return updateInterfaceDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members); + return factory.updateInterfaceDeclaration(d, d.decorators, modifiers, d.name, d.typeParameters, d.heritageClauses, d.members); case SyntaxKind.ImportEqualsDeclaration: - return updateImportEqualsDeclaration(d, d.decorators, modifiers, d.name, d.moduleReference); + return factory.updateImportEqualsDeclaration(d, d.decorators, modifiers, d.name, d.moduleReference); case SyntaxKind.ExpressionStatement: return Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...` default: @@ -797,10 +797,10 @@ namespace ts.refactor { /** Creates `exports.x = x;` */ function createExportAssignment(name: string): Statement { - return createExpressionStatement( - createBinary( - createPropertyAccess(createIdentifier("exports"), createIdentifier(name)), + return factory.createExpressionStatement( + factory.createBinaryExpression( + factory.createPropertyAccessExpression(factory.createIdentifier("exports"), factory.createIdentifier(name)), SyntaxKind.EqualsToken, - createIdentifier(name))); + factory.createIdentifier(name))); } } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index d2244e3f894ca..54447417a2a49 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -593,7 +593,7 @@ namespace ts.SignatureHelp { const thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : []; return checker.getExpandedParameters(candidateSignature).map(paramList => { - const params = createNodeArray([...thisParameter, ...map(paramList, param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]); + const params = factory.createNodeArray([...thisParameter, ...map(paramList, param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]); const parameterParts = mapToDisplayParts(writer => { printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer); }); @@ -606,7 +606,7 @@ namespace ts.SignatureHelp { const printer = createPrinter({ removeComments: true }); const typeParameterParts = mapToDisplayParts(writer => { if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { - const args = createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)); + const args = factory.createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)); printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer); } }); diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index d7df7037e38c4..3263e7ed4fdb8 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -252,9 +252,7 @@ namespace ts.SmartSelectionRange { function createSyntaxList(children: Node[]): SyntaxList { Debug.assertGreaterThanOrEqual(children.length, 1); - const syntaxList = createNode(SyntaxKind.SyntaxList, children[0].pos, last(children).end) as SyntaxList; - syntaxList._children = children; - return syntaxList; + return setTextRangePosEnd(parseNodeFactory.createSyntaxList(children), children[0].pos, last(children).end); } function isListOpener(token: Node | undefined): token is Node { diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 216301fc01124..1acce25574bfb 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -390,7 +390,7 @@ namespace ts.textChanges { public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void { const pos = before.getStart(sourceFile); - this.insertNodeAt(sourceFile, pos, createToken(modifier), { suffix: " " }); + this.insertNodeAt(sourceFile, pos, factory.createToken(modifier), { suffix: " " }); } public insertLastModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void { @@ -400,7 +400,7 @@ namespace ts.textChanges { } const pos = before.modifiers.end; - this.insertNodeAt(sourceFile, pos, createToken(modifier), { prefix: " " }); + this.insertNodeAt(sourceFile, pos, factory.createToken(modifier), { prefix: " " }); } public insertCommentBeforeLine(sourceFile: SourceFile, lineNumber: number, position: number, commentText: string): void { @@ -509,7 +509,7 @@ namespace ts.textChanges { } private replaceConstructorBody(sourceFile: SourceFile, ctr: ConstructorDeclaration, statements: readonly Statement[]): void { - this.replaceNode(sourceFile, ctr.body!, createBlock(statements, /*multiLine*/ true)); + this.replaceNode(sourceFile, ctr.body!, factory.createBlock(statements, /*multiLine*/ true)); } public insertNodeAtEndOfScope(sourceFile: SourceFile, scope: Node, newNode: Node): void { @@ -612,7 +612,7 @@ namespace ts.textChanges { // check if previous statement ends with semicolon // if not - insert semicolon to preserve the code from changing the meaning due to ASI if (sourceFile.text.charCodeAt(after.end - 1) !== CharacterCodes.semicolon) { - this.replaceRange(sourceFile, createRange(after.end), createToken(SyntaxKind.SemicolonToken)); + this.replaceRange(sourceFile, createRange(after.end), factory.createToken(SyntaxKind.SemicolonToken)); } } const endPosition = getAdjustedEndPosition(sourceFile, after, {}); @@ -660,25 +660,25 @@ namespace ts.textChanges { const lparen = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile); if (lparen) { // `() => {}` --> `function f() {}` - this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [createToken(SyntaxKind.FunctionKeyword), createIdentifier(name)], { joiner: " " }); + this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [factory.createToken(SyntaxKind.FunctionKeyword), factory.createIdentifier(name)], { joiner: " " }); deleteNode(this, sourceFile, arrow); } else { // `x => {}` -> `function f(x) {}` this.insertText(sourceFile, first(node.parameters).getStart(sourceFile), `function ${name}(`); // Replacing full range of arrow to get rid of the leading space -- replace ` =>` with `)` - this.replaceRange(sourceFile, arrow, createToken(SyntaxKind.CloseParenToken)); + this.replaceRange(sourceFile, arrow, factory.createToken(SyntaxKind.CloseParenToken)); } if (node.body.kind !== SyntaxKind.Block) { // `() => 0` => `function f() { return 0; }` - this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [createToken(SyntaxKind.OpenBraceToken), createToken(SyntaxKind.ReturnKeyword)], { joiner: " ", suffix: " " }); - this.insertNodesAt(sourceFile, node.body.end, [createToken(SyntaxKind.SemicolonToken), createToken(SyntaxKind.CloseBraceToken)], { joiner: " " }); + this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [factory.createToken(SyntaxKind.OpenBraceToken), factory.createToken(SyntaxKind.ReturnKeyword)], { joiner: " ", suffix: " " }); + this.insertNodesAt(sourceFile, node.body.end, [factory.createToken(SyntaxKind.SemicolonToken), factory.createToken(SyntaxKind.CloseBraceToken)], { joiner: " " }); } } else { const pos = findChildOfKind(node, node.kind === SyntaxKind.FunctionExpression ? SyntaxKind.FunctionKeyword : SyntaxKind.ClassKeyword, sourceFile)!.end; - this.insertNodeAt(sourceFile, pos, createIdentifier(name), { prefix: " " }); + this.insertNodeAt(sourceFile, pos, factory.createIdentifier(name), { prefix: " " }); } } @@ -786,7 +786,7 @@ namespace ts.textChanges { } if (multilineList) { // insert separator immediately following the 'after' node to preserve comments in trailing trivia - this.replaceRange(sourceFile, createRange(end), createToken(separator)); + this.replaceRange(sourceFile, createRange(end), factory.createToken(separator)); // use the same indentation as 'after' item const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options); // insert element before the line break on the line that contains 'after' element @@ -803,7 +803,7 @@ namespace ts.textChanges { } public parenthesizeExpression(sourceFile: SourceFile, expression: Expression) { - this.replaceRange(sourceFile, rangeOfNode(expression), createParen(expression)); + this.replaceRange(sourceFile, rangeOfNode(expression), factory.createParenthesizedExpression(expression)); } private finishClassesWithNodesInsertedAtStart(): void { @@ -1003,8 +1003,7 @@ namespace ts.textChanges { const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode)!; // TODO: GH#18217 // create proxy node for non synthesized nodes const newNode = nodeIsSynthesized(visited) ? visited : Object.create(visited) as Node; - newNode.pos = getPos(node); - newNode.end = getEnd(node); + setTextRangePosEnd(newNode, getPos(node), getEnd(node)); return newNode; } @@ -1014,9 +1013,8 @@ namespace ts.textChanges { return visited; } // clone nodearray if necessary - const nodeArray = visited === nodes ? createNodeArray(visited.slice(0)) : visited; - nodeArray.pos = getPos(nodes); - nodeArray.end = getEnd(nodes); + const nodeArray = visited === nodes ? factory.createNodeArray(visited.slice(0)) : visited; + setTextRangePosEnd(nodeArray, getPos(nodes), getEnd(nodes)); return nodeArray; } @@ -1417,7 +1415,7 @@ namespace ts.textChanges { switch (gp.kind) { case SyntaxKind.ForOfStatement: case SyntaxKind.ForInStatement: - changes.replaceNode(sourceFile, node, createObjectLiteral()); + changes.replaceNode(sourceFile, node, factory.createObjectLiteralExpression()); break; case SyntaxKind.ForStatement: diff --git a/src/services/transform.ts b/src/services/transform.ts index a3d0d7b10c3f0..c0d87f67b6f1e 100644 --- a/src/services/transform.ts +++ b/src/services/transform.ts @@ -9,7 +9,7 @@ namespace ts { const diagnostics: DiagnosticWithLocation[] = []; compilerOptions = fixupCompilerOptions(compilerOptions!, diagnostics); // TODO: GH#18217 const nodes = isArray(source) ? source : [source]; - const result = transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true); + const result = transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, factory, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true); result.diagnostics = concatenate(result.diagnostics, diagnostics); return result; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index b1799167c437b..af6834bb69ca4 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1751,17 +1751,17 @@ namespace ts { } export function makeImport(defaultImport: Identifier | undefined, namedImports: readonly ImportSpecifier[] | undefined, moduleSpecifier: string | Expression, quotePreference: QuotePreference, isTypeOnly?: boolean): ImportDeclaration { - return createImportDeclaration( + return factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, defaultImport || namedImports - ? createImportClause(defaultImport, namedImports && namedImports.length ? createNamedImports(namedImports) : undefined, isTypeOnly) + ? factory.createImportClause(!!isTypeOnly, defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined) : undefined, typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier); } export function makeStringLiteral(text: string, quotePreference: QuotePreference): StringLiteral { - return createLiteral(text, quotePreference === QuotePreference.Single); + return factory.createStringLiteral(text, quotePreference === QuotePreference.Single); } export const enum QuotePreference { Single, Double } @@ -2198,7 +2198,7 @@ namespace ts { if (renameInfo && renameInfo.text !== (node.name || node.propertyName).getText()) { clone = setOriginalNode( - createBindingElement( + factory.createBindingElement( node.dotDotDotToken, node.propertyName || node.name, renameInfo, @@ -2211,7 +2211,7 @@ namespace ts { const renameInfo = symbol && renameMap.get(String(getSymbolId(symbol))); if (renameInfo) { - clone = setOriginalNode(createIdentifier(renameInfo.text), node); + clone = setOriginalNode(factory.createIdentifier(renameInfo.text), node); } } @@ -2233,20 +2233,17 @@ namespace ts { if (visited === node) { // This only happens for leaf nodes - internal nodes always see their children change. - const clone = getSynthesizedClone(node); - if (isStringLiteral(clone)) { - clone.textSourceNode = node as any; - } - else if (isNumericLiteral(clone)) { - clone.numericLiteralFlags = (node as any).numericLiteralFlags; - } + const clone = + isStringLiteral(node) ? setOriginalNode(factory.createStringLiteralFromNode(node), node) as Node as T : + isNumericLiteral(node) ? setOriginalNode(factory.createNumericLiteral(node.text, node.numericLiteralFlags), node) as Node as T : + factory.cloneNode(node); return setTextRange(clone, node); } // PERF: As an optimization, rather than calling getSynthesizedClone, we'll update // the new node created by visitEachChild with the extra changes getSynthesizedClone // would have made. - visited.parent = undefined!; + (visited as Mutable).parent = undefined!; return visited; function wrapper(node: T) { @@ -2257,7 +2254,7 @@ namespace ts { export function getSynthesizedDeepClones(nodes: NodeArray, includeTrivia?: boolean): NodeArray; export function getSynthesizedDeepClones(nodes: NodeArray | undefined, includeTrivia?: boolean): NodeArray | undefined; export function getSynthesizedDeepClones(nodes: NodeArray | undefined, includeTrivia = true): NodeArray | undefined { - return nodes && createNodeArray(nodes.map(n => getSynthesizedDeepClone(n, includeTrivia)), nodes.hasTrailingComma); + return nodes && factory.createNodeArray(nodes.map(n => getSynthesizedDeepClone(n, includeTrivia)), nodes.hasTrailingComma); } /** diff --git a/src/testRunner/runner.ts b/src/testRunner/runner.ts index 6c85e0c53199d..c3d7d72c2a9d1 100644 --- a/src/testRunner/runner.ts +++ b/src/testRunner/runner.ts @@ -223,6 +223,12 @@ namespace Harness { } function beginTests() { + ts.Debug.loggingHost = { + log(_level, s) { + console.log(s || ""); + } + }; + if (ts.Debug.isDebugging) { ts.Debug.enableDebugInfo(); } diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index e764553c80ca1..8a0c0fbaf57b9 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -194,6 +194,7 @@ "unittests/tsserver/typeReferenceDirectives.ts", "unittests/tsserver/typingsInstaller.ts", "unittests/tsserver/versionCache.ts", - "unittests/tsserver/watchEnvironment.ts" + "unittests/tsserver/watchEnvironment.ts", + "unittests/debugDeprecation.ts" ] } diff --git a/src/testRunner/unittests/asserts.ts b/src/testRunner/unittests/asserts.ts index 116a74cf17911..a0cde51a0f841 100644 --- a/src/testRunner/unittests/asserts.ts +++ b/src/testRunner/unittests/asserts.ts @@ -1,9 +1,9 @@ namespace ts { describe("unittests:: assert", () => { it("deepEqual", () => { - assert.throws(() => assert.deepEqual(createNodeArray([createIdentifier("A")]), createNodeArray([createIdentifier("B")]))); - assert.throws(() => assert.deepEqual(createNodeArray([], /*hasTrailingComma*/ true), createNodeArray([], /*hasTrailingComma*/ false))); - assert.deepEqual(createNodeArray([createIdentifier("A")], /*hasTrailingComma*/ true), createNodeArray([createIdentifier("A")], /*hasTrailingComma*/ true)); + assert.throws(() => assert.deepEqual(factory.createNodeArray([factory.createIdentifier("A")]), factory.createNodeArray([factory.createIdentifier("B")]))); + assert.throws(() => assert.deepEqual(factory.createNodeArray([], /*hasTrailingComma*/ true), factory.createNodeArray([], /*hasTrailingComma*/ false))); + assert.deepEqual(factory.createNodeArray([factory.createIdentifier("A")], /*hasTrailingComma*/ true), factory.createNodeArray([factory.createIdentifier("A")], /*hasTrailingComma*/ true)); }); it("assertNever on string has correct error", () => { assert.throws(() => Debug.assertNever("hi" as never), "Debug Failure. Illegal value: \"hi\""); diff --git a/src/testRunner/unittests/customTransforms.ts b/src/testRunner/unittests/customTransforms.ts index 2a2309d4b8786..f346ea47dd658 100644 --- a/src/testRunner/unittests/customTransforms.ts +++ b/src/testRunner/unittests/customTransforms.ts @@ -87,7 +87,7 @@ namespace ts { ` }], {before: [ context => node => visitNode(node, function visitor(node: Node): Node { - if (isStringLiteral(node) && node.text === "change") return createLiteral("changed"); + if (isStringLiteral(node) && node.text === "change") return factory.createStringLiteral("changed"); return visitEachChild(node, visitor, context); }) ]}, { @@ -143,7 +143,7 @@ namespace ts { context => { const transformSourceFile: Transformer = node => visitNode(node, function visitor(node: Node): Node { if (isIdentifier(node) && node.text === "original") { - const newNode = createIdentifier("changed"); + const newNode = factory.createIdentifier("changed"); setSourceMapRange(newNode, { pos: 0, end: 7, @@ -156,7 +156,7 @@ namespace ts { }); return { transformSourceFile, - transformBundle: node => createBundle(map(node.sourceFiles, transformSourceFile), node.prepends), + transformBundle: node => factory.createBundle(map(node.sourceFiles, transformSourceFile), node.prepends), }; } ] diff --git a/src/testRunner/unittests/debugDeprecation.ts b/src/testRunner/unittests/debugDeprecation.ts new file mode 100644 index 0000000000000..79f2f557ebe83 --- /dev/null +++ b/src/testRunner/unittests/debugDeprecation.ts @@ -0,0 +1,71 @@ +namespace ts { + describe("unittests:: debugDeprecation", () => { + beforeEach(() => { + const loggingHost = Debug.loggingHost; + afterEach(() => { + Debug.loggingHost = loggingHost; + }); + }); + describe("deprecateFunction", () => { + it("silent deprecation", () => { + const deprecation = Debug.deprecate(noop, { + warnAfter: "3.9", + typeScriptVersion: "3.8" + }); + let logWritten = false; + Debug.loggingHost = { log() { logWritten = true; } }; + deprecation(); + assert.isFalse(logWritten); + }); + it("warning deprecation with warnAfter", () => { + const deprecation = Debug.deprecate(noop, { + warnAfter: "3.9", + typeScriptVersion: "3.9" + }); + let logWritten = false; + Debug.loggingHost = { log() { logWritten = true; } }; + deprecation(); + assert.isTrue(logWritten); + }); + it("warning deprecation without warnAfter", () => { + const deprecation = Debug.deprecate(noop, { + typeScriptVersion: "3.9" + }); + let logWritten = false; + Debug.loggingHost = { log() { logWritten = true; } }; + deprecation(); + assert.isTrue(logWritten); + }); + it("warning deprecation writes once", () => { + const deprecation = Debug.deprecate(noop, { + typeScriptVersion: "3.9" + }); + let logWrites = 0; + Debug.loggingHost = { log() { logWrites++; } }; + deprecation(); + deprecation(); + assert.equal(logWrites, 1); + }); + it("error deprecation with errorAfter", () => { + const deprecation = Debug.deprecate(noop, { + warnAfter: "3.8", + errorAfter: "3.9", + typeScriptVersion: "3.9" + }); + let logWritten = false; + Debug.loggingHost = { log() { logWritten = true; } }; + expect(deprecation).throws(); + assert.isFalse(logWritten); + }); + it("error deprecation with error", () => { + const deprecation = Debug.deprecate(noop, { + error: true, + }); + let logWritten = false; + Debug.loggingHost = { log() { logWritten = true; } }; + expect(deprecation).throws(); + assert.isFalse(logWritten); + }); + }); + }); +} \ No newline at end of file diff --git a/src/testRunner/unittests/factory.ts b/src/testRunner/unittests/factory.ts index b7f510ecdfdc6..a413881c07d3e 100644 --- a/src/testRunner/unittests/factory.ts +++ b/src/testRunner/unittests/factory.ts @@ -3,10 +3,10 @@ namespace ts { function assertSyntaxKind(node: Node, expected: SyntaxKind) { assert.strictEqual(node.kind, expected, `Actual: ${Debug.formatSyntaxKind(node.kind)} Expected: ${Debug.formatSyntaxKind(expected)}`); } - describe("createExportAssignment", () => { + describe("factory.createExportAssignment", () => { it("parenthesizes default export if necessary", () => { function checkExpression(expression: Expression) { - const node = createExportAssignment( + const node = factory.createExportAssignment( /*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, @@ -15,26 +15,26 @@ namespace ts { assertSyntaxKind(node.expression, SyntaxKind.ParenthesizedExpression); } - const clazz = createClassExpression(/*modifiers*/ undefined, "C", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ - createProperty(/*decorators*/ undefined, [createToken(SyntaxKind.StaticKeyword)], "prop", /*questionOrExclamationToken*/ undefined, /*type*/ undefined, createLiteral("1")), + const clazz = factory.createClassExpression(/*decorators*/ undefined, /*modifiers*/ undefined, "C", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ + factory.createPropertyDeclaration(/*decorators*/ undefined, [factory.createToken(SyntaxKind.StaticKeyword)], "prop", /*questionOrExclamationToken*/ undefined, /*type*/ undefined, factory.createStringLiteral("1")), ]); checkExpression(clazz); - checkExpression(createPropertyAccess(clazz, "prop")); + checkExpression(factory.createPropertyAccessExpression(clazz, "prop")); - const func = createFunctionExpression(/*modifiers*/ undefined, /*asteriskToken*/ undefined, "fn", /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, createBlock([])); + const func = factory.createFunctionExpression(/*modifiers*/ undefined, /*asteriskToken*/ undefined, "fn", /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, factory.createBlock([])); checkExpression(func); - checkExpression(createCall(func, /*typeArguments*/ undefined, /*argumentsArray*/ undefined)); - checkExpression(createTaggedTemplate(func, createNoSubstitutionTemplateLiteral(""))); + checkExpression(factory.createCallExpression(func, /*typeArguments*/ undefined, /*argumentsArray*/ undefined)); + checkExpression(factory.createTaggedTemplateExpression(func, /*typeArguments*/ undefined, factory.createNoSubstitutionTemplateLiteral(""))); - checkExpression(createBinary(createLiteral("a"), SyntaxKind.CommaToken, createLiteral("b"))); - checkExpression(createCommaList([createLiteral("a"), createLiteral("b")])); + checkExpression(factory.createBinaryExpression(factory.createStringLiteral("a"), SyntaxKind.CommaToken, factory.createStringLiteral("b"))); + checkExpression(factory.createCommaListExpression([factory.createStringLiteral("a"), factory.createStringLiteral("b")])); }); }); - describe("createArrowFunction", () => { + describe("factory.createArrowFunction", () => { it("parenthesizes concise body if necessary", () => { function checkBody(body: ConciseBody) { - const node = createArrowFunction( + const node = factory.createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, [], @@ -45,28 +45,28 @@ namespace ts { assertSyntaxKind(node.body, SyntaxKind.ParenthesizedExpression); } - checkBody(createObjectLiteral()); - checkBody(createPropertyAccess(createObjectLiteral(), "prop")); - checkBody(createAsExpression(createPropertyAccess(createObjectLiteral(), "prop"), createTypeReferenceNode("T", /*typeArguments*/ undefined))); - checkBody(createNonNullExpression(createPropertyAccess(createObjectLiteral(), "prop"))); - checkBody(createCommaList([createLiteral("a"), createLiteral("b")])); - checkBody(createBinary(createLiteral("a"), SyntaxKind.CommaToken, createLiteral("b"))); + checkBody(factory.createObjectLiteralExpression()); + checkBody(factory.createPropertyAccessExpression(factory.createObjectLiteralExpression(), "prop")); + checkBody(factory.createAsExpression(factory.createPropertyAccessExpression(factory.createObjectLiteralExpression(), "prop"), factory.createTypeReferenceNode("T", /*typeArguments*/ undefined))); + checkBody(factory.createNonNullExpression(factory.createPropertyAccessExpression(factory.createObjectLiteralExpression(), "prop"))); + checkBody(factory.createCommaListExpression([factory.createStringLiteral("a"), factory.createStringLiteral("b")])); + checkBody(factory.createBinaryExpression(factory.createStringLiteral("a"), SyntaxKind.CommaToken, factory.createStringLiteral("b"))); }); }); describe("createBinaryExpression", () => { it("parenthesizes arrow function in RHS if necessary", () => { - const lhs = createIdentifier("foo"); - const rhs = createArrowFunction( + const lhs = factory.createIdentifier("foo"); + const rhs = factory.createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, - createBlock([]), + factory.createBlock([]), ); function checkRhs(operator: BinaryOperator, expectParens: boolean) { - const node = createBinary(lhs, operator, rhs); + const node = factory.createBinaryExpression(lhs, operator, rhs); assertSyntaxKind(node.right, expectParens ? SyntaxKind.ParenthesizedExpression : SyntaxKind.ArrowFunction); } diff --git a/src/testRunner/unittests/printer.ts b/src/testRunner/unittests/printer.ts index 6c5449c97943d..59ffa8f0ed24f 100644 --- a/src/testRunner/unittests/printer.ts +++ b/src/testRunner/unittests/printer.ts @@ -97,7 +97,7 @@ namespace ts { const printsCorrectly = makePrintsCorrectly("printsBundleCorrectly"); let bundle: Bundle; before(() => { - bundle = createBundle([ + bundle = factory.createBundle([ createSourceFile("a.ts", ` /*! [a.ts] */ @@ -120,16 +120,16 @@ namespace ts { const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly"); printsCorrectly("class", {}, printer => printer.printNode( EmitHint.Unspecified, - createClassDeclaration( + factory.createClassDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*name*/ createIdentifier("C"), + /*name*/ factory.createIdentifier("C"), /*typeParameters*/ undefined, /*heritageClauses*/ undefined, - [createProperty( + [factory.createPropertyDeclaration( /*decorators*/ undefined, - createNodeArray([createToken(SyntaxKind.PublicKeyword)]), - createIdentifier("prop"), + factory.createNodeArray([factory.createToken(SyntaxKind.PublicKeyword)]), + factory.createIdentifier("prop"), /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined @@ -140,15 +140,15 @@ namespace ts { printsCorrectly("namespaceExportDeclaration", {}, printer => printer.printNode( EmitHint.Unspecified, - createNamespaceExportDeclaration("B"), + factory.createNamespaceExportDeclaration("B"), createSourceFile("source.ts", "", ScriptTarget.ES2015) )); printsCorrectly("newExpressionWithPropertyAccessOnCallExpression", {}, printer => printer.printNode( EmitHint.Unspecified, - createNew( - createPropertyAccess( - createCall(createIdentifier("f"), /*typeArguments*/ undefined, /*argumentsArray*/ undefined), + factory.createNewExpression( + factory.createPropertyAccessExpression( + factory.createCallExpression(factory.createIdentifier("f"), /*typeArguments*/ undefined, /*argumentsArray*/ undefined), "x"), /*typeArguments*/ undefined, /*argumentsArray*/ undefined @@ -158,11 +158,11 @@ namespace ts { printsCorrectly("newExpressionOnConditionalExpression", {}, printer => printer.printNode( EmitHint.Unspecified, - createNew( - createConditional( - createIdentifier("x"), createToken(SyntaxKind.QuestionToken), - createIdentifier("y"), createToken(SyntaxKind.ColonToken), - createIdentifier("z")), + factory.createNewExpression( + factory.createConditionalExpression( + factory.createIdentifier("x"), factory.createToken(SyntaxKind.QuestionToken), + factory.createIdentifier("y"), factory.createToken(SyntaxKind.ColonToken), + factory.createIdentifier("z")), /*typeArguments*/ undefined, /*argumentsArray*/ undefined ), @@ -171,22 +171,22 @@ namespace ts { printsCorrectly("emptyGlobalAugmentation", {}, printer => printer.printNode( EmitHint.Unspecified, - createModuleDeclaration( + factory.createModuleDeclaration( /*decorators*/ undefined, - /*modifiers*/ [createToken(SyntaxKind.DeclareKeyword)], - createIdentifier("global"), - createModuleBlock(emptyArray), + /*modifiers*/ [factory.createToken(SyntaxKind.DeclareKeyword)], + factory.createIdentifier("global"), + factory.createModuleBlock(emptyArray), NodeFlags.GlobalAugmentation), createSourceFile("source.ts", "", ScriptTarget.ES2015) )); printsCorrectly("emptyGlobalAugmentationWithNoDeclareKeyword", {}, printer => printer.printNode( EmitHint.Unspecified, - createModuleDeclaration( + factory.createModuleDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createIdentifier("global"), - createModuleBlock(emptyArray), + factory.createIdentifier("global"), + factory.createModuleBlock(emptyArray), NodeFlags.GlobalAugmentation), createSourceFile("source.ts", "", ScriptTarget.ES2015) )); @@ -194,30 +194,30 @@ namespace ts { // https://github.com/Microsoft/TypeScript/issues/15971 printsCorrectly("classWithOptionalMethodAndProperty", {}, printer => printer.printNode( EmitHint.Unspecified, - createClassDeclaration( + factory.createClassDeclaration( /*decorators*/ undefined, - /*modifiers*/ [createToken(SyntaxKind.DeclareKeyword)], - /*name*/ createIdentifier("X"), + /*modifiers*/ [factory.createToken(SyntaxKind.DeclareKeyword)], + /*name*/ factory.createIdentifier("X"), /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ - createMethod( + factory.createMethodDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, - /*name*/ createIdentifier("method"), - /*questionToken*/ createToken(SyntaxKind.QuestionToken), + /*name*/ factory.createIdentifier("method"), + /*questionToken*/ factory.createToken(SyntaxKind.QuestionToken), /*typeParameters*/ undefined, [], - /*type*/ createKeywordTypeNode(SyntaxKind.VoidKeyword), + /*type*/ factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), /*body*/ undefined ), - createProperty( + factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*name*/ createIdentifier("property"), - /*questionToken*/ createToken(SyntaxKind.QuestionToken), - /*type*/ createKeywordTypeNode(SyntaxKind.StringKeyword), + /*name*/ factory.createIdentifier("property"), + /*questionToken*/ factory.createToken(SyntaxKind.QuestionToken), + /*type*/ factory.createKeywordTypeNode(SyntaxKind.StringKeyword), /*initializer*/ undefined ), ] @@ -228,69 +228,69 @@ namespace ts { // https://github.com/Microsoft/TypeScript/issues/15651 printsCorrectly("functionTypes", {}, printer => printer.printNode( EmitHint.Unspecified, - setEmitFlags(createTupleTypeNode([ - createFunctionTypeNode( + setEmitFlags(factory.createTupleTypeNode([ + factory.createFunctionTypeNode( /*typeArguments*/ undefined, - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, - createIdentifier("args") + factory.createIdentifier("args") )], - createKeywordTypeNode(SyntaxKind.AnyKeyword) + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ), - createFunctionTypeNode( - [createTypeParameterDeclaration("T")], - [createParameter( + factory.createFunctionTypeNode( + [factory.createTypeParameterDeclaration("T")], + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, - createIdentifier("args") + factory.createIdentifier("args") )], - createKeywordTypeNode(SyntaxKind.AnyKeyword) + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ), - createFunctionTypeNode( + factory.createFunctionTypeNode( /*typeArguments*/ undefined, - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createToken(SyntaxKind.DotDotDotToken), - createIdentifier("args") + factory.createToken(SyntaxKind.DotDotDotToken), + factory.createIdentifier("args") )], - createKeywordTypeNode(SyntaxKind.AnyKeyword) + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ), - createFunctionTypeNode( + factory.createFunctionTypeNode( /*typeArguments*/ undefined, - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, - createIdentifier("args"), - createToken(SyntaxKind.QuestionToken) + factory.createIdentifier("args"), + factory.createToken(SyntaxKind.QuestionToken) )], - createKeywordTypeNode(SyntaxKind.AnyKeyword) + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ), - createFunctionTypeNode( + factory.createFunctionTypeNode( /*typeArguments*/ undefined, - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, - createIdentifier("args"), + factory.createIdentifier("args"), /*questionToken*/ undefined, - createKeywordTypeNode(SyntaxKind.AnyKeyword) + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) )], - createKeywordTypeNode(SyntaxKind.AnyKeyword) + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ), - createFunctionTypeNode( + factory.createFunctionTypeNode( /*typeArguments*/ undefined, - [createParameter( + [factory.createParameterDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, - createObjectBindingPattern([]) + factory.createObjectBindingPattern([]) )], - createKeywordTypeNode(SyntaxKind.AnyKeyword) + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ), ]), EmitFlags.SingleLine), createSourceFile("source.ts", "", ScriptTarget.ES2015) diff --git a/src/testRunner/unittests/publicApi.ts b/src/testRunner/unittests/publicApi.ts index 7f141f16c2705..4cf83d6c8fc67 100644 --- a/src/testRunner/unittests/publicApi.ts +++ b/src/testRunner/unittests/publicApi.ts @@ -49,13 +49,13 @@ describe("unittests:: Public APIs:: token to string", () => { describe("unittests:: Public APIs:: createPrivateIdentifier", () => { it("throws when name doesn't start with #", () => { - assert.throw(() => ts.createPrivateIdentifier("not"), "Debug Failure. First character of private identifier must be #: not"); + assert.throw(() => ts.factory.createPrivateIdentifier("not"), "Debug Failure. First character of private identifier must be #: not"); }); }); describe("unittests:: Public APIs:: isPropertyName", () => { it("checks if a PrivateIdentifier is a valid property name", () => { - const prop = ts.createPrivateIdentifier("#foo"); + const prop = ts.factory.createPrivateIdentifier("#foo"); assert.isTrue(ts.isPropertyName(prop), "PrivateIdentifier must be a valid property name."); }); }); diff --git a/src/testRunner/unittests/services/textChanges.ts b/src/testRunner/unittests/services/textChanges.ts index 5c3a103c23833..7a5c9af03ff56 100644 --- a/src/testRunner/unittests/services/textChanges.ts +++ b/src/testRunner/unittests/services/textChanges.ts @@ -82,22 +82,22 @@ namespace M }`; runSingleFileTest("extractMethodLike", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { const statements = (findChild("foo", sourceFile)).body!.statements.slice(1); - const newFunction = createFunctionDeclaration( + const newFunction = factory.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ "bar", /*typeParameters*/ undefined, /*parameters*/ emptyArray, - /*type*/ createKeywordTypeNode(SyntaxKind.AnyKeyword), - /*body */ createBlock(statements) + /*type*/ factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*body */ factory.createBlock(statements) ); changeTracker.insertNodeBefore(sourceFile, /*before*/findChild("M2", sourceFile), newFunction); // replace statements with return statement - const newStatement = createReturn( - createCall( + const newStatement = factory.createReturnStatement( + factory.createCallExpression( /*expression*/ newFunction.name!, /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray @@ -178,31 +178,31 @@ var a = 4; // comment 7 }); } function createTestVariableDeclaration(name: string) { - return createVariableDeclaration(name, /*type*/ undefined, createObjectLiteral([createPropertyAssignment("p1", createLiteral(1))], /*multiline*/ true)); + return factory.createVariableDeclaration(name, /*exclamationToken*/ undefined, /*type*/ undefined, factory.createObjectLiteralExpression([factory.createPropertyAssignment("p1", factory.createNumericLiteral(1))], /*multiline*/ true)); } function createTestClass() { - return createClassDeclaration( + return factory.createClassDeclaration( /*decorators*/ undefined, [ - createToken(SyntaxKind.PublicKeyword) + factory.createToken(SyntaxKind.PublicKeyword) ], "class1", /*typeParameters*/ undefined, [ - createHeritageClause( + factory.createHeritageClause( SyntaxKind.ImplementsKeyword, [ - createExpressionWithTypeArguments(/*typeArguments*/ undefined, createIdentifier("interface1")) + factory.createExpressionWithTypeArguments(factory.createIdentifier("interface1"), /*typeArguments*/ undefined) ] ) ], [ - createProperty( + factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, "property1", /*questionToken*/ undefined, - createKeywordTypeNode(SyntaxKind.BooleanKeyword), + factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword), /*initializer*/ undefined ) ] @@ -333,12 +333,12 @@ namespace M { return find(classDecl.members, (m): m is ConstructorDeclaration => isConstructorDeclaration(m) && !!m.body)!; } function createTestSuperCall() { - const superCall = createCall( - createSuper(), + const superCall = factory.createCallExpression( + factory.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray ); - return createStatement(superCall); + return factory.createExpressionStatement(superCall); } { @@ -484,27 +484,27 @@ function foo( const text = ` const x = 1, y = 2;`; runSingleFileTest("insertNodeInListAfter1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); runSingleFileTest("insertNodeInListAfter2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); } { const text = ` const /*x*/ x = 1, /*y*/ y = 2;`; runSingleFileTest("insertNodeInListAfter3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); runSingleFileTest("insertNodeInListAfter4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); } { const text = ` const x = 1;`; runSingleFileTest("insertNodeInListAfter5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); } { @@ -512,10 +512,10 @@ const x = 1;`; const x = 1, y = 2;`; runSingleFileTest("insertNodeInListAfter6", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); runSingleFileTest("insertNodeInListAfter7", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); } { @@ -523,10 +523,10 @@ const x = 1, const /*x*/ x = 1, /*y*/ y = 2;`; runSingleFileTest("insertNodeInListAfter8", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); runSingleFileTest("insertNodeInListAfter9", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), factory.createVariableDeclaration("z", /*exclamationToken*/ undefined, /*type*/ undefined, factory.createNumericLiteral(1))); }); } { @@ -535,7 +535,7 @@ import { x } from "bar"`; runSingleFileTest("insertNodeInListAfter10", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(factory.createIdentifier("b"), factory.createIdentifier("a"))); }); } { @@ -544,7 +544,7 @@ import { x // this is x } from "bar"`; runSingleFileTest("insertNodeInListAfter11", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(factory.createIdentifier("b"), factory.createIdentifier("a"))); }); } { @@ -553,7 +553,8 @@ import { x } from "bar"`; runSingleFileTest("insertNodeInListAfter12", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + // eslint-disable-next-line boolean-trivia + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(undefined, factory.createIdentifier("a"))); }); } { @@ -562,7 +563,8 @@ import { x // this is x } from "bar"`; runSingleFileTest("insertNodeInListAfter13", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + // eslint-disable-next-line boolean-trivia + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(undefined, factory.createIdentifier("a"))); }); } { @@ -572,7 +574,7 @@ import { x } from "bar"`; runSingleFileTest("insertNodeInListAfter14", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(factory.createIdentifier("b"), factory.createIdentifier("a"))); }); } { @@ -582,7 +584,7 @@ import { x // this is x } from "bar"`; runSingleFileTest("insertNodeInListAfter15", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a"))); + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(factory.createIdentifier("b"), factory.createIdentifier("a"))); }); } { @@ -592,7 +594,8 @@ import { x } from "bar"`; runSingleFileTest("insertNodeInListAfter16", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + // eslint-disable-next-line boolean-trivia + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(undefined, factory.createIdentifier("a"))); }); } { @@ -602,7 +605,8 @@ import { x // this is x } from "bar"`; runSingleFileTest("insertNodeInListAfter17", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + // eslint-disable-next-line boolean-trivia + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(undefined, factory.createIdentifier("a"))); }); } { @@ -611,7 +615,8 @@ import { x0, x } from "bar"`; runSingleFileTest("insertNodeInListAfter18", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + // eslint-disable-next-line boolean-trivia + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), factory.createImportSpecifier(undefined, factory.createIdentifier("a"))); }); } { @@ -623,7 +628,8 @@ class A { const newNodes = []; for (let i = 0; i < 11 /*error doesn't occur with fewer nodes*/; ++i) { newNodes.push( - createProperty(undefined, undefined, i + "", undefined, undefined, undefined)); + // eslint-disable-next-line boolean-trivia + factory.createPropertyDeclaration(undefined, undefined, i + "", undefined, undefined, undefined)); } const insertAfter = findChild("x", sourceFile); for (const newNode of newNodes) { @@ -638,7 +644,8 @@ class A { } `; runSingleFileTest("insertNodeAfterInClass1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), createProperty(undefined, undefined, "a", undefined, createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined)); + // eslint-disable-next-line boolean-trivia + changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), factory.createPropertyDeclaration(undefined, undefined, "a", undefined, factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined)); }); } { @@ -648,7 +655,8 @@ class A { } `; runSingleFileTest("insertNodeAfterInClass2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), createProperty(undefined, undefined, "a", undefined, createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined)); + // eslint-disable-next-line boolean-trivia + changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), factory.createPropertyDeclaration(undefined, undefined, "a", undefined, factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined)); }); } { @@ -680,12 +688,12 @@ class A { } `; runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = createProperty( + const newNode = factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createComputedPropertyName(createLiteral(1)), + factory.createComputedPropertyName(factory.createNumericLiteral(1)), /*questionToken*/ undefined, - createKeywordTypeNode(SyntaxKind.AnyKeyword), + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), /*initializer*/ undefined); changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), newNode); }); @@ -698,12 +706,12 @@ class A { } `; runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = createProperty( + const newNode = factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createComputedPropertyName(createLiteral(1)), + factory.createComputedPropertyName(factory.createNumericLiteral(1)), /*questionToken*/ undefined, - createKeywordTypeNode(SyntaxKind.AnyKeyword), + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), /*initializer*/ undefined); changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), newNode); }); @@ -715,12 +723,12 @@ interface A { } `; runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = createProperty( + const newNode = factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createComputedPropertyName(createLiteral(1)), + factory.createComputedPropertyName(factory.createNumericLiteral(1)), /*questionToken*/ undefined, - createKeywordTypeNode(SyntaxKind.AnyKeyword), + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), /*initializer*/ undefined); changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), newNode); }); @@ -732,12 +740,12 @@ interface A { } `; runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = createProperty( + const newNode = factory.createPropertyDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - createComputedPropertyName(createLiteral(1)), + factory.createComputedPropertyName(factory.createNumericLiteral(1)), /*questionToken*/ undefined, - createKeywordTypeNode(SyntaxKind.AnyKeyword), + factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), /*initializer*/ undefined); changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), newNode); }); @@ -747,7 +755,7 @@ interface A { let x = foo `; runSingleFileTest("insertNodeInStatementListAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { - const newNode = createStatement(createParen(createLiteral(1))); + const newNode = factory.createExpressionStatement(factory.createParenthesizedExpression(factory.createNumericLiteral(1))); changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), newNode); }); } diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 47b87b2e86600..e18dd33c92c3c 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -6,10 +6,10 @@ namespace ts { context.onSubstituteNode = (hint, node) => { node = previousOnSubstituteNode(hint, node); if (hint === EmitHint.Expression && isIdentifier(node) && node.escapedText === "undefined") { - node = createPartiallyEmittedExpression( + node = factory.createPartiallyEmittedExpression( addSyntheticTrailingComment( setTextRange( - createVoidZero(), + factory.createVoidZero(), node), SyntaxKind.MultiLineCommentTrivia, "undefined")); } @@ -20,7 +20,7 @@ namespace ts { function replaceNumberWith2(context: TransformationContext) { function visitor(node: Node): Node { if (isNumericLiteral(node)) { - return createNumericLiteral("2"); + return factory.createNumericLiteral("2"); } return visitEachChild(node, visitor, context); } @@ -33,7 +33,7 @@ namespace ts { context.onSubstituteNode = (hint, node) => { node = previousOnSubstituteNode(hint, node); if (isIdentifier(node) && node.escapedText === "oldName") { - node = setTextRange(createIdentifier("newName"), node); + node = setTextRange(factory.createIdentifier("newName"), node); } return node; }; @@ -43,7 +43,7 @@ namespace ts { function replaceIdentifiersNamedOldNameWithNewName2(context: TransformationContext) { const visitor: Visitor = (node) => { if (isIdentifier(node) && node.text === "oldName") { - return createIdentifier("newName"); + return factory.createIdentifier("newName"); } return visitEachChild(node, visitor, context); }; @@ -51,11 +51,12 @@ namespace ts { } function createTaggedTemplateLiteral(): Transformer { - return sourceFile => updateSourceFileNode(sourceFile, [ - createStatement( - createTaggedTemplate( - createIdentifier("$tpl"), - createNoSubstitutionTemplateLiteral("foo", "foo"))) + return sourceFile => factory.updateSourceFile(sourceFile, [ + factory.createExpressionStatement( + factory.createTaggedTemplateExpression( + factory.createIdentifier("$tpl"), + /*typeArguments*/ undefined, + factory.createNoSubstitutionTemplateLiteral("foo", "foo"))) ]); } @@ -65,7 +66,7 @@ namespace ts { onEmitNode: transformed.emitNodeWithNotification, substituteNode: transformed.substituteNode }); - const result = printer.printBundle(createBundle(transformed.transformed)); + const result = printer.printBundle(factory.createBundle(transformed.transformed)); transformed.dispose(); return result; } @@ -110,7 +111,7 @@ namespace ts { return transformSourceFile(`let a!: () => void`, [ context => file => visitNode(file, function visitor(node: Node): VisitResult { if (node.kind === SyntaxKind.VoidKeyword) { - return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + return factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword); } return visitEachChild(node, visitor, context); }) @@ -206,11 +207,14 @@ namespace ts { function replaceWithClassAndNamespace() { return (sourceFile: SourceFile) => { - const result = getMutableClone(sourceFile); - result.statements = createNodeArray([ - createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined!), // TODO: GH#18217 - createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createIdentifier("Foo"), createModuleBlock([createEmptyStatement()])) - ]); + // TODO(rbuckton): Does this need to be parented? + const result = factory.updateSourceFile( + sourceFile, + factory.createNodeArray([ + factory.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined!), // TODO: GH#18217 + factory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createIdentifier("Foo"), factory.createModuleBlock([factory.createEmptyStatement()])) + ]) + ); return result; }; } @@ -223,8 +227,8 @@ namespace ts { function visitNode(node: T): T { if (node.kind === SyntaxKind.ModuleBlock) { const block = node as T & ModuleBlock; - const statements = createNodeArray([...block.statements]); - return updateModuleBlock(block, statements) as typeof block; + const statements = factory.createNodeArray([...block.statements]); + return factory.updateModuleBlock(block, statements) as typeof block; } return visitEachChild(node, visitNode, context); } @@ -250,9 +254,9 @@ namespace ts { if (node.kind === SyntaxKind.ExportDeclaration) { const ed = node as Node as ExportDeclaration; const exports = [{ name: "x" }]; - const exportSpecifiers = exports.map(e => createExportSpecifier(e.name, e.name)); - const exportClause = createNamedExports(exportSpecifiers); - const newEd = updateExportDeclaration(ed, ed.decorators, ed.modifiers, exportClause, ed.moduleSpecifier, ed.isTypeOnly); + const exportSpecifiers = exports.map(e => factory.createExportSpecifier(e.name, e.name)); + const exportClause = factory.createNamedExports(exportSpecifiers); + const newEd = factory.updateExportDeclaration(ed, ed.decorators, ed.modifiers, ed.isTypeOnly, exportClause, ed.moduleSpecifier); return newEd as Node as T; } @@ -281,15 +285,16 @@ namespace ts { }; function visitNode(sf: SourceFile) { // produce `import * as i0 from './comp'; - const importStar = createImportDeclaration( + const importStar = factory.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, - /*importClause*/ createImportClause( + /*importClause*/ factory.createImportClause( + /*isTypeOnly*/ false, /*name*/ undefined, - createNamespaceImport(createIdentifier("i0")) + factory.createNamespaceImport(factory.createIdentifier("i0")) ), - /*moduleSpecifier*/ createLiteral("./comp1")); - return updateSourceFileNode(sf, [importStar]); + /*moduleSpecifier*/ factory.createStringLiteral("./comp1")); + return factory.updateSourceFile(sf, [importStar]); } } }); @@ -312,10 +317,10 @@ namespace ts { }; function visitNode(sf: SourceFile) { // produce `class Foo { @Bar baz() {} }`; - const classDecl = createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ - createMethod([createDecorator(createIdentifier("Bar"))], [], /**/ undefined, "baz", /**/ undefined, /**/ undefined, [], /**/ undefined, createBlock([])) + const classDecl = factory.createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ + factory.createMethodDeclaration([factory.createDecorator(factory.createIdentifier("Bar"))], [], /**/ undefined, "baz", /**/ undefined, /**/ undefined, [], /**/ undefined, factory.createBlock([])) ]); - return updateSourceFileNode(sf, [classDecl]); + return factory.updateSourceFile(sf, [classDecl]); } } }); @@ -351,11 +356,11 @@ namespace ts { function visitNode(sf: SourceFile) { // produce `class Foo { constructor(@Dec private x) {} }`; // The decorator is required to trigger ts.ts transformations. - const classDecl = createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ - createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, [ - createParameter(/*decorators*/ [createDecorator(createIdentifier("Dec"))], /*modifiers*/ [createModifier(SyntaxKind.PrivateKeyword)], /*dotDotDotToken*/ undefined, "x")], createBlock([])) + const classDecl = factory.createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ + factory.createConstructorDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, [ + factory.createParameterDeclaration(/*decorators*/ [factory.createDecorator(factory.createIdentifier("Dec"))], /*modifiers*/ [factory.createModifier(SyntaxKind.PrivateKeyword)], /*dotDotDotToken*/ undefined, "x")], factory.createBlock([])) ]); - return updateSourceFileNode(sf, [classDecl]); + return factory.updateSourceFile(sf, [classDecl]); } } }); @@ -501,7 +506,7 @@ module MyModule { }; function rootTransform(node: T): Node { if (isVariableDeclaration(node)) { - return updateVariableDeclaration(node, createIdentifier("newName"), /* type */ undefined, node.initializer); + return factory.updateVariableDeclaration(node, factory.createIdentifier("newName"), /*exclamationToken*/ undefined, /*type*/ undefined, node.initializer); } return visitEachChild(node, rootTransform, context); } @@ -527,12 +532,12 @@ module MyModule { function transformSourceFile(context: TransformationContext) { const visitor: Visitor = (node) => { if (isMethodDeclaration(node)) { - return updateMethod( + return factory.updateMethodDeclaration( node, node.decorators, node.modifiers, node.asteriskToken, - createIdentifier("foobar"), + factory.createIdentifier("foobar"), node.questionToken, node.typeParameters, node.parameters, @@ -561,7 +566,7 @@ module MyModule { function transformSourceFile(context: TransformationContext): Transformer { function visitor(node: Node): VisitResult { if (isNoSubstitutionTemplateLiteral(node)) { - return createNoSubstitutionTemplateLiteral(node.text, node.rawText); + return factory.createNoSubstitutionTemplateLiteral(node.text, node.rawText); } else { return visitEachChild(node, visitor, context); diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index f290691160cc3..19c3e84a0dc96 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -1,5 +1,11 @@ namespace ts {} // empty ts module so the module migration script knows this file depends on the `ts` project namespace // This file actually uses arguments passed on commandline and executes it +ts.Debug.loggingHost = { + log(_level, s) { + ts.sys.write(`${s || ""}${ts.sys.newLine}`); + } +}; + if (ts.Debug.isDebugging) { ts.Debug.enableDebugInfo(); } diff --git a/src/tsserver/tsconfig.json b/src/tsserver/tsconfig.json index 16ffd722f2d63..52f9fcc4d66f0 100644 --- a/src/tsserver/tsconfig.json +++ b/src/tsserver/tsconfig.json @@ -14,6 +14,7 @@ { "path": "../compiler", "prepend": true }, { "path": "../services", "prepend": true }, { "path": "../jsTyping", "prepend": true }, - { "path": "../server", "prepend": true } + { "path": "../server", "prepend": true }, + { "path": "../compat", "prepend": true } ] } diff --git a/src/tsserverlibrary/tsconfig.json b/src/tsserverlibrary/tsconfig.json index f9953772f1fe9..b9012d8d6fc47 100644 --- a/src/tsserverlibrary/tsconfig.json +++ b/src/tsserverlibrary/tsconfig.json @@ -11,6 +11,7 @@ { "path": "../compiler", "prepend": true }, { "path": "../jsTyping", "prepend": true }, { "path": "../services", "prepend": true }, - { "path": "../server", "prepend": true } + { "path": "../server", "prepend": true }, + { "path": "../compat", "prepend": true } ] } diff --git a/src/typescriptServices/tsconfig.json b/src/typescriptServices/tsconfig.json index 33028aad27ce7..62b5d66f0f562 100644 --- a/src/typescriptServices/tsconfig.json +++ b/src/typescriptServices/tsconfig.json @@ -10,6 +10,7 @@ { "path": "../shims", "prepend": true }, { "path": "../compiler", "prepend": true }, { "path": "../jsTyping", "prepend": true }, - { "path": "../services", "prepend": true } + { "path": "../services", "prepend": true }, + { "path": "../compat", "prepend": true } ] } diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.@link tags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.@link tags.json index 9817af1157fb8..0d3b49aafba95 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.@link tags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.@link tags.json @@ -5,6 +5,7 @@ "flags": "JSDoc", "modifierFlagsCache": 0, "transformFlags": 0, + "comment": "{@link first link}\nInside {@link link text} thing", "tags": { "0": { "kind": "JSDocTag", @@ -24,7 +25,8 @@ }, "length": 1, "pos": 63, - "end": 68 - }, - "comment": "{@link first link}\nInside {@link link text} thing" + "end": 68, + "hasTrailingComma": false, + "transformFlags": 0 + } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json index 05eb12758911d..2c42878ec2605 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Nested @param tags.json @@ -20,6 +20,7 @@ "transformFlags": 0, "escapedText": "param" }, + "comment": "Doc doc", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 34, @@ -32,8 +33,8 @@ "end": 64, "modifierFlagsCache": 0, "transformFlags": 0, - "jsDocPropertyTags": [ - { + "jsDocPropertyTags": { + "0": { "kind": "JSDocParameterTag", "pos": 34, "end": 64, @@ -47,6 +48,7 @@ "transformFlags": 0, "escapedText": "param" }, + "comment": "Doc for f", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 41, @@ -58,7 +60,7 @@ "pos": 42, "end": 48, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -85,10 +87,15 @@ } }, "isNameFirst": false, - "isBracketed": false, - "comment": "Doc for f" - } - ] + "isBracketed": false + }, + "length": 1, + "pos": -1, + "end": -1, + "hasTrailingComma": false, + "transformFlags": 0 + }, + "isArrayType": false } }, "name": { @@ -100,11 +107,12 @@ "escapedText": "o" }, "isNameFirst": true, - "isBracketed": false, - "comment": "Doc doc" + "isBracketed": false }, "length": 1, "pos": 6, - "end": 64 + "end": 64, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json index 3a6ee3365dcfc..beadc1f572e2b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json @@ -20,6 +20,7 @@ "transformFlags": 0, "escapedText": "arg" }, + "comment": "Description", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 13, @@ -31,7 +32,7 @@ "pos": 14, "end": 20, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -43,11 +44,12 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "Description" + "isBracketed": false }, "length": 1, "pos": 8, - "end": 42 + "end": 42, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json index 2fa5734c1a36b..5ecb6ad069499 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json @@ -20,6 +20,7 @@ "transformFlags": 0, "escapedText": "argument" }, + "comment": "Description", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 18, @@ -31,7 +32,7 @@ "pos": 19, "end": 25, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -43,11 +44,12 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "Description" + "isBracketed": false }, "length": 1, "pos": 8, - "end": 47 + "end": 47, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json index eff1b97e80a73..b9e91293d73ed 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json @@ -40,6 +40,8 @@ }, "length": 2, "pos": 7, - "end": 110 + "end": 110, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json index 8f056c2da4045..1289886390bdf 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json @@ -32,12 +32,14 @@ "pos": 15, "end": 21, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } }, "length": 1, "pos": 8, - "end": 22 + "end": 22, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json index e0a57b72e9386..25c634c52caa8 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.less-than and greater-than characters.json @@ -20,6 +20,7 @@ "transformFlags": 0, "escapedText": "param" }, + "comment": "hi\n< > still part of the previous comment", "name": { "kind": "Identifier", "pos": 14, @@ -29,11 +30,12 @@ "escapedText": "x" }, "isNameFirst": true, - "isBracketed": false, - "comment": "hi\n< > still part of the previous comment" + "isBracketed": false }, "length": 1, "pos": 7, - "end": 59 + "end": 59, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json index 8f056c2da4045..1289886390bdf 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json @@ -32,12 +32,14 @@ "pos": 15, "end": 21, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } }, "length": 1, "pos": 8, - "end": 22 + "end": 22, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json index e0c0f1c97130a..e7e8b9d13d78b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json @@ -24,6 +24,8 @@ }, "length": 1, "pos": 8, - "end": 15 + "end": 15, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json index 1b072194d847e..be64961dc77bf 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json @@ -31,7 +31,7 @@ "pos": 16, "end": 22, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -47,6 +47,8 @@ }, "length": 1, "pos": 8, - "end": 32 + "end": 32, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json index 712ac49a36f19..f45eb771178a3 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json @@ -20,6 +20,7 @@ "transformFlags": 0, "escapedText": "param" }, + "comment": "Description text follows", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 15, @@ -31,7 +32,7 @@ "pos": 16, "end": 22, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -43,11 +44,12 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "Description text follows" + "isBracketed": false }, "length": 1, "pos": 8, - "end": 57 + "end": 57, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json index 3eebbc73ba904..0db3f02520e82 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName1.json @@ -20,6 +20,7 @@ "transformFlags": 0, "escapedText": "param" }, + "comment": "Description text follows", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 15, @@ -31,7 +32,7 @@ "pos": 16, "end": 22, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -43,11 +44,12 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": true, - "comment": "Description text follows" + "isBracketed": true }, "length": 1, "pos": 8, - "end": 59 + "end": 59, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json index d864cbeafd23e..71cb84f5ed793 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagBracketedName2.json @@ -20,6 +20,7 @@ "transformFlags": 0, "escapedText": "param" }, + "comment": "Description text follows", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 15, @@ -31,7 +32,7 @@ "pos": 16, "end": 22, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -43,11 +44,12 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": true, - "comment": "Description text follows" + "isBracketed": true }, "length": 1, "pos": 8, - "end": 64 + "end": 64, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json index 223d1e9510546..97a9e69010c1e 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json @@ -31,7 +31,7 @@ "pos": 22, "end": 28, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -47,6 +47,8 @@ }, "length": 1, "pos": 8, - "end": 32 + "end": 32, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json index 4c29e477e1078..a1bed4eb49b73 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json @@ -20,6 +20,7 @@ "transformFlags": 0, "escapedText": "param" }, + "comment": "Description", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 21, @@ -31,7 +32,7 @@ "pos": 22, "end": 28, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -43,11 +44,12 @@ "escapedText": "name1" }, "isNameFirst": true, - "isBracketed": false, - "comment": "Description" + "isBracketed": false }, "length": 1, "pos": 8, - "end": 44 + "end": 44, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json index c2cb7a167db4f..1143002ee91a8 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json @@ -33,6 +33,8 @@ }, "length": 1, "pos": 8, - "end": 21 + "end": 21, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json index a2d66247e1423..a7f96aa220f0d 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json @@ -32,12 +32,14 @@ "pos": 17, "end": 23, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } }, "length": 1, "pos": 8, - "end": 24 + "end": 24, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag2.json index 5fe9854187d2e..e243e4fb5e2f6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag2.json @@ -21,6 +21,7 @@ "originalKeywordKind": "ReturnKeyword", "escapedText": "return" }, + "comment": "Description text follows", "typeExpression": { "kind": "JSDocTypeExpression", "pos": 16, @@ -32,13 +33,14 @@ "pos": 17, "end": 23, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } - }, - "comment": "Description text follows" + } }, "length": 1, "pos": 8, - "end": 24 + "end": 24, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json index 3d1722eedc2f3..a0af3c57f2543 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json @@ -31,12 +31,14 @@ "pos": 18, "end": 24, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } }, "length": 1, "pos": 8, - "end": 25 + "end": 25, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json index 1e7cc39feb7eb..14d338f4368c3 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json @@ -26,7 +26,7 @@ "pos": 18, "end": 19, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 18, @@ -38,11 +38,15 @@ }, "length": 1, "pos": 18, - "end": 19 + "end": 19, + "hasTrailingComma": false, + "transformFlags": 1 } }, "length": 1, "pos": 8, - "end": 19 + "end": 19, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json index 0428568bdb461..0217b5efc5749 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json @@ -26,7 +26,7 @@ "pos": 18, "end": 19, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 18, @@ -41,7 +41,7 @@ "pos": 20, "end": 21, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 20, @@ -53,11 +53,15 @@ }, "length": 2, "pos": 18, - "end": 21 + "end": 21, + "hasTrailingComma": false, + "transformFlags": 1 } }, "length": 1, "pos": 8, - "end": 21 + "end": 21, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json index e7e6a0f30d0a5..1761d1f67b3c4 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json @@ -26,7 +26,7 @@ "pos": 18, "end": 19, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 18, @@ -41,7 +41,7 @@ "pos": 21, "end": 22, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 21, @@ -53,11 +53,15 @@ }, "length": 2, "pos": 18, - "end": 22 + "end": 22, + "hasTrailingComma": false, + "transformFlags": 1 } }, "length": 1, "pos": 8, - "end": 22 + "end": 22, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json index e7e6a0f30d0a5..1761d1f67b3c4 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json @@ -26,7 +26,7 @@ "pos": 18, "end": 19, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 18, @@ -41,7 +41,7 @@ "pos": 21, "end": 22, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 21, @@ -53,11 +53,15 @@ }, "length": 2, "pos": 18, - "end": 22 + "end": 22, + "hasTrailingComma": false, + "transformFlags": 1 } }, "length": 1, "pos": 8, - "end": 22 + "end": 22, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json index 1322ca477f237..d0faa579c0826 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json @@ -26,7 +26,7 @@ "pos": 18, "end": 19, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 18, @@ -41,7 +41,7 @@ "pos": 22, "end": 23, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 22, @@ -53,11 +53,15 @@ }, "length": 2, "pos": 18, - "end": 23 + "end": 23, + "hasTrailingComma": false, + "transformFlags": 1 } }, "length": 1, "pos": 8, - "end": 23 + "end": 23, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag6.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag6.json index c3e885082a69e..874e64567fba5 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag6.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag6.json @@ -20,13 +20,14 @@ "transformFlags": 0, "escapedText": "template" }, + "comment": "Description of type parameters.", "typeParameters": { "0": { "kind": "TypeParameter", "pos": 18, "end": 19, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 18, @@ -41,7 +42,7 @@ "pos": 22, "end": 23, "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 22, @@ -53,12 +54,15 @@ }, "length": 2, "pos": 18, - "end": 24 - }, - "comment": "Description of type parameters." + "end": 24, + "hasTrailingComma": false, + "transformFlags": 1 + } }, "length": 1, "pos": 8, - "end": 24 + "end": 24, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json index 5532f8fd2d170..8797eee4fef9f 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json @@ -31,7 +31,7 @@ "pos": 16, "end": 22, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -70,7 +70,7 @@ "pos": 42, "end": 48, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -86,6 +86,8 @@ }, "length": 2, "pos": 8, - "end": 58 + "end": 58, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json index 3d7c904d3055f..937fc3836d757 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json @@ -31,7 +31,7 @@ "pos": 16, "end": 22, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -70,7 +70,7 @@ "pos": 38, "end": 44, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -86,6 +86,8 @@ }, "length": 2, "pos": 8, - "end": 54 + "end": 54, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json index 8f056c2da4045..1289886390bdf 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json @@ -32,12 +32,14 @@ "pos": 15, "end": 21, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } }, "length": 1, "pos": 8, - "end": 22 + "end": 22, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json index 623073917980d..228d54b2e1c51 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json @@ -20,30 +20,14 @@ "transformFlags": 0, "escapedText": "typedef" }, - "fullName": { - "kind": "Identifier", - "pos": 17, - "end": 23, - "modifierFlagsCache": 0, - "transformFlags": 0, - "escapedText": "People" - }, - "name": { - "kind": "Identifier", - "pos": 17, - "end": 23, - "modifierFlagsCache": 0, - "transformFlags": 0, - "escapedText": "People" - }, "typeExpression": { "kind": "JSDocTypeLiteral", "pos": 8, "end": 100, "modifierFlagsCache": 0, "transformFlags": 0, - "jsDocPropertyTags": [ - { + "jsDocPropertyTags": { + "0": { "kind": "JSDocPropertyTag", "pos": 47, "end": 74, @@ -68,7 +52,7 @@ "pos": 58, "end": 64, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -82,7 +66,7 @@ "isNameFirst": false, "isBracketed": false }, - { + "1": { "kind": "JSDocPropertyTag", "pos": 74, "end": 100, @@ -107,7 +91,7 @@ "pos": 85, "end": 91, "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "name": { @@ -120,12 +104,36 @@ }, "isNameFirst": false, "isBracketed": false - } - ] + }, + "length": 2, + "pos": -1, + "end": -1, + "hasTrailingComma": false, + "transformFlags": 0 + }, + "isArrayType": false + }, + "fullName": { + "kind": "Identifier", + "pos": 17, + "end": 23, + "modifierFlagsCache": 0, + "transformFlags": 0, + "escapedText": "People" + }, + "name": { + "kind": "Identifier", + "pos": 17, + "end": 23, + "modifierFlagsCache": 0, + "transformFlags": 0, + "escapedText": "People" } }, "length": 1, "pos": 8, - "end": 100 + "end": 100, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType1.json index b7a03178849ba..1495118eb01fa 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType1.json @@ -4,14 +4,14 @@ "end": 4, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elementType": { "kind": "TypeReference", "pos": 1, "end": 2, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "Identifier", "pos": 1, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType2.json index eab2683341632..ec1b762ec8ae4 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType2.json @@ -4,21 +4,21 @@ "end": 6, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elementType": { "kind": "ArrayType", "pos": 1, "end": 4, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elementType": { "kind": "TypeReference", "pos": 1, "end": 2, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "Identifier", "pos": 1, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType3.json index 41333f0fec015..9ff034ed0c206 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.arrayType3.json @@ -11,28 +11,28 @@ "end": 8, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "ArrayType", "pos": 2, "end": 7, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elementType": { "kind": "ArrayType", "pos": 2, "end": 5, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elementType": { "kind": "TypeReference", "pos": 2, "end": 3, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "Identifier", "pos": 2, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.callSignatureInRecordType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.callSignatureInRecordType.json index 082dc6519065f..af72564535911 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.callSignatureInRecordType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.callSignatureInRecordType.json @@ -4,7 +4,7 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "CallSignature", @@ -12,11 +12,13 @@ "end": 12, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "parameters": { "length": 0, "pos": 3, - "end": 3 + "end": 3, + "hasTrailingComma": false, + "transformFlags": 0 }, "type": { "kind": "NumberKeyword", @@ -24,11 +26,13 @@ "end": 12, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "length": 1, "pos": 2, - "end": 12 + "end": 12, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionReturnType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionReturnType1.json index f1e75c25a3122..1f19771399fbf 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionReturnType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionReturnType1.json @@ -4,7 +4,7 @@ "end": 26, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "parameters": { "0": { "kind": "Parameter", @@ -12,14 +12,14 @@ "end": 16, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "StringKeyword", "pos": 10, "end": 16, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "1": { @@ -28,18 +28,20 @@ "end": 25, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "BooleanKeyword", "pos": 17, "end": 25, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "length": 2, "pos": 10, - "end": 25 + "end": 25, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType1.json index 6d466db8c64cc..ed1f75ffcb8c6 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType1.json @@ -8,6 +8,8 @@ "parameters": { "length": 0, "pos": 10, - "end": 10 + "end": 10, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType2.json index f1e75c25a3122..1f19771399fbf 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionType2.json @@ -4,7 +4,7 @@ "end": 26, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "parameters": { "0": { "kind": "Parameter", @@ -12,14 +12,14 @@ "end": 16, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "StringKeyword", "pos": 10, "end": 16, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "1": { @@ -28,18 +28,20 @@ "end": 25, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "BooleanKeyword", "pos": 17, "end": 25, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "length": 2, "pos": 10, - "end": 25 + "end": 25, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionTypeWithTrailingComma.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionTypeWithTrailingComma.json index e8fe1d2d3bbf9..d9f2543b29fec 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionTypeWithTrailingComma.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.functionTypeWithTrailingComma.json @@ -4,7 +4,7 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "parameters": { "0": { "kind": "Parameter", @@ -12,14 +12,14 @@ "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "TypeReference", "pos": 10, "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "Identifier", "pos": 10, @@ -34,6 +34,7 @@ "length": 1, "pos": 10, "end": 12, - "hasTrailingComma": true + "hasTrailingComma": true, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword1.json index 798749477c144..4dbd3f2959bf8 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword1.json @@ -4,7 +4,7 @@ "end": 4, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "Identifier", "pos": 1, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword2.json index 4259856647a0b..042e09174b62e 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword2.json @@ -1,8 +1,16 @@ { - "kind": "NullKeyword", + "kind": "LiteralType", "pos": 1, "end": 5, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1, + "literal": { + "kind": "NullKeyword", + "pos": 1, + "end": 5, + "flags": "JSDoc", + "modifierFlagsCache": 0, + "transformFlags": 0 + } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword3.json index 7fc6b62acdc56..13e057fbca4cf 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.keyword3.json @@ -4,5 +4,5 @@ "end": 10, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.methodInRecordType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.methodInRecordType.json index b0960589a80fb..96f5614bbdb6d 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.methodInRecordType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.methodInRecordType.json @@ -4,7 +4,7 @@ "end": 16, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "MethodSignature", @@ -12,7 +12,7 @@ "end": 15, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -25,7 +25,9 @@ "parameters": { "length": 0, "pos": 6, - "end": 6 + "end": 6, + "hasTrailingComma": false, + "transformFlags": 0 }, "type": { "kind": "NumberKeyword", @@ -33,11 +35,13 @@ "end": 15, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "length": 1, "pos": 2, - "end": 15 + "end": 15, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.newType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.newType1.json index 53a5267c708ea..48d7b66b2af24 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.newType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.newType1.json @@ -4,7 +4,7 @@ "end": 18, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "parameters": { "0": { "kind": "Parameter", @@ -12,7 +12,7 @@ "end": 17, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 10, @@ -29,7 +29,7 @@ "end": 17, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "FirstNode", "pos": 14, @@ -60,6 +60,8 @@ }, "length": 1, "pos": 10, - "end": 17 + "end": 17, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType.json index ff21ba236e2e5..6753df2cc0668 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType.json @@ -11,6 +11,6 @@ "end": 8, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType2.json index f4e88254a56ae..e579a0db6e3cd 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nonNullableType2.json @@ -11,6 +11,6 @@ "end": 7, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType.json index 3c9b183a7c49f..bdc4edb280e66 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType.json @@ -11,6 +11,6 @@ "end": 8, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType2.json index 1171dff7bb04a..44f20173cd3d7 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.nullableType2.json @@ -11,6 +11,6 @@ "end": 7, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalType.json index 089709f0ca1b8..0d684a34ade97 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.optionalType.json @@ -11,6 +11,6 @@ "end": 7, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType1.json index 19efd2d3d4802..f43b1bdac1823 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType1.json @@ -4,10 +4,12 @@ "end": 3, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "length": 0, "pos": 2, - "end": 2 + "end": 2, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType2.json index abbe1ac213cbf..9399b03826ced 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType2.json @@ -4,7 +4,7 @@ "end": 6, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "PropertySignature", @@ -12,7 +12,7 @@ "end": 5, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -25,6 +25,8 @@ }, "length": 1, "pos": 2, - "end": 5 + "end": 5, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType3.json index ae93512585cdd..95f7490af76ec 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType3.json @@ -4,7 +4,7 @@ "end": 14, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "PropertySignature", @@ -12,7 +12,7 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -28,11 +28,13 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "length": 1, "pos": 2, - "end": 13 + "end": 13, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType4.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType4.json index ac6ffce27b7b8..9a9b15f5698c0 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType4.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType4.json @@ -4,7 +4,7 @@ "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "PropertySignature", @@ -12,7 +12,7 @@ "end": 6, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -29,7 +29,7 @@ "end": 10, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 6, @@ -42,6 +42,8 @@ }, "length": 2, "pos": 2, - "end": 10 + "end": 10, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType5.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType5.json index 4b4aaac19fbb6..52c45d3efd7ff 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType5.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType5.json @@ -4,7 +4,7 @@ "end": 19, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "PropertySignature", @@ -12,7 +12,7 @@ "end": 14, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -28,7 +28,7 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "1": { @@ -37,7 +37,7 @@ "end": 18, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 14, @@ -50,6 +50,8 @@ }, "length": 2, "pos": 2, - "end": 18 + "end": 18, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType6.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType6.json index 6b74491eff17f..ecd6b5c14fb8f 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType6.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType6.json @@ -4,7 +4,7 @@ "end": 19, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "PropertySignature", @@ -12,7 +12,7 @@ "end": 6, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -29,7 +29,7 @@ "end": 18, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 6, @@ -45,11 +45,13 @@ "end": 18, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "length": 2, "pos": 2, - "end": 18 + "end": 18, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType7.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType7.json index 4bcda10cf317d..574f2c56badae 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType7.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType7.json @@ -4,7 +4,7 @@ "end": 27, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "PropertySignature", @@ -12,7 +12,7 @@ "end": 14, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -28,7 +28,7 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "1": { @@ -37,7 +37,7 @@ "end": 26, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 14, @@ -53,11 +53,13 @@ "end": 26, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } }, "length": 2, "pos": 2, - "end": 26 + "end": 26, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType8.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType8.json index 42ce502e7ec75..780a7289bd51c 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType8.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.recordType8.json @@ -4,7 +4,7 @@ "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "PropertySignature", @@ -12,7 +12,7 @@ "end": 10, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -26,6 +26,8 @@ }, "length": 1, "pos": 2, - "end": 10 + "end": 10, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.thisType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.thisType1.json index 8e0690303396c..2caf63ec50862 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.thisType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.thisType1.json @@ -4,7 +4,7 @@ "end": 19, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "parameters": { "0": { "kind": "Parameter", @@ -12,7 +12,7 @@ "end": 18, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 10, @@ -29,7 +29,7 @@ "end": 18, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "FirstNode", "pos": 15, @@ -60,6 +60,8 @@ }, "length": 1, "pos": 10, - "end": 18 + "end": 18, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.topLevelNoParenUnionType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.topLevelNoParenUnionType.json index 595ae4b849f9d..cecca945f8766 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.topLevelNoParenUnionType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.topLevelNoParenUnionType.json @@ -4,7 +4,7 @@ "end": 14, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "types": { "0": { "kind": "NumberKeyword", @@ -12,7 +12,7 @@ "end": 7, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "1": { "kind": "StringKeyword", @@ -20,10 +20,12 @@ "end": 14, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 2, "pos": 1, - "end": 14 + "end": 14, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.trailingCommaInRecordType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.trailingCommaInRecordType.json index 506f103861fc9..1c70750268db7 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.trailingCommaInRecordType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.trailingCommaInRecordType.json @@ -4,7 +4,7 @@ "end": 5, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "members": { "0": { "kind": "PropertySignature", @@ -12,7 +12,7 @@ "end": 4, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "name": { "kind": "Identifier", "pos": 2, @@ -25,6 +25,8 @@ }, "length": 1, "pos": 2, - "end": 4 + "end": 4, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsConstructorType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsConstructorType.json index 2f46004450214..bcbe47b7f7e53 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsConstructorType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsConstructorType.json @@ -4,11 +4,13 @@ "end": 17, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "parameters": { "length": 0, "pos": 6, - "end": 6 + "end": 6, + "hasTrailingComma": false, + "transformFlags": 0 }, "type": { "kind": "StringKeyword", @@ -16,6 +18,6 @@ "end": 17, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsFunctionType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsFunctionType.json index 2d2d81d602300..4308670e5c906 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsFunctionType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tsFunctionType.json @@ -4,11 +4,13 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "parameters": { "length": 0, "pos": 2, - "end": 2 + "end": 2, + "hasTrailingComma": false, + "transformFlags": 0 }, "type": { "kind": "StringKeyword", @@ -16,6 +18,6 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType0.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType0.json index 8bce108137668..d4edc50f085dd 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType0.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType0.json @@ -4,10 +4,12 @@ "end": 3, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elements": { "length": 0, "pos": 2, - "end": 2 + "end": 2, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType1.json index dc98f9164e73a..cbc7c4e5fef27 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType1.json @@ -4,7 +4,7 @@ "end": 9, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elements": { "0": { "kind": "NumberKeyword", @@ -12,10 +12,12 @@ "end": 8, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 1, "pos": 2, - "end": 8 + "end": 8, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType2.json index f6da41187797f..39cc53e916d14 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType2.json @@ -4,7 +4,7 @@ "end": 16, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elements": { "0": { "kind": "NumberKeyword", @@ -12,7 +12,7 @@ "end": 8, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "1": { "kind": "StringKeyword", @@ -20,10 +20,12 @@ "end": 15, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 2, "pos": 2, - "end": 15 + "end": 15, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType3.json index 08c3a7dbede68..3ffaae428a0e6 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleType3.json @@ -4,7 +4,7 @@ "end": 24, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elements": { "0": { "kind": "NumberKeyword", @@ -12,7 +12,7 @@ "end": 8, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "1": { "kind": "StringKeyword", @@ -20,7 +20,7 @@ "end": 15, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "2": { "kind": "BooleanKeyword", @@ -28,10 +28,12 @@ "end": 23, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 3, "pos": 2, - "end": 23 + "end": 23, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleTypeWithTrailingComma.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleTypeWithTrailingComma.json index da5978138999b..257d5ddf798f3 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleTypeWithTrailingComma.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.tupleTypeWithTrailingComma.json @@ -4,7 +4,7 @@ "end": 10, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "elements": { "0": { "kind": "NumberKeyword", @@ -12,11 +12,12 @@ "end": 8, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 1, "pos": 2, "end": 9, - "hasTrailingComma": true + "hasTrailingComma": true, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeArgumentsNotFollowingDot.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeArgumentsNotFollowingDot.json index 204592587352a..772888ef36f09 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeArgumentsNotFollowingDot.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeArgumentsNotFollowingDot.json @@ -4,7 +4,7 @@ "end": 4, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "Identifier", "pos": 1, @@ -17,6 +17,8 @@ "typeArguments": { "length": 0, "pos": 3, - "end": 3 + "end": 3, + "hasTrailingComma": false, + "transformFlags": 0 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeOfType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeOfType.json index dd8fd9f4c1bca..2d1f6a9d97e31 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeOfType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeOfType.json @@ -4,7 +4,7 @@ "end": 9, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "exprName": { "kind": "Identifier", "pos": 7, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json index 0ed013799e717..cfbef060a8516 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json @@ -4,7 +4,7 @@ "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "Identifier", "pos": 1, @@ -22,10 +22,12 @@ "end": 10, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 1, "pos": 4, - "end": 10 + "end": 10, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json index 43f0cec8d8225..3802cb3212932 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json @@ -4,7 +4,7 @@ "end": 18, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "Identifier", "pos": 1, @@ -22,7 +22,7 @@ "end": 10, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "1": { "kind": "StringKeyword", @@ -30,10 +30,12 @@ "end": 17, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 2, "pos": 4, - "end": 17 + "end": 17, + "hasTrailingComma": false, + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference3.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference3.json index 488c2d027abcf..b1d3af633c207 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference3.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference3.json @@ -4,7 +4,7 @@ "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "typeName": { "kind": "FirstNode", "pos": 1, diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionType.json index 0ae2d95021314..0d340996e327c 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionType.json @@ -4,14 +4,14 @@ "end": 16, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "UnionType", "pos": 2, "end": 15, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "types": { "0": { "kind": "NumberKeyword", @@ -19,7 +19,7 @@ "end": 8, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "1": { "kind": "StringKeyword", @@ -27,11 +27,13 @@ "end": 15, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 2, "pos": 2, - "end": 15 + "end": 15, + "hasTrailingComma": false, + "transformFlags": 1 } } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionTypeWithLeadingOperator.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionTypeWithLeadingOperator.json index fd53183d6168f..c41b696a22e4b 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionTypeWithLeadingOperator.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionTypeWithLeadingOperator.json @@ -4,14 +4,14 @@ "end": 22, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "UnionType", "pos": 2, "end": 20, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "types": { "0": { "kind": "NumberKeyword", @@ -19,7 +19,7 @@ "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "1": { "kind": "StringKeyword", @@ -27,11 +27,13 @@ "end": 20, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 2, "pos": 2, - "end": 20 + "end": 20, + "hasTrailingComma": false, + "transformFlags": 1 } } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionTypeWithOneElementAndLeadingOperator.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionTypeWithOneElementAndLeadingOperator.json index 7fd1b1b98f2b5..bf89e3afe8bb3 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionTypeWithOneElementAndLeadingOperator.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.unionTypeWithOneElementAndLeadingOperator.json @@ -4,14 +4,14 @@ "end": 13, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "type": { "kind": "UnionType", "pos": 2, "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0, + "transformFlags": 1, "types": { "0": { "kind": "NumberKeyword", @@ -19,11 +19,13 @@ "end": 11, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 }, "length": 1, "pos": 2, - "end": 11 + "end": 11, + "hasTrailingComma": false, + "transformFlags": 1 } } } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.variadicType.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.variadicType.json index 120a6da66c54d..d162c5260553f 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.variadicType.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.variadicType.json @@ -11,6 +11,6 @@ "end": 10, "flags": "JSDoc", "modifierFlagsCache": 0, - "transformFlags": 0 + "transformFlags": 1 } } \ No newline at end of file diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b777c66e3a281..012164ed997b3 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -70,9 +70,10 @@ declare namespace ts { pos: number; end: number; } - export type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; - export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword; - export type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; + export interface ReadonlyTextRange { + readonly pos: number; + readonly end: number; + } export enum SyntaxKind { Unknown = 0, EndOfFileToken = 1, @@ -443,6 +444,16 @@ declare namespace ts { FirstJSDocTagNode = 310, LastJSDocTagNode = 327, } + export type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; + export type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; + export type PseudoLiteralSyntaxKind = SyntaxKind.TemplateHead | SyntaxKind.TemplateMiddle | SyntaxKind.TemplateTail; + export type PunctuationSyntaxKind = SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.CloseParenToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.DotToken | SyntaxKind.DotDotDotToken | SyntaxKind.SemicolonToken | SyntaxKind.CommaToken | SyntaxKind.QuestionDotToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanSlashToken | SyntaxKind.GreaterThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.EqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.EqualsGreaterThanToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.AsteriskToken | SyntaxKind.AsteriskAsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.ExclamationToken | SyntaxKind.TildeToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.QuestionQuestionToken | SyntaxKind.QuestionToken | SyntaxKind.ColonToken | SyntaxKind.AtToken | SyntaxKind.BacktickToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken; + export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword; + export type ModifierSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.ConstKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.ExportKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.StaticKeyword; + export type KeywordTypeSyntaxKind = SyntaxKind.AnyKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VoidKeyword; + export type TokenSyntaxKind = SyntaxKind.Unknown | SyntaxKind.EndOfFileToken | TriviaSyntaxKind | LiteralSyntaxKind | PseudoLiteralSyntaxKind | PunctuationSyntaxKind | SyntaxKind.Identifier | KeywordSyntaxKind; + export type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; + export type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; export enum NodeFlags { None = 0, Let = 1, @@ -503,60 +514,91 @@ declare namespace ts { IntrinsicIndexedElement = 2, IntrinsicElement = 3 } - export interface Node extends TextRange { - kind: SyntaxKind; - flags: NodeFlags; - decorators?: NodeArray; - modifiers?: ModifiersArray; - parent: Node; + export interface Node extends ReadonlyTextRange { + readonly kind: SyntaxKind; + readonly flags: NodeFlags; + readonly decorators?: NodeArray; + readonly modifiers?: ModifiersArray; + readonly parent: Node; } export interface JSDocContainer { } - export type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | EndOfFileToken; + export type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | EndOfFileToken; export type HasType = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertySignature | PropertyDeclaration | TypePredicateNode | ParenthesizedTypeNode | TypeOperatorNode | MappedTypeNode | AssertionExpression | TypeAliasDeclaration | JSDocTypeExpression | JSDocNonNullableType | JSDocNullableType | JSDocOptionalType | JSDocVariadicType; export type HasTypeArguments = CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement | JsxSelfClosingElement; export type HasInitializer = HasExpressionInitializer | ForStatement | ForInStatement | ForOfStatement | JsxAttribute; export type HasExpressionInitializer = VariableDeclaration | ParameterDeclaration | BindingElement | PropertySignature | PropertyDeclaration | PropertyAssignment | EnumMember; - export interface NodeArray extends ReadonlyArray, TextRange { + export interface NodeArray extends ReadonlyArray, ReadonlyTextRange { hasTrailingComma?: boolean; } export interface Token extends Node { - kind: TKind; - } - export type DotToken = Token; - export type DotDotDotToken = Token; - export type QuestionToken = Token; - export type QuestionDotToken = Token; - export type ExclamationToken = Token; - export type ColonToken = Token; - export type EqualsToken = Token; - export type AsteriskToken = Token; - export type EqualsGreaterThanToken = Token; + readonly kind: TKind; + } export type EndOfFileToken = Token & JSDocContainer; - export type ReadonlyToken = Token; - export type AwaitKeywordToken = Token; - export type PlusToken = Token; - export type MinusToken = Token; - export type AssertsToken = Token; - export type Modifier = Token | Token | Token | Token | Token | Token | Token | Token | Token | Token | Token; + export interface PunctuationToken extends Token { + } + export type DotToken = PunctuationToken; + export type DotDotDotToken = PunctuationToken; + export type QuestionToken = PunctuationToken; + export type ExclamationToken = PunctuationToken; + export type ColonToken = PunctuationToken; + export type EqualsToken = PunctuationToken; + export type AsteriskToken = PunctuationToken; + export type EqualsGreaterThanToken = PunctuationToken; + export type PlusToken = PunctuationToken; + export type MinusToken = PunctuationToken; + export type QuestionDotToken = PunctuationToken; + export interface KeywordToken extends Token { + } + export type AssertsKeyword = KeywordToken; + export type AwaitKeyword = KeywordToken; + /** @deprecated Use `AwaitKeyword` instead. */ + export type AwaitKeywordToken = AwaitKeyword; + /** @deprecated Use `AssertsKeyword` instead. */ + export type AssertsToken = AssertsKeyword; + export interface ModifierToken extends KeywordToken { + } + export type AbstractKeyword = ModifierToken; + export type AsyncKeyword = ModifierToken; + export type ConstKeyword = ModifierToken; + export type DeclareKeyword = ModifierToken; + export type DefaultKeyword = ModifierToken; + export type ExportKeyword = ModifierToken; + export type PrivateKeyword = ModifierToken; + export type ProtectedKeyword = ModifierToken; + export type PublicKeyword = ModifierToken; + export type ReadonlyKeyword = ModifierToken; + export type StaticKeyword = ModifierToken; + /** @deprecated Use `ReadonlyKeyword` instead. */ + export type ReadonlyToken = ReadonlyKeyword; + export type Modifier = AbstractKeyword | AsyncKeyword | ConstKeyword | DeclareKeyword | DefaultKeyword | ExportKeyword | PrivateKeyword | ProtectedKeyword | PublicKeyword | ReadonlyKeyword | StaticKeyword; + export type AccessibilityModifier = PublicKeyword | PrivateKeyword | ProtectedKeyword; + export type ParameterPropertyModifier = AccessibilityModifier | ReadonlyKeyword; + export type ClassMemberModifier = AccessibilityModifier | ReadonlyKeyword | StaticKeyword; export type ModifiersArray = NodeArray; + export enum GeneratedIdentifierFlags { + None = 0, + ReservedInNestedScopes = 8, + Optimistic = 16, + FileLevel = 32 + } export interface Identifier extends PrimaryExpression, Declaration { - kind: SyntaxKind.Identifier; + readonly kind: SyntaxKind.Identifier; /** * Prefer to use `id.unescapedText`. (Note: This is available only in services, not internally to the TypeScript compiler.) * Text of identifier, but if the identifier begins with two underscores, this will begin with three. */ - escapedText: __String; - originalKeywordKind?: SyntaxKind; + readonly escapedText: __String; + readonly originalKeywordKind?: SyntaxKind; isInJSDocNamespace?: boolean; } export interface TransientIdentifier extends Identifier { resolvedSymbol: Symbol; } export interface QualifiedName extends Node { - kind: SyntaxKind.QualifiedName; - left: EntityName; - right: Identifier; + readonly kind: SyntaxKind.QualifiedName; + readonly left: EntityName; + readonly right: Identifier; } export type EntityName = Identifier | QualifiedName; export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier; @@ -565,135 +607,136 @@ declare namespace ts { _declarationBrand: any; } export interface NamedDeclaration extends Declaration { - name?: DeclarationName; + readonly name?: DeclarationName; } export interface DeclarationStatement extends NamedDeclaration, Statement { - name?: Identifier | StringLiteral | NumericLiteral; + readonly name?: Identifier | StringLiteral | NumericLiteral; } export interface ComputedPropertyName extends Node { - parent: Declaration; - kind: SyntaxKind.ComputedPropertyName; - expression: Expression; + readonly kind: SyntaxKind.ComputedPropertyName; + readonly parent: Declaration; + readonly expression: Expression; } export interface PrivateIdentifier extends Node { - kind: SyntaxKind.PrivateIdentifier; - escapedText: __String; + readonly kind: SyntaxKind.PrivateIdentifier; + readonly escapedText: __String; } export interface Decorator extends Node { - kind: SyntaxKind.Decorator; - parent: NamedDeclaration; - expression: LeftHandSideExpression; + readonly kind: SyntaxKind.Decorator; + readonly parent: NamedDeclaration; + readonly expression: LeftHandSideExpression; } export interface TypeParameterDeclaration extends NamedDeclaration { - kind: SyntaxKind.TypeParameter; - parent: DeclarationWithTypeParameterChildren | InferTypeNode; - name: Identifier; + readonly kind: SyntaxKind.TypeParameter; + readonly parent: DeclarationWithTypeParameterChildren | InferTypeNode; + readonly name: Identifier; /** Note: Consider calling `getEffectiveConstraintOfTypeParameter` */ - constraint?: TypeNode; - default?: TypeNode; + readonly constraint?: TypeNode; + readonly default?: TypeNode; expression?: Expression; } export interface SignatureDeclarationBase extends NamedDeclaration, JSDocContainer { - kind: SignatureDeclaration["kind"]; - name?: PropertyName; - typeParameters?: NodeArray; - parameters: NodeArray; - type?: TypeNode; + readonly kind: SignatureDeclaration["kind"]; + readonly name?: PropertyName; + readonly typeParameters?: NodeArray; + readonly parameters: NodeArray; + readonly type?: TypeNode; } export type SignatureDeclaration = CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | AccessorDeclaration | FunctionExpression | ArrowFunction; export interface CallSignatureDeclaration extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.CallSignature; + readonly kind: SyntaxKind.CallSignature; } export interface ConstructSignatureDeclaration extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.ConstructSignature; + readonly kind: SyntaxKind.ConstructSignature; } export type BindingName = Identifier | BindingPattern; export interface VariableDeclaration extends NamedDeclaration { - kind: SyntaxKind.VariableDeclaration; - parent: VariableDeclarationList | CatchClause; - name: BindingName; - exclamationToken?: ExclamationToken; - type?: TypeNode; - initializer?: Expression; + readonly kind: SyntaxKind.VariableDeclaration; + readonly parent: VariableDeclarationList | CatchClause; + readonly name: BindingName; + readonly exclamationToken?: ExclamationToken; + readonly type?: TypeNode; + readonly initializer?: Expression; } export interface VariableDeclarationList extends Node { - kind: SyntaxKind.VariableDeclarationList; - parent: VariableStatement | ForStatement | ForOfStatement | ForInStatement; - declarations: NodeArray; + readonly kind: SyntaxKind.VariableDeclarationList; + readonly parent: VariableStatement | ForStatement | ForOfStatement | ForInStatement; + readonly declarations: NodeArray; } export interface ParameterDeclaration extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.Parameter; - parent: SignatureDeclaration; - dotDotDotToken?: DotDotDotToken; - name: BindingName; - questionToken?: QuestionToken; - type?: TypeNode; - initializer?: Expression; + readonly kind: SyntaxKind.Parameter; + readonly parent: SignatureDeclaration; + readonly dotDotDotToken?: DotDotDotToken; + readonly name: BindingName; + readonly questionToken?: QuestionToken; + readonly type?: TypeNode; + readonly initializer?: Expression; } export interface BindingElement extends NamedDeclaration { - kind: SyntaxKind.BindingElement; - parent: BindingPattern; - propertyName?: PropertyName; - dotDotDotToken?: DotDotDotToken; - name: BindingName; - initializer?: Expression; + readonly kind: SyntaxKind.BindingElement; + readonly parent: BindingPattern; + readonly propertyName?: PropertyName; + readonly dotDotDotToken?: DotDotDotToken; + readonly name: BindingName; + readonly initializer?: Expression; } export interface PropertySignature extends TypeElement, JSDocContainer { - kind: SyntaxKind.PropertySignature; - name: PropertyName; - questionToken?: QuestionToken; - type?: TypeNode; + readonly kind: SyntaxKind.PropertySignature; + readonly name: PropertyName; + readonly questionToken?: QuestionToken; + readonly type?: TypeNode; initializer?: Expression; } export interface PropertyDeclaration extends ClassElement, JSDocContainer { - kind: SyntaxKind.PropertyDeclaration; - parent: ClassLikeDeclaration; - name: PropertyName; - questionToken?: QuestionToken; - exclamationToken?: ExclamationToken; - type?: TypeNode; - initializer?: Expression; + readonly kind: SyntaxKind.PropertyDeclaration; + readonly parent: ClassLikeDeclaration; + readonly name: PropertyName; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly type?: TypeNode; + readonly initializer?: Expression; } export interface ObjectLiteralElement extends NamedDeclaration { _objectLiteralBrand: any; - name?: PropertyName; + readonly name?: PropertyName; } /** Unlike ObjectLiteralElement, excludes JSXAttribute and JSXSpreadAttribute. */ export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | MethodDeclaration | AccessorDeclaration; export interface PropertyAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.PropertyAssignment; - name: PropertyName; - questionToken?: QuestionToken; - initializer: Expression; + readonly kind: SyntaxKind.PropertyAssignment; + readonly parent: ObjectLiteralExpression; + readonly name: PropertyName; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly initializer: Expression; } export interface ShorthandPropertyAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.ShorthandPropertyAssignment; - name: Identifier; - questionToken?: QuestionToken; - exclamationToken?: ExclamationToken; - equalsToken?: Token; - objectAssignmentInitializer?: Expression; + readonly kind: SyntaxKind.ShorthandPropertyAssignment; + readonly parent: ObjectLiteralExpression; + readonly name: Identifier; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly equalsToken?: EqualsToken; + readonly objectAssignmentInitializer?: Expression; } export interface SpreadAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.SpreadAssignment; - expression: Expression; + readonly kind: SyntaxKind.SpreadAssignment; + readonly parent: ObjectLiteralExpression; + readonly expression: Expression; } export type VariableLikeDeclaration = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyDeclaration | PropertyAssignment | PropertySignature | JsxAttribute | ShorthandPropertyAssignment | EnumMember | JSDocPropertyTag | JSDocParameterTag; export interface PropertyLikeDeclaration extends NamedDeclaration { - name: PropertyName; + readonly name: PropertyName; } export interface ObjectBindingPattern extends Node { - kind: SyntaxKind.ObjectBindingPattern; - parent: VariableDeclaration | ParameterDeclaration | BindingElement; - elements: NodeArray; + readonly kind: SyntaxKind.ObjectBindingPattern; + readonly parent: VariableDeclaration | ParameterDeclaration | BindingElement; + readonly elements: NodeArray; } export interface ArrayBindingPattern extends Node { - kind: SyntaxKind.ArrayBindingPattern; - parent: VariableDeclaration | ParameterDeclaration | BindingElement; - elements: NodeArray; + readonly kind: SyntaxKind.ArrayBindingPattern; + readonly parent: VariableDeclaration | ParameterDeclaration | BindingElement; + readonly elements: NodeArray; } export type BindingPattern = ObjectBindingPattern | ArrayBindingPattern; export type ArrayBindingElement = BindingElement | OmittedExpression; @@ -707,187 +750,189 @@ declare namespace ts { */ export interface FunctionLikeDeclarationBase extends SignatureDeclarationBase { _functionLikeDeclarationBrand: any; - asteriskToken?: AsteriskToken; - questionToken?: QuestionToken; - exclamationToken?: ExclamationToken; - body?: Block | Expression; + readonly asteriskToken?: AsteriskToken; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly body?: Block | Expression; } export type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction; /** @deprecated Use SignatureDeclaration */ export type FunctionLike = SignatureDeclaration; export interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { - kind: SyntaxKind.FunctionDeclaration; - name?: Identifier; - body?: FunctionBody; + readonly kind: SyntaxKind.FunctionDeclaration; + readonly name?: Identifier; + readonly body?: FunctionBody; } export interface MethodSignature extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.MethodSignature; - parent: ObjectTypeDeclaration; - name: PropertyName; + readonly kind: SyntaxKind.MethodSignature; + readonly parent: ObjectTypeDeclaration; + readonly name: PropertyName; } export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.MethodDeclaration; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.MethodDeclaration; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; } export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement, JSDocContainer { - kind: SyntaxKind.Constructor; - parent: ClassLikeDeclaration; - body?: FunctionBody; + readonly kind: SyntaxKind.Constructor; + readonly parent: ClassLikeDeclaration; + readonly body?: FunctionBody; } /** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */ export interface SemicolonClassElement extends ClassElement { - kind: SyntaxKind.SemicolonClassElement; - parent: ClassLikeDeclaration; + readonly kind: SyntaxKind.SemicolonClassElement; + readonly parent: ClassLikeDeclaration; } export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.GetAccessor; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.GetAccessor; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; } export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.SetAccessor; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.SetAccessor; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; } export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration; export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { - kind: SyntaxKind.IndexSignature; - parent: ObjectTypeDeclaration; + readonly kind: SyntaxKind.IndexSignature; + readonly parent: ObjectTypeDeclaration; + readonly type: TypeNode; } export interface TypeNode extends Node { _typeNodeBrand: any; } - export interface KeywordTypeNode extends TypeNode { - kind: SyntaxKind.AnyKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.NumberKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword | SyntaxKind.NeverKeyword; + export interface KeywordTypeNode extends KeywordToken, TypeNode { + readonly kind: TKind; } export interface ImportTypeNode extends NodeWithTypeArguments { - kind: SyntaxKind.ImportType; - isTypeOf?: boolean; - argument: TypeNode; - qualifier?: EntityName; + readonly kind: SyntaxKind.ImportType; + readonly isTypeOf: boolean; + readonly argument: TypeNode; + readonly qualifier?: EntityName; } export interface ThisTypeNode extends TypeNode { - kind: SyntaxKind.ThisType; + readonly kind: SyntaxKind.ThisType; } export type FunctionOrConstructorTypeNode = FunctionTypeNode | ConstructorTypeNode; export interface FunctionOrConstructorTypeNodeBase extends TypeNode, SignatureDeclarationBase { - kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType; - type: TypeNode; + readonly kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType; + readonly type: TypeNode; } export interface FunctionTypeNode extends FunctionOrConstructorTypeNodeBase { - kind: SyntaxKind.FunctionType; + readonly kind: SyntaxKind.FunctionType; } export interface ConstructorTypeNode extends FunctionOrConstructorTypeNodeBase { - kind: SyntaxKind.ConstructorType; + readonly kind: SyntaxKind.ConstructorType; } export interface NodeWithTypeArguments extends TypeNode { - typeArguments?: NodeArray; + readonly typeArguments?: NodeArray; } export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments; export interface TypeReferenceNode extends NodeWithTypeArguments { - kind: SyntaxKind.TypeReference; - typeName: EntityName; + readonly kind: SyntaxKind.TypeReference; + readonly typeName: EntityName; } export interface TypePredicateNode extends TypeNode { - kind: SyntaxKind.TypePredicate; - parent: SignatureDeclaration | JSDocTypeExpression; - assertsModifier?: AssertsToken; - parameterName: Identifier | ThisTypeNode; - type?: TypeNode; + readonly kind: SyntaxKind.TypePredicate; + readonly parent: SignatureDeclaration | JSDocTypeExpression; + readonly assertsModifier?: AssertsToken; + readonly parameterName: Identifier | ThisTypeNode; + readonly type?: TypeNode; } export interface TypeQueryNode extends TypeNode { - kind: SyntaxKind.TypeQuery; - exprName: EntityName; + readonly kind: SyntaxKind.TypeQuery; + readonly exprName: EntityName; } export interface TypeLiteralNode extends TypeNode, Declaration { - kind: SyntaxKind.TypeLiteral; - members: NodeArray; + readonly kind: SyntaxKind.TypeLiteral; + readonly members: NodeArray; } export interface ArrayTypeNode extends TypeNode { - kind: SyntaxKind.ArrayType; - elementType: TypeNode; + readonly kind: SyntaxKind.ArrayType; + readonly elementType: TypeNode; } export interface TupleTypeNode extends TypeNode { - kind: SyntaxKind.TupleType; - elements: NodeArray; + readonly kind: SyntaxKind.TupleType; + readonly elements: NodeArray; } export interface NamedTupleMember extends TypeNode, JSDocContainer, Declaration { - kind: SyntaxKind.NamedTupleMember; - dotDotDotToken?: Token; - name: Identifier; - questionToken?: Token; - type: TypeNode; + readonly kind: SyntaxKind.NamedTupleMember; + readonly dotDotDotToken?: Token; + readonly name: Identifier; + readonly questionToken?: Token; + readonly type: TypeNode; } export interface OptionalTypeNode extends TypeNode { - kind: SyntaxKind.OptionalType; - type: TypeNode; + readonly kind: SyntaxKind.OptionalType; + readonly type: TypeNode; } export interface RestTypeNode extends TypeNode { - kind: SyntaxKind.RestType; - type: TypeNode; + readonly kind: SyntaxKind.RestType; + readonly type: TypeNode; } export type UnionOrIntersectionTypeNode = UnionTypeNode | IntersectionTypeNode; export interface UnionTypeNode extends TypeNode { - kind: SyntaxKind.UnionType; - types: NodeArray; + readonly kind: SyntaxKind.UnionType; + readonly types: NodeArray; } export interface IntersectionTypeNode extends TypeNode { - kind: SyntaxKind.IntersectionType; - types: NodeArray; + readonly kind: SyntaxKind.IntersectionType; + readonly types: NodeArray; } export interface ConditionalTypeNode extends TypeNode { - kind: SyntaxKind.ConditionalType; - checkType: TypeNode; - extendsType: TypeNode; - trueType: TypeNode; - falseType: TypeNode; + readonly kind: SyntaxKind.ConditionalType; + readonly checkType: TypeNode; + readonly extendsType: TypeNode; + readonly trueType: TypeNode; + readonly falseType: TypeNode; } export interface InferTypeNode extends TypeNode { - kind: SyntaxKind.InferType; - typeParameter: TypeParameterDeclaration; + readonly kind: SyntaxKind.InferType; + readonly typeParameter: TypeParameterDeclaration; } export interface ParenthesizedTypeNode extends TypeNode { - kind: SyntaxKind.ParenthesizedType; - type: TypeNode; + readonly kind: SyntaxKind.ParenthesizedType; + readonly type: TypeNode; } export interface TypeOperatorNode extends TypeNode { - kind: SyntaxKind.TypeOperator; - operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword; - type: TypeNode; + readonly kind: SyntaxKind.TypeOperator; + readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword; + readonly type: TypeNode; } export interface IndexedAccessTypeNode extends TypeNode { - kind: SyntaxKind.IndexedAccessType; - objectType: TypeNode; - indexType: TypeNode; + readonly kind: SyntaxKind.IndexedAccessType; + readonly objectType: TypeNode; + readonly indexType: TypeNode; } export interface MappedTypeNode extends TypeNode, Declaration { - kind: SyntaxKind.MappedType; - readonlyToken?: ReadonlyToken | PlusToken | MinusToken; - typeParameter: TypeParameterDeclaration; - questionToken?: QuestionToken | PlusToken | MinusToken; - type?: TypeNode; + readonly kind: SyntaxKind.MappedType; + readonly readonlyToken?: ReadonlyToken | PlusToken | MinusToken; + readonly typeParameter: TypeParameterDeclaration; + readonly questionToken?: QuestionToken | PlusToken | MinusToken; + readonly type?: TypeNode; } export interface LiteralTypeNode extends TypeNode { - kind: SyntaxKind.LiteralType; - literal: BooleanLiteral | LiteralExpression | PrefixUnaryExpression; + readonly kind: SyntaxKind.LiteralType; + readonly literal: NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression; } export interface StringLiteral extends LiteralExpression, Declaration { - kind: SyntaxKind.StringLiteral; + readonly kind: SyntaxKind.StringLiteral; } export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral; + export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral; export interface Expression extends Node { _expressionBrand: any; } export interface OmittedExpression extends Expression { - kind: SyntaxKind.OmittedExpression; + readonly kind: SyntaxKind.OmittedExpression; } export interface PartiallyEmittedExpression extends LeftHandSideExpression { - kind: SyntaxKind.PartiallyEmittedExpression; - expression: Expression; + readonly kind: SyntaxKind.PartiallyEmittedExpression; + readonly expression: Expression; } export interface UnaryExpression extends Expression { _unaryExpressionBrand: any; @@ -899,15 +944,15 @@ declare namespace ts { } export type PrefixUnaryOperator = SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken; export interface PrefixUnaryExpression extends UpdateExpression { - kind: SyntaxKind.PrefixUnaryExpression; - operator: PrefixUnaryOperator; - operand: UnaryExpression; + readonly kind: SyntaxKind.PrefixUnaryExpression; + readonly operator: PrefixUnaryOperator; + readonly operand: UnaryExpression; } export type PostfixUnaryOperator = SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken; export interface PostfixUnaryExpression extends UpdateExpression { - kind: SyntaxKind.PostfixUnaryExpression; - operand: LeftHandSideExpression; - operator: PostfixUnaryOperator; + readonly kind: SyntaxKind.PostfixUnaryExpression; + readonly operand: LeftHandSideExpression; + readonly operator: PostfixUnaryOperator; } export interface LeftHandSideExpression extends UpdateExpression { _leftHandSideExpressionBrand: any; @@ -918,47 +963,51 @@ declare namespace ts { export interface PrimaryExpression extends MemberExpression { _primaryExpressionBrand: any; } - export interface NullLiteral extends PrimaryExpression, TypeNode { - kind: SyntaxKind.NullKeyword; + export interface NullLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.NullKeyword; } - export interface BooleanLiteral extends PrimaryExpression, TypeNode { - kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword; + export interface TrueLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.TrueKeyword; } - export interface ThisExpression extends PrimaryExpression, KeywordTypeNode { - kind: SyntaxKind.ThisKeyword; + export interface FalseLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.FalseKeyword; + } + export type BooleanLiteral = TrueLiteral | FalseLiteral; + export interface ThisExpression extends PrimaryExpression { + readonly kind: SyntaxKind.ThisKeyword; } export interface SuperExpression extends PrimaryExpression { - kind: SyntaxKind.SuperKeyword; + readonly kind: SyntaxKind.SuperKeyword; } export interface ImportExpression extends PrimaryExpression { - kind: SyntaxKind.ImportKeyword; + readonly kind: SyntaxKind.ImportKeyword; } export interface DeleteExpression extends UnaryExpression { - kind: SyntaxKind.DeleteExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.DeleteExpression; + readonly expression: UnaryExpression; } export interface TypeOfExpression extends UnaryExpression { - kind: SyntaxKind.TypeOfExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.TypeOfExpression; + readonly expression: UnaryExpression; } export interface VoidExpression extends UnaryExpression { - kind: SyntaxKind.VoidExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.VoidExpression; + readonly expression: UnaryExpression; } export interface AwaitExpression extends UnaryExpression { - kind: SyntaxKind.AwaitExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.AwaitExpression; + readonly expression: UnaryExpression; } export interface YieldExpression extends Expression { - kind: SyntaxKind.YieldExpression; - asteriskToken?: AsteriskToken; - expression?: Expression; + readonly kind: SyntaxKind.YieldExpression; + readonly asteriskToken?: AsteriskToken; + readonly expression?: Expression; } export interface SyntheticExpression extends Expression { - kind: SyntaxKind.SyntheticExpression; - isSpread: boolean; - type: Type; - tupleNameSource?: ParameterDeclaration | NamedTupleMember; + readonly kind: SyntaxKind.SyntheticExpression; + readonly isSpread: boolean; + readonly type: Type; + readonly tupleNameSource?: ParameterDeclaration | NamedTupleMember; } export type ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken; export type MultiplicativeOperator = SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken; @@ -982,24 +1031,26 @@ declare namespace ts { export type LogicalOrCoalescingAssignmentOperator = SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.QuestionQuestionEqualsToken; export type BinaryOperatorToken = Token; export interface BinaryExpression extends Expression, Declaration { - kind: SyntaxKind.BinaryExpression; - left: Expression; - operatorToken: BinaryOperatorToken; - right: Expression; + readonly kind: SyntaxKind.BinaryExpression; + readonly left: Expression; + readonly operatorToken: BinaryOperatorToken; + readonly right: Expression; } export type AssignmentOperatorToken = Token; export interface AssignmentExpression extends BinaryExpression { - left: LeftHandSideExpression; - operatorToken: TOperator; + readonly left: LeftHandSideExpression; + readonly operatorToken: TOperator; } export interface ObjectDestructuringAssignment extends AssignmentExpression { - left: ObjectLiteralExpression; + readonly left: ObjectLiteralExpression; } export interface ArrayDestructuringAssignment extends AssignmentExpression { - left: ArrayLiteralExpression; + readonly left: ArrayLiteralExpression; } export type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment; - export type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; + export type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | ObjectBindingOrAssignmentElement | ArrayBindingOrAssignmentElement; + export type ObjectBindingOrAssignmentElement = BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment; + export type ArrayBindingOrAssignmentElement = BindingElement | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; export type BindingOrAssignmentElementRestIndicator = DotDotDotToken | SpreadElement | SpreadAssignment; export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; export type ObjectBindingOrAssignmentPattern = ObjectBindingPattern | ObjectLiteralExpression; @@ -1007,25 +1058,25 @@ declare namespace ts { export type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression; export type BindingOrAssignmentPattern = ObjectBindingOrAssignmentPattern | ArrayBindingOrAssignmentPattern; export interface ConditionalExpression extends Expression { - kind: SyntaxKind.ConditionalExpression; - condition: Expression; - questionToken: QuestionToken; - whenTrue: Expression; - colonToken: ColonToken; - whenFalse: Expression; + readonly kind: SyntaxKind.ConditionalExpression; + readonly condition: Expression; + readonly questionToken: QuestionToken; + readonly whenTrue: Expression; + readonly colonToken: ColonToken; + readonly whenFalse: Expression; } export type FunctionBody = Block; export type ConciseBody = FunctionBody | Expression; export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { - kind: SyntaxKind.FunctionExpression; - name?: Identifier; - body: FunctionBody; + readonly kind: SyntaxKind.FunctionExpression; + readonly name?: Identifier; + readonly body: FunctionBody; } export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase, JSDocContainer { - kind: SyntaxKind.ArrowFunction; - equalsGreaterThanToken: EqualsGreaterThanToken; - body: ConciseBody; - name: never; + readonly kind: SyntaxKind.ArrowFunction; + readonly equalsGreaterThanToken: EqualsGreaterThanToken; + readonly body: ConciseBody; + readonly name: never; } export interface LiteralLikeNode extends Node { text: string; @@ -1039,10 +1090,10 @@ declare namespace ts { _literalExpressionBrand: any; } export interface RegularExpressionLiteral extends LiteralExpression { - kind: SyntaxKind.RegularExpressionLiteral; + readonly kind: SyntaxKind.RegularExpressionLiteral; } export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode, Declaration { - kind: SyntaxKind.NoSubstitutionTemplateLiteral; + readonly kind: SyntaxKind.NoSubstitutionTemplateLiteral; } export enum TokenFlags { None = 0, @@ -1053,47 +1104,50 @@ declare namespace ts { OctalSpecifier = 256, } export interface NumericLiteral extends LiteralExpression, Declaration { - kind: SyntaxKind.NumericLiteral; + readonly kind: SyntaxKind.NumericLiteral; } export interface BigIntLiteral extends LiteralExpression { - kind: SyntaxKind.BigIntLiteral; + readonly kind: SyntaxKind.BigIntLiteral; } + export type LiteralToken = NumericLiteral | BigIntLiteral | StringLiteral | JsxText | RegularExpressionLiteral | NoSubstitutionTemplateLiteral; export interface TemplateHead extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateHead; - parent: TemplateExpression; + readonly kind: SyntaxKind.TemplateHead; + readonly parent: TemplateExpression; } export interface TemplateMiddle extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateMiddle; - parent: TemplateSpan; + readonly kind: SyntaxKind.TemplateMiddle; + readonly parent: TemplateSpan; } export interface TemplateTail extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateTail; - parent: TemplateSpan; + readonly kind: SyntaxKind.TemplateTail; + readonly parent: TemplateSpan; } - export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral; + export type PseudoLiteralToken = TemplateHead | TemplateMiddle | TemplateTail; + export type TemplateLiteralToken = NoSubstitutionTemplateLiteral | PseudoLiteralToken; export interface TemplateExpression extends PrimaryExpression { - kind: SyntaxKind.TemplateExpression; - head: TemplateHead; - templateSpans: NodeArray; + readonly kind: SyntaxKind.TemplateExpression; + readonly head: TemplateHead; + readonly templateSpans: NodeArray; } + export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral; export interface TemplateSpan extends Node { - kind: SyntaxKind.TemplateSpan; - parent: TemplateExpression; - expression: Expression; - literal: TemplateMiddle | TemplateTail; + readonly kind: SyntaxKind.TemplateSpan; + readonly parent: TemplateExpression; + readonly expression: Expression; + readonly literal: TemplateMiddle | TemplateTail; } export interface ParenthesizedExpression extends PrimaryExpression, JSDocContainer { - kind: SyntaxKind.ParenthesizedExpression; - expression: Expression; + readonly kind: SyntaxKind.ParenthesizedExpression; + readonly expression: Expression; } export interface ArrayLiteralExpression extends PrimaryExpression { - kind: SyntaxKind.ArrayLiteralExpression; - elements: NodeArray; + readonly kind: SyntaxKind.ArrayLiteralExpression; + readonly elements: NodeArray; } export interface SpreadElement extends Expression { - kind: SyntaxKind.SpreadElement; - parent: ArrayLiteralExpression | CallExpression | NewExpression; - expression: Expression; + readonly kind: SyntaxKind.SpreadElement; + readonly parent: ArrayLiteralExpression | CallExpression | NewExpression; + readonly expression: Expression; } /** * This interface is a base interface for ObjectLiteralExpression and JSXAttributes to extend from. JSXAttributes is similar to @@ -1102,388 +1156,389 @@ declare namespace ts { * ObjectLiteralElement (e.g. PropertyAssignment, ShorthandPropertyAssignment etc.) */ export interface ObjectLiteralExpressionBase extends PrimaryExpression, Declaration { - properties: NodeArray; + readonly properties: NodeArray; } export interface ObjectLiteralExpression extends ObjectLiteralExpressionBase { - kind: SyntaxKind.ObjectLiteralExpression; + readonly kind: SyntaxKind.ObjectLiteralExpression; } export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression; export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; + export type AccessExpression = PropertyAccessExpression | ElementAccessExpression; export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration { - kind: SyntaxKind.PropertyAccessExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - name: Identifier | PrivateIdentifier; + readonly kind: SyntaxKind.PropertyAccessExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly name: Identifier | PrivateIdentifier; } export interface PropertyAccessChain extends PropertyAccessExpression { _optionalChainBrand: any; - name: Identifier; + readonly name: Identifier | PrivateIdentifier; } export interface SuperPropertyAccessExpression extends PropertyAccessExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; - expression: EntityNameExpression; - name: Identifier; + readonly expression: EntityNameExpression; + readonly name: Identifier; } export interface ElementAccessExpression extends MemberExpression { - kind: SyntaxKind.ElementAccessExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - argumentExpression: Expression; + readonly kind: SyntaxKind.ElementAccessExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly argumentExpression: Expression; } export interface ElementAccessChain extends ElementAccessExpression { _optionalChainBrand: any; } export interface SuperElementAccessExpression extends ElementAccessExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } export type SuperProperty = SuperPropertyAccessExpression | SuperElementAccessExpression; export interface CallExpression extends LeftHandSideExpression, Declaration { - kind: SyntaxKind.CallExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - typeArguments?: NodeArray; - arguments: NodeArray; + readonly kind: SyntaxKind.CallExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly typeArguments?: NodeArray; + readonly arguments: NodeArray; } export interface CallChain extends CallExpression { _optionalChainBrand: any; } export type OptionalChain = PropertyAccessChain | ElementAccessChain | CallChain | NonNullChain; export interface SuperCall extends CallExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } export interface ImportCall extends CallExpression { - expression: ImportExpression; + readonly expression: ImportExpression; } export interface ExpressionWithTypeArguments extends NodeWithTypeArguments { - kind: SyntaxKind.ExpressionWithTypeArguments; - parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; - expression: LeftHandSideExpression; + readonly kind: SyntaxKind.ExpressionWithTypeArguments; + readonly parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; + readonly expression: LeftHandSideExpression; } export interface NewExpression extends PrimaryExpression, Declaration { - kind: SyntaxKind.NewExpression; - expression: LeftHandSideExpression; - typeArguments?: NodeArray; - arguments?: NodeArray; + readonly kind: SyntaxKind.NewExpression; + readonly expression: LeftHandSideExpression; + readonly typeArguments?: NodeArray; + readonly arguments?: NodeArray; } export interface TaggedTemplateExpression extends MemberExpression { - kind: SyntaxKind.TaggedTemplateExpression; - tag: LeftHandSideExpression; - typeArguments?: NodeArray; - template: TemplateLiteral; + readonly kind: SyntaxKind.TaggedTemplateExpression; + readonly tag: LeftHandSideExpression; + readonly typeArguments?: NodeArray; + readonly template: TemplateLiteral; } export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; export interface AsExpression extends Expression { - kind: SyntaxKind.AsExpression; - expression: Expression; - type: TypeNode; + readonly kind: SyntaxKind.AsExpression; + readonly expression: Expression; + readonly type: TypeNode; } export interface TypeAssertion extends UnaryExpression { - kind: SyntaxKind.TypeAssertionExpression; - type: TypeNode; - expression: UnaryExpression; + readonly kind: SyntaxKind.TypeAssertionExpression; + readonly type: TypeNode; + readonly expression: UnaryExpression; } export type AssertionExpression = TypeAssertion | AsExpression; export interface NonNullExpression extends LeftHandSideExpression { - kind: SyntaxKind.NonNullExpression; - expression: Expression; + readonly kind: SyntaxKind.NonNullExpression; + readonly expression: Expression; } export interface NonNullChain extends NonNullExpression { _optionalChainBrand: any; } export interface MetaProperty extends PrimaryExpression { - kind: SyntaxKind.MetaProperty; - keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; - name: Identifier; + readonly kind: SyntaxKind.MetaProperty; + readonly keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; + readonly name: Identifier; } export interface JsxElement extends PrimaryExpression { - kind: SyntaxKind.JsxElement; - openingElement: JsxOpeningElement; - children: NodeArray; - closingElement: JsxClosingElement; + readonly kind: SyntaxKind.JsxElement; + readonly openingElement: JsxOpeningElement; + readonly children: NodeArray; + readonly closingElement: JsxClosingElement; } export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; export type JsxTagNameExpression = Identifier | ThisExpression | JsxTagNamePropertyAccess; export interface JsxTagNamePropertyAccess extends PropertyAccessExpression { - expression: JsxTagNameExpression; + readonly expression: JsxTagNameExpression; } export interface JsxAttributes extends ObjectLiteralExpressionBase { - kind: SyntaxKind.JsxAttributes; - parent: JsxOpeningLikeElement; + readonly kind: SyntaxKind.JsxAttributes; + readonly parent: JsxOpeningLikeElement; } export interface JsxOpeningElement extends Expression { - kind: SyntaxKind.JsxOpeningElement; - parent: JsxElement; - tagName: JsxTagNameExpression; - typeArguments?: NodeArray; - attributes: JsxAttributes; + readonly kind: SyntaxKind.JsxOpeningElement; + readonly parent: JsxElement; + readonly tagName: JsxTagNameExpression; + readonly typeArguments?: NodeArray; + readonly attributes: JsxAttributes; } export interface JsxSelfClosingElement extends PrimaryExpression { - kind: SyntaxKind.JsxSelfClosingElement; - tagName: JsxTagNameExpression; - typeArguments?: NodeArray; - attributes: JsxAttributes; + readonly kind: SyntaxKind.JsxSelfClosingElement; + readonly tagName: JsxTagNameExpression; + readonly typeArguments?: NodeArray; + readonly attributes: JsxAttributes; } export interface JsxFragment extends PrimaryExpression { - kind: SyntaxKind.JsxFragment; - openingFragment: JsxOpeningFragment; - children: NodeArray; - closingFragment: JsxClosingFragment; + readonly kind: SyntaxKind.JsxFragment; + readonly openingFragment: JsxOpeningFragment; + readonly children: NodeArray; + readonly closingFragment: JsxClosingFragment; } export interface JsxOpeningFragment extends Expression { - kind: SyntaxKind.JsxOpeningFragment; - parent: JsxFragment; + readonly kind: SyntaxKind.JsxOpeningFragment; + readonly parent: JsxFragment; } export interface JsxClosingFragment extends Expression { - kind: SyntaxKind.JsxClosingFragment; - parent: JsxFragment; + readonly kind: SyntaxKind.JsxClosingFragment; + readonly parent: JsxFragment; } export interface JsxAttribute extends ObjectLiteralElement { - kind: SyntaxKind.JsxAttribute; - parent: JsxAttributes; - name: Identifier; - initializer?: StringLiteral | JsxExpression; + readonly kind: SyntaxKind.JsxAttribute; + readonly parent: JsxAttributes; + readonly name: Identifier; + readonly initializer?: StringLiteral | JsxExpression; } export interface JsxSpreadAttribute extends ObjectLiteralElement { - kind: SyntaxKind.JsxSpreadAttribute; - parent: JsxAttributes; - expression: Expression; + readonly kind: SyntaxKind.JsxSpreadAttribute; + readonly parent: JsxAttributes; + readonly expression: Expression; } export interface JsxClosingElement extends Node { - kind: SyntaxKind.JsxClosingElement; - parent: JsxElement; - tagName: JsxTagNameExpression; + readonly kind: SyntaxKind.JsxClosingElement; + readonly parent: JsxElement; + readonly tagName: JsxTagNameExpression; } export interface JsxExpression extends Expression { - kind: SyntaxKind.JsxExpression; - parent: JsxElement | JsxAttributeLike; - dotDotDotToken?: Token; - expression?: Expression; + readonly kind: SyntaxKind.JsxExpression; + readonly parent: JsxElement | JsxAttributeLike; + readonly dotDotDotToken?: Token; + readonly expression?: Expression; } export interface JsxText extends LiteralLikeNode { - kind: SyntaxKind.JsxText; - containsOnlyTriviaWhiteSpaces: boolean; - parent: JsxElement; + readonly kind: SyntaxKind.JsxText; + readonly parent: JsxElement; + readonly containsOnlyTriviaWhiteSpaces: boolean; } export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment; export interface Statement extends Node { _statementBrand: any; } export interface NotEmittedStatement extends Statement { - kind: SyntaxKind.NotEmittedStatement; + readonly kind: SyntaxKind.NotEmittedStatement; } /** * A list of comma-separated expressions. This node is only created by transformations. */ export interface CommaListExpression extends Expression { - kind: SyntaxKind.CommaListExpression; - elements: NodeArray; + readonly kind: SyntaxKind.CommaListExpression; + readonly elements: NodeArray; } export interface EmptyStatement extends Statement { - kind: SyntaxKind.EmptyStatement; + readonly kind: SyntaxKind.EmptyStatement; } export interface DebuggerStatement extends Statement { - kind: SyntaxKind.DebuggerStatement; + readonly kind: SyntaxKind.DebuggerStatement; } export interface MissingDeclaration extends DeclarationStatement { - kind: SyntaxKind.MissingDeclaration; - name?: Identifier; + readonly kind: SyntaxKind.MissingDeclaration; + readonly name?: Identifier; } export type BlockLike = SourceFile | Block | ModuleBlock | CaseOrDefaultClause; export interface Block extends Statement { - kind: SyntaxKind.Block; - statements: NodeArray; + readonly kind: SyntaxKind.Block; + readonly statements: NodeArray; } export interface VariableStatement extends Statement, JSDocContainer { - kind: SyntaxKind.VariableStatement; - declarationList: VariableDeclarationList; + readonly kind: SyntaxKind.VariableStatement; + readonly declarationList: VariableDeclarationList; } export interface ExpressionStatement extends Statement, JSDocContainer { - kind: SyntaxKind.ExpressionStatement; - expression: Expression; + readonly kind: SyntaxKind.ExpressionStatement; + readonly expression: Expression; } export interface IfStatement extends Statement { - kind: SyntaxKind.IfStatement; - expression: Expression; - thenStatement: Statement; - elseStatement?: Statement; + readonly kind: SyntaxKind.IfStatement; + readonly expression: Expression; + readonly thenStatement: Statement; + readonly elseStatement?: Statement; } export interface IterationStatement extends Statement { - statement: Statement; + readonly statement: Statement; } export interface DoStatement extends IterationStatement { - kind: SyntaxKind.DoStatement; - expression: Expression; + readonly kind: SyntaxKind.DoStatement; + readonly expression: Expression; } export interface WhileStatement extends IterationStatement { - kind: SyntaxKind.WhileStatement; - expression: Expression; + readonly kind: SyntaxKind.WhileStatement; + readonly expression: Expression; } export type ForInitializer = VariableDeclarationList | Expression; export interface ForStatement extends IterationStatement { - kind: SyntaxKind.ForStatement; - initializer?: ForInitializer; - condition?: Expression; - incrementor?: Expression; + readonly kind: SyntaxKind.ForStatement; + readonly initializer?: ForInitializer; + readonly condition?: Expression; + readonly incrementor?: Expression; } export type ForInOrOfStatement = ForInStatement | ForOfStatement; export interface ForInStatement extends IterationStatement { - kind: SyntaxKind.ForInStatement; - initializer: ForInitializer; - expression: Expression; + readonly kind: SyntaxKind.ForInStatement; + readonly initializer: ForInitializer; + readonly expression: Expression; } export interface ForOfStatement extends IterationStatement { - kind: SyntaxKind.ForOfStatement; - awaitModifier?: AwaitKeywordToken; - initializer: ForInitializer; - expression: Expression; + readonly kind: SyntaxKind.ForOfStatement; + readonly awaitModifier?: AwaitKeywordToken; + readonly initializer: ForInitializer; + readonly expression: Expression; } export interface BreakStatement extends Statement { - kind: SyntaxKind.BreakStatement; - label?: Identifier; + readonly kind: SyntaxKind.BreakStatement; + readonly label?: Identifier; } export interface ContinueStatement extends Statement { - kind: SyntaxKind.ContinueStatement; - label?: Identifier; + readonly kind: SyntaxKind.ContinueStatement; + readonly label?: Identifier; } export type BreakOrContinueStatement = BreakStatement | ContinueStatement; export interface ReturnStatement extends Statement { - kind: SyntaxKind.ReturnStatement; - expression?: Expression; + readonly kind: SyntaxKind.ReturnStatement; + readonly expression?: Expression; } export interface WithStatement extends Statement { - kind: SyntaxKind.WithStatement; - expression: Expression; - statement: Statement; + readonly kind: SyntaxKind.WithStatement; + readonly expression: Expression; + readonly statement: Statement; } export interface SwitchStatement extends Statement { - kind: SyntaxKind.SwitchStatement; - expression: Expression; - caseBlock: CaseBlock; + readonly kind: SyntaxKind.SwitchStatement; + readonly expression: Expression; + readonly caseBlock: CaseBlock; possiblyExhaustive?: boolean; } export interface CaseBlock extends Node { - kind: SyntaxKind.CaseBlock; - parent: SwitchStatement; - clauses: NodeArray; + readonly kind: SyntaxKind.CaseBlock; + readonly parent: SwitchStatement; + readonly clauses: NodeArray; } export interface CaseClause extends Node { - kind: SyntaxKind.CaseClause; - parent: CaseBlock; - expression: Expression; - statements: NodeArray; + readonly kind: SyntaxKind.CaseClause; + readonly parent: CaseBlock; + readonly expression: Expression; + readonly statements: NodeArray; } export interface DefaultClause extends Node { - kind: SyntaxKind.DefaultClause; - parent: CaseBlock; - statements: NodeArray; + readonly kind: SyntaxKind.DefaultClause; + readonly parent: CaseBlock; + readonly statements: NodeArray; } export type CaseOrDefaultClause = CaseClause | DefaultClause; export interface LabeledStatement extends Statement, JSDocContainer { - kind: SyntaxKind.LabeledStatement; - label: Identifier; - statement: Statement; + readonly kind: SyntaxKind.LabeledStatement; + readonly label: Identifier; + readonly statement: Statement; } export interface ThrowStatement extends Statement { - kind: SyntaxKind.ThrowStatement; - expression?: Expression; + readonly kind: SyntaxKind.ThrowStatement; + readonly expression?: Expression; } export interface TryStatement extends Statement { - kind: SyntaxKind.TryStatement; - tryBlock: Block; - catchClause?: CatchClause; - finallyBlock?: Block; + readonly kind: SyntaxKind.TryStatement; + readonly tryBlock: Block; + readonly catchClause?: CatchClause; + readonly finallyBlock?: Block; } export interface CatchClause extends Node { - kind: SyntaxKind.CatchClause; - parent: TryStatement; - variableDeclaration?: VariableDeclaration; - block: Block; + readonly kind: SyntaxKind.CatchClause; + readonly parent: TryStatement; + readonly variableDeclaration?: VariableDeclaration; + readonly block: Block; } export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode; export type DeclarationWithTypeParameters = DeclarationWithTypeParameterChildren | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; export type DeclarationWithTypeParameterChildren = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; - name?: Identifier; - typeParameters?: NodeArray; - heritageClauses?: NodeArray; - members: NodeArray; + readonly kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; + readonly name?: Identifier; + readonly typeParameters?: NodeArray; + readonly heritageClauses?: NodeArray; + readonly members: NodeArray; } export interface ClassDeclaration extends ClassLikeDeclarationBase, DeclarationStatement { - kind: SyntaxKind.ClassDeclaration; + readonly kind: SyntaxKind.ClassDeclaration; /** May be undefined in `export default class { ... }`. */ - name?: Identifier; + readonly name?: Identifier; } export interface ClassExpression extends ClassLikeDeclarationBase, PrimaryExpression { - kind: SyntaxKind.ClassExpression; + readonly kind: SyntaxKind.ClassExpression; } export type ClassLikeDeclaration = ClassDeclaration | ClassExpression; export interface ClassElement extends NamedDeclaration { _classElementBrand: any; - name?: PropertyName; + readonly name?: PropertyName; } export interface TypeElement extends NamedDeclaration { _typeElementBrand: any; - name?: PropertyName; - questionToken?: QuestionToken; + readonly name?: PropertyName; + readonly questionToken?: QuestionToken; } export interface InterfaceDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.InterfaceDeclaration; - name: Identifier; - typeParameters?: NodeArray; - heritageClauses?: NodeArray; - members: NodeArray; + readonly kind: SyntaxKind.InterfaceDeclaration; + readonly name: Identifier; + readonly typeParameters?: NodeArray; + readonly heritageClauses?: NodeArray; + readonly members: NodeArray; } export interface HeritageClause extends Node { - kind: SyntaxKind.HeritageClause; - parent: InterfaceDeclaration | ClassLikeDeclaration; - token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword; - types: NodeArray; + readonly kind: SyntaxKind.HeritageClause; + readonly parent: InterfaceDeclaration | ClassLikeDeclaration; + readonly token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword; + readonly types: NodeArray; } export interface TypeAliasDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.TypeAliasDeclaration; - name: Identifier; - typeParameters?: NodeArray; - type: TypeNode; + readonly kind: SyntaxKind.TypeAliasDeclaration; + readonly name: Identifier; + readonly typeParameters?: NodeArray; + readonly type: TypeNode; } export interface EnumMember extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.EnumMember; - parent: EnumDeclaration; - name: PropertyName; - initializer?: Expression; + readonly kind: SyntaxKind.EnumMember; + readonly parent: EnumDeclaration; + readonly name: PropertyName; + readonly initializer?: Expression; } export interface EnumDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.EnumDeclaration; - name: Identifier; - members: NodeArray; + readonly kind: SyntaxKind.EnumDeclaration; + readonly name: Identifier; + readonly members: NodeArray; } export type ModuleName = Identifier | StringLiteral; export type ModuleBody = NamespaceBody | JSDocNamespaceBody; export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ModuleDeclaration; - parent: ModuleBody | SourceFile; - name: ModuleName; - body?: ModuleBody | JSDocNamespaceDeclaration; + readonly kind: SyntaxKind.ModuleDeclaration; + readonly parent: ModuleBody | SourceFile; + readonly name: ModuleName; + readonly body?: ModuleBody | JSDocNamespaceDeclaration; } export type NamespaceBody = ModuleBlock | NamespaceDeclaration; export interface NamespaceDeclaration extends ModuleDeclaration { - name: Identifier; - body: NamespaceBody; + readonly name: Identifier; + readonly body: NamespaceBody; } export type JSDocNamespaceBody = Identifier | JSDocNamespaceDeclaration; export interface JSDocNamespaceDeclaration extends ModuleDeclaration { - name: Identifier; - body?: JSDocNamespaceBody; + readonly name: Identifier; + readonly body?: JSDocNamespaceBody; } export interface ModuleBlock extends Node, Statement { - kind: SyntaxKind.ModuleBlock; - parent: ModuleDeclaration; - statements: NodeArray; + readonly kind: SyntaxKind.ModuleBlock; + readonly parent: ModuleDeclaration; + readonly statements: NodeArray; } export type ModuleReference = EntityName | ExternalModuleReference; /** @@ -1492,77 +1547,77 @@ declare namespace ts { * - import x = M.x; */ export interface ImportEqualsDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ImportEqualsDeclaration; - parent: SourceFile | ModuleBlock; - name: Identifier; - moduleReference: ModuleReference; + readonly kind: SyntaxKind.ImportEqualsDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly name: Identifier; + readonly moduleReference: ModuleReference; } export interface ExternalModuleReference extends Node { - kind: SyntaxKind.ExternalModuleReference; - parent: ImportEqualsDeclaration; - expression: Expression; - } - export interface ImportDeclaration extends Statement { - kind: SyntaxKind.ImportDeclaration; - parent: SourceFile | ModuleBlock; - importClause?: ImportClause; + readonly kind: SyntaxKind.ExternalModuleReference; + readonly parent: ImportEqualsDeclaration; + readonly expression: Expression; + } + export interface ImportDeclaration extends Statement, JSDocContainer { + readonly kind: SyntaxKind.ImportDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly importClause?: ImportClause; /** If this is not a StringLiteral it will be a grammar error. */ - moduleSpecifier: Expression; + readonly moduleSpecifier: Expression; } export type NamedImportBindings = NamespaceImport | NamedImports; export type NamedExportBindings = NamespaceExport | NamedExports; export interface ImportClause extends NamedDeclaration { - kind: SyntaxKind.ImportClause; - parent: ImportDeclaration; - isTypeOnly: boolean; - name?: Identifier; - namedBindings?: NamedImportBindings; + readonly kind: SyntaxKind.ImportClause; + readonly parent: ImportDeclaration; + readonly isTypeOnly: boolean; + readonly name?: Identifier; + readonly namedBindings?: NamedImportBindings; } export interface NamespaceImport extends NamedDeclaration { - kind: SyntaxKind.NamespaceImport; - parent: ImportClause; - name: Identifier; + readonly kind: SyntaxKind.NamespaceImport; + readonly parent: ImportClause; + readonly name: Identifier; } export interface NamespaceExport extends NamedDeclaration { - kind: SyntaxKind.NamespaceExport; - parent: ExportDeclaration; - name: Identifier; + readonly kind: SyntaxKind.NamespaceExport; + readonly parent: ExportDeclaration; + readonly name: Identifier; } - export interface NamespaceExportDeclaration extends DeclarationStatement { - kind: SyntaxKind.NamespaceExportDeclaration; - name: Identifier; + export interface NamespaceExportDeclaration extends DeclarationStatement, JSDocContainer { + readonly kind: SyntaxKind.NamespaceExportDeclaration; + readonly name: Identifier; } export interface ExportDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ExportDeclaration; - parent: SourceFile | ModuleBlock; - isTypeOnly: boolean; + readonly kind: SyntaxKind.ExportDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly isTypeOnly: boolean; /** Will not be assigned in the case of `export * from "foo";` */ - exportClause?: NamedExportBindings; + readonly exportClause?: NamedExportBindings; /** If this is not a StringLiteral it will be a grammar error. */ - moduleSpecifier?: Expression; + readonly moduleSpecifier?: Expression; } export interface NamedImports extends Node { - kind: SyntaxKind.NamedImports; - parent: ImportClause; - elements: NodeArray; + readonly kind: SyntaxKind.NamedImports; + readonly parent: ImportClause; + readonly elements: NodeArray; } export interface NamedExports extends Node { - kind: SyntaxKind.NamedExports; - parent: ExportDeclaration; - elements: NodeArray; + readonly kind: SyntaxKind.NamedExports; + readonly parent: ExportDeclaration; + readonly elements: NodeArray; } export type NamedImportsOrExports = NamedImports | NamedExports; export interface ImportSpecifier extends NamedDeclaration { - kind: SyntaxKind.ImportSpecifier; - parent: NamedImports; - propertyName?: Identifier; - name: Identifier; + readonly kind: SyntaxKind.ImportSpecifier; + readonly parent: NamedImports; + readonly propertyName?: Identifier; + readonly name: Identifier; } export interface ExportSpecifier extends NamedDeclaration { - kind: SyntaxKind.ExportSpecifier; - parent: NamedExports; - propertyName?: Identifier; - name: Identifier; + readonly kind: SyntaxKind.ExportSpecifier; + readonly parent: NamedExports; + readonly propertyName?: Identifier; + readonly name: Identifier; } export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier; export type TypeOnlyCompatibleAliasDeclaration = ImportClause | NamespaceImport | ImportOrExportSpecifier; @@ -1570,11 +1625,11 @@ declare namespace ts { * This is either an `export =` or an `export default` declaration. * Unless `isExportEquals` is set, this node was parsed as an `export default`. */ - export interface ExportAssignment extends DeclarationStatement { - kind: SyntaxKind.ExportAssignment; - parent: SourceFile; - isExportEquals?: boolean; - expression: Expression; + export interface ExportAssignment extends DeclarationStatement, JSDocContainer { + readonly kind: SyntaxKind.ExportAssignment; + readonly parent: SourceFile; + readonly isExportEquals?: boolean; + readonly expression: Expression; } export interface FileReference extends TextRange { fileName: string; @@ -1594,151 +1649,151 @@ declare namespace ts { hasLeadingNewline?: boolean; } export interface JSDocTypeExpression extends TypeNode { - kind: SyntaxKind.JSDocTypeExpression; - type: TypeNode; + readonly kind: SyntaxKind.JSDocTypeExpression; + readonly type: TypeNode; } export interface JSDocType extends TypeNode { _jsDocTypeBrand: any; } export interface JSDocAllType extends JSDocType { - kind: SyntaxKind.JSDocAllType; + readonly kind: SyntaxKind.JSDocAllType; } export interface JSDocUnknownType extends JSDocType { - kind: SyntaxKind.JSDocUnknownType; + readonly kind: SyntaxKind.JSDocUnknownType; } export interface JSDocNonNullableType extends JSDocType { - kind: SyntaxKind.JSDocNonNullableType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNonNullableType; + readonly type: TypeNode; } export interface JSDocNullableType extends JSDocType { - kind: SyntaxKind.JSDocNullableType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNullableType; + readonly type: TypeNode; } export interface JSDocOptionalType extends JSDocType { - kind: SyntaxKind.JSDocOptionalType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocOptionalType; + readonly type: TypeNode; } export interface JSDocFunctionType extends JSDocType, SignatureDeclarationBase { - kind: SyntaxKind.JSDocFunctionType; + readonly kind: SyntaxKind.JSDocFunctionType; } export interface JSDocVariadicType extends JSDocType { - kind: SyntaxKind.JSDocVariadicType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocVariadicType; + readonly type: TypeNode; } export interface JSDocNamepathType extends JSDocType { - kind: SyntaxKind.JSDocNamepathType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNamepathType; + readonly type: TypeNode; } export type JSDocTypeReferencingNode = JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType; export interface JSDoc extends Node { - kind: SyntaxKind.JSDocComment; - parent: HasJSDoc; - tags?: NodeArray; - comment?: string; + readonly kind: SyntaxKind.JSDocComment; + readonly parent: HasJSDoc; + readonly tags?: NodeArray; + readonly comment?: string; } export interface JSDocTag extends Node { - parent: JSDoc | JSDocTypeLiteral; - tagName: Identifier; - comment?: string; + readonly parent: JSDoc | JSDocTypeLiteral; + readonly tagName: Identifier; + readonly comment?: string; } export interface JSDocUnknownTag extends JSDocTag { - kind: SyntaxKind.JSDocTag; + readonly kind: SyntaxKind.JSDocTag; } /** * Note that `@extends` is a synonym of `@augments`. * Both tags are represented by this interface. */ export interface JSDocAugmentsTag extends JSDocTag { - kind: SyntaxKind.JSDocAugmentsTag; - class: ExpressionWithTypeArguments & { - expression: Identifier | PropertyAccessEntityNameExpression; + readonly kind: SyntaxKind.JSDocAugmentsTag; + readonly class: ExpressionWithTypeArguments & { + readonly expression: Identifier | PropertyAccessEntityNameExpression; }; } export interface JSDocImplementsTag extends JSDocTag { - kind: SyntaxKind.JSDocImplementsTag; - class: ExpressionWithTypeArguments & { - expression: Identifier | PropertyAccessEntityNameExpression; + readonly kind: SyntaxKind.JSDocImplementsTag; + readonly class: ExpressionWithTypeArguments & { + readonly expression: Identifier | PropertyAccessEntityNameExpression; }; } export interface JSDocAuthorTag extends JSDocTag { - kind: SyntaxKind.JSDocAuthorTag; + readonly kind: SyntaxKind.JSDocAuthorTag; } export interface JSDocClassTag extends JSDocTag { - kind: SyntaxKind.JSDocClassTag; + readonly kind: SyntaxKind.JSDocClassTag; } export interface JSDocPublicTag extends JSDocTag { - kind: SyntaxKind.JSDocPublicTag; + readonly kind: SyntaxKind.JSDocPublicTag; } export interface JSDocPrivateTag extends JSDocTag { - kind: SyntaxKind.JSDocPrivateTag; + readonly kind: SyntaxKind.JSDocPrivateTag; } export interface JSDocProtectedTag extends JSDocTag { - kind: SyntaxKind.JSDocProtectedTag; + readonly kind: SyntaxKind.JSDocProtectedTag; } export interface JSDocReadonlyTag extends JSDocTag { - kind: SyntaxKind.JSDocReadonlyTag; + readonly kind: SyntaxKind.JSDocReadonlyTag; } export interface JSDocEnumTag extends JSDocTag, Declaration { - parent: JSDoc; - kind: SyntaxKind.JSDocEnumTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocEnumTag; + readonly parent: JSDoc; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocThisTag extends JSDocTag { - kind: SyntaxKind.JSDocThisTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocThisTag; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocTemplateTag extends JSDocTag { - kind: SyntaxKind.JSDocTemplateTag; - constraint: JSDocTypeExpression | undefined; - typeParameters: NodeArray; + readonly kind: SyntaxKind.JSDocTemplateTag; + readonly constraint: JSDocTypeExpression | undefined; + readonly typeParameters: NodeArray; } export interface JSDocReturnTag extends JSDocTag { - kind: SyntaxKind.JSDocReturnTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocReturnTag; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocTypeTag extends JSDocTag { - kind: SyntaxKind.JSDocTypeTag; - typeExpression: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocTypeTag; + readonly typeExpression: JSDocTypeExpression; } export interface JSDocTypedefTag extends JSDocTag, NamedDeclaration { - parent: JSDoc; - kind: SyntaxKind.JSDocTypedefTag; - fullName?: JSDocNamespaceDeclaration | Identifier; - name?: Identifier; - typeExpression?: JSDocTypeExpression | JSDocTypeLiteral; + readonly kind: SyntaxKind.JSDocTypedefTag; + readonly parent: JSDoc; + readonly fullName?: JSDocNamespaceDeclaration | Identifier; + readonly name?: Identifier; + readonly typeExpression?: JSDocTypeExpression | JSDocTypeLiteral; } export interface JSDocCallbackTag extends JSDocTag, NamedDeclaration { - parent: JSDoc; - kind: SyntaxKind.JSDocCallbackTag; - fullName?: JSDocNamespaceDeclaration | Identifier; - name?: Identifier; - typeExpression: JSDocSignature; + readonly kind: SyntaxKind.JSDocCallbackTag; + readonly parent: JSDoc; + readonly fullName?: JSDocNamespaceDeclaration | Identifier; + readonly name?: Identifier; + readonly typeExpression: JSDocSignature; } export interface JSDocSignature extends JSDocType, Declaration { - kind: SyntaxKind.JSDocSignature; - typeParameters?: readonly JSDocTemplateTag[]; - parameters: readonly JSDocParameterTag[]; - type: JSDocReturnTag | undefined; + readonly kind: SyntaxKind.JSDocSignature; + readonly typeParameters?: readonly JSDocTemplateTag[]; + readonly parameters: readonly JSDocParameterTag[]; + readonly type: JSDocReturnTag | undefined; } export interface JSDocPropertyLikeTag extends JSDocTag, Declaration { - parent: JSDoc; - name: EntityName; - typeExpression?: JSDocTypeExpression; + readonly parent: JSDoc; + readonly name: EntityName; + readonly typeExpression?: JSDocTypeExpression; /** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */ - isNameFirst: boolean; - isBracketed: boolean; + readonly isNameFirst: boolean; + readonly isBracketed: boolean; } export interface JSDocPropertyTag extends JSDocPropertyLikeTag { - kind: SyntaxKind.JSDocPropertyTag; + readonly kind: SyntaxKind.JSDocPropertyTag; } export interface JSDocParameterTag extends JSDocPropertyLikeTag { - kind: SyntaxKind.JSDocParameterTag; + readonly kind: SyntaxKind.JSDocParameterTag; } export interface JSDocTypeLiteral extends JSDocType { - kind: SyntaxKind.JSDocTypeLiteral; - jsDocPropertyTags?: readonly JSDocPropertyLikeTag[]; + readonly kind: SyntaxKind.JSDocTypeLiteral; + readonly jsDocPropertyTags?: readonly JSDocPropertyLikeTag[]; /** If true, then this type literal represents an *array* of its type. */ - isArrayType?: boolean; + readonly isArrayType: boolean; } export enum FlowFlags { Unreachable = 1, @@ -1805,9 +1860,9 @@ declare namespace ts { name?: string; } export interface SourceFile extends Declaration { - kind: SyntaxKind.SourceFile; - statements: NodeArray; - endOfFileToken: Token; + readonly kind: SyntaxKind.SourceFile; + readonly statements: NodeArray; + readonly endOfFileToken: Token; fileName: string; text: string; amdDependencies: readonly AmdDependency[]; @@ -1829,12 +1884,12 @@ declare namespace ts { languageVersion: ScriptTarget; } export interface Bundle extends Node { - kind: SyntaxKind.Bundle; - prepends: readonly (InputFiles | UnparsedSource)[]; - sourceFiles: readonly SourceFile[]; + readonly kind: SyntaxKind.Bundle; + readonly prepends: readonly (InputFiles | UnparsedSource)[]; + readonly sourceFiles: readonly SourceFile[]; } export interface InputFiles extends Node { - kind: SyntaxKind.InputFiles; + readonly kind: SyntaxKind.InputFiles; javascriptPath?: string; javascriptText: string; javascriptMapPath?: string; @@ -1845,10 +1900,10 @@ declare namespace ts { declarationMapText?: string; } export interface UnparsedSource extends Node { - kind: SyntaxKind.UnparsedSource; + readonly kind: SyntaxKind.UnparsedSource; fileName: string; text: string; - prologues: readonly UnparsedPrologue[]; + readonly prologues: readonly UnparsedPrologue[]; helpers: readonly UnscopedEmitHelper[] | undefined; referencedFiles: readonly FileReference[]; typeReferenceDirectives: readonly string[] | undefined; @@ -1856,48 +1911,49 @@ declare namespace ts { hasNoDefaultLib?: boolean; sourceMapPath?: string; sourceMapText?: string; - syntheticReferences?: readonly UnparsedSyntheticReference[]; - texts: readonly UnparsedSourceText[]; + readonly syntheticReferences?: readonly UnparsedSyntheticReference[]; + readonly texts: readonly UnparsedSourceText[]; } export type UnparsedSourceText = UnparsedPrepend | UnparsedTextLike; export type UnparsedNode = UnparsedPrologue | UnparsedSourceText | UnparsedSyntheticReference; export interface UnparsedSection extends Node { - kind: SyntaxKind; - data?: string; - parent: UnparsedSource; + readonly kind: SyntaxKind; + readonly parent: UnparsedSource; + readonly data?: string; } export interface UnparsedPrologue extends UnparsedSection { - kind: SyntaxKind.UnparsedPrologue; - data: string; - parent: UnparsedSource; + readonly kind: SyntaxKind.UnparsedPrologue; + readonly parent: UnparsedSource; + readonly data: string; } export interface UnparsedPrepend extends UnparsedSection { - kind: SyntaxKind.UnparsedPrepend; - data: string; - parent: UnparsedSource; - texts: readonly UnparsedTextLike[]; + readonly kind: SyntaxKind.UnparsedPrepend; + readonly parent: UnparsedSource; + readonly data: string; + readonly texts: readonly UnparsedTextLike[]; } export interface UnparsedTextLike extends UnparsedSection { - kind: SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText; - parent: UnparsedSource; + readonly kind: SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText; + readonly parent: UnparsedSource; } export interface UnparsedSyntheticReference extends UnparsedSection { - kind: SyntaxKind.UnparsedSyntheticReference; - parent: UnparsedSource; + readonly kind: SyntaxKind.UnparsedSyntheticReference; + readonly parent: UnparsedSource; } export interface JsonSourceFile extends SourceFile { - statements: NodeArray; + readonly statements: NodeArray; } export interface TsConfigSourceFile extends JsonSourceFile { extendedSourceFiles?: string[]; } export interface JsonMinusNumericLiteral extends PrefixUnaryExpression { - kind: SyntaxKind.PrefixUnaryExpression; - operator: SyntaxKind.MinusToken; - operand: NumericLiteral; + readonly kind: SyntaxKind.PrefixUnaryExpression; + readonly operator: SyntaxKind.MinusToken; + readonly operand: NumericLiteral; } + export type JsonObjectExpression = ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | BooleanLiteral | NullLiteral; export interface JsonObjectExpressionStatement extends ExpressionStatement { - expression: ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | BooleanLiteral | NullLiteral; + readonly expression: JsonObjectExpression; } export interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; @@ -3011,7 +3067,435 @@ declare namespace ts { EmbeddedStatement = 5, JsxAttributeValue = 6 } - export interface TransformationContext { + export enum OuterExpressionKinds { + Parentheses = 1, + TypeAssertions = 2, + NonNullAssertions = 4, + PartiallyEmittedExpressions = 8, + Assertions = 6, + All = 15 + } + export type TypeOfTag = "undefined" | "number" | "bigint" | "boolean" | "string" | "symbol" | "object" | "function"; + export interface NodeFactory { + createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray; + createNumericLiteral(value: string | number, numericLiteralFlags?: TokenFlags): NumericLiteral; + createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral; + createStringLiteral(text: string, isSingleQuote?: boolean): StringLiteral; + createStringLiteralFromNode(sourceNode: PropertyNameLiteral, isSingleQuote?: boolean): StringLiteral; + createRegularExpressionLiteral(text: string): RegularExpressionLiteral; + createIdentifier(text: string): Identifier; + /** Create a unique temporary variable. */ + createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; + /** Create a unique temporary variable for use in a loop. */ + createLoopVariable(): Identifier; + /** Create a unique name based on the supplied text. */ + createUniqueName(text: string, flags?: GeneratedIdentifierFlags): Identifier; + /** Create a unique name generated for a node. */ + getGeneratedNameForNode(node: Node | undefined): Identifier; + createPrivateIdentifier(text: string): PrivateIdentifier; + createToken(token: SyntaxKind.SuperKeyword): SuperExpression; + createToken(token: SyntaxKind.ThisKeyword): ThisExpression; + createToken(token: SyntaxKind.NullKeyword): NullLiteral; + createToken(token: SyntaxKind.TrueKeyword): TrueLiteral; + createToken(token: SyntaxKind.FalseKeyword): FalseLiteral; + createToken(token: TKind): PunctuationToken; + createToken(token: TKind): KeywordTypeNode; + createToken(token: TKind): ModifierToken; + createToken(token: TKind): KeywordToken; + createToken(token: TKind): Token; + createSuper(): SuperExpression; + createThis(): ThisExpression; + createNull(): NullLiteral; + createTrue(): TrueLiteral; + createFalse(): FalseLiteral; + createModifier(kind: T): ModifierToken; + createModifiersFromModifierFlags(flags: ModifierFlags): Modifier[]; + createQualifiedName(left: EntityName, right: string | Identifier): QualifiedName; + updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName; + createComputedPropertyName(expression: Expression): ComputedPropertyName; + updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName; + createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; + updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined): TypeParameterDeclaration; + createParameterDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): ParameterDeclaration; + updateParameterDeclaration(node: ParameterDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): ParameterDeclaration; + createDecorator(expression: Expression): Decorator; + updateDecorator(node: Decorator, expression: Expression): Decorator; + createPropertySignature(modifiers: readonly Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined): PropertySignature; + updatePropertySignature(node: PropertySignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined): PropertySignature; + createPropertyDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + updatePropertyDeclaration(node: PropertyDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + createMethodSignature(modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): MethodSignature; + updateMethodSignature(node: MethodSignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): MethodSignature; + createMethodDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; + updateMethodDeclaration(node: MethodDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; + createConstructorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; + updateConstructorDeclaration(node: ConstructorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; + createGetAccessorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; + updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; + createSetAccessorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; + updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; + createCallSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration; + updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration; + createConstructSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration; + updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration; + createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; + updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; + createKeywordTypeNode(kind: TKind): KeywordTypeNode; + createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; + createTypeReferenceNode(typeName: string | EntityName, typeArguments?: readonly TypeNode[]): TypeReferenceNode; + updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; + createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; + updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; + createTypeQueryNode(exprName: EntityName): TypeQueryNode; + updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; + createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; + updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode; + createArrayTypeNode(elementType: TypeNode): ArrayTypeNode; + updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode; + createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; + updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; + createNamedTupleMember(dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode): NamedTupleMember; + updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode): NamedTupleMember; + createOptionalTypeNode(type: TypeNode): OptionalTypeNode; + updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode; + createRestTypeNode(type: TypeNode): RestTypeNode; + updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode; + createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode; + updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode; + createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode; + updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode; + createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; + updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; + createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; + updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; + createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; + updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean): ImportTypeNode; + createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; + updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; + createThisTypeNode(): ThisTypeNode; + createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; + updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; + createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; + updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; + createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; + updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; + createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern; + updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]): ObjectBindingPattern; + createArrayBindingPattern(elements: readonly ArrayBindingElement[]): ArrayBindingPattern; + updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]): ArrayBindingPattern; + createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression): BindingElement; + updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined): BindingElement; + createArrayLiteralExpression(elements?: readonly Expression[], multiLine?: boolean): ArrayLiteralExpression; + updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; + createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; + updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; + createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression; + updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression; + createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier): PropertyAccessChain; + updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier): PropertyAccessChain; + createElementAccessExpression(expression: Expression, index: number | Expression): ElementAccessExpression; + updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression; + createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain; + updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression): ElementAccessChain; + createCallExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallExpression; + updateCallExpression(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallExpression; + createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallChain; + updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallChain; + createNewExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; + updateNewExpression(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; + createTaggedTemplateExpression(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; + updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; + createParenthesizedExpression(expression: Expression): ParenthesizedExpression; + updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression; + createFunctionExpression(modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[] | undefined, type: TypeNode | undefined, body: Block): FunctionExpression; + updateFunctionExpression(node: FunctionExpression, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block): FunctionExpression; + createArrowFunction(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; + updateArrowFunction(node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody): ArrowFunction; + createDeleteExpression(expression: Expression): DeleteExpression; + updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression; + createTypeOfExpression(expression: Expression): TypeOfExpression; + updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression; + createVoidExpression(expression: Expression): VoidExpression; + updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression; + createAwaitExpression(expression: Expression): AwaitExpression; + updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression; + createPrefixUnaryExpression(operator: PrefixUnaryOperator, operand: Expression): PrefixUnaryExpression; + updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression; + createPostfixUnaryExpression(operand: Expression, operator: PostfixUnaryOperator): PostfixUnaryExpression; + updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression; + createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; + updateBinaryExpression(node: BinaryExpression, left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; + createConditionalExpression(condition: Expression, questionToken: QuestionToken | undefined, whenTrue: Expression, colonToken: ColonToken | undefined, whenFalse: Expression): ConditionalExpression; + updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; + createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; + updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; + createTemplateHead(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateHead; + createTemplateHead(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateHead; + createTemplateMiddle(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateMiddle; + createTemplateMiddle(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateMiddle; + createTemplateTail(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateTail; + createTemplateTail(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateTail; + createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; + createNoSubstitutionTemplateLiteral(text: string | undefined, rawText: string): NoSubstitutionTemplateLiteral; + createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression; + createYieldExpression(asteriskToken: undefined, expression: Expression | undefined): YieldExpression; + updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression | undefined): YieldExpression; + createSpreadElement(expression: Expression): SpreadElement; + updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement; + createClassExpression(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; + updateClassExpression(node: ClassExpression, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; + createOmittedExpression(): OmittedExpression; + createExpressionWithTypeArguments(expression: Expression, typeArguments: readonly TypeNode[] | undefined): ExpressionWithTypeArguments; + updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: readonly TypeNode[] | undefined): ExpressionWithTypeArguments; + createAsExpression(expression: Expression, type: TypeNode): AsExpression; + updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression; + createNonNullExpression(expression: Expression): NonNullExpression; + updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression; + createNonNullChain(expression: Expression): NonNullChain; + updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain; + createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier): MetaProperty; + updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty; + createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; + updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; + createSemicolonClassElement(): SemicolonClassElement; + createBlock(statements: readonly Statement[], multiLine?: boolean): Block; + updateBlock(node: Block, statements: readonly Statement[]): Block; + createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]): VariableStatement; + updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList): VariableStatement; + createEmptyStatement(): EmptyStatement; + createExpressionStatement(expression: Expression): ExpressionStatement; + updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement; + createIfStatement(expression: Expression, thenStatement: Statement, elseStatement?: Statement): IfStatement; + updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined): IfStatement; + createDoStatement(statement: Statement, expression: Expression): DoStatement; + updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement; + createWhileStatement(expression: Expression, statement: Statement): WhileStatement; + updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement; + createForStatement(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; + updateForStatement(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; + createForInStatement(initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; + updateForInStatement(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; + createForOfStatement(awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; + updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; + createContinueStatement(label?: string | Identifier): ContinueStatement; + updateContinueStatement(node: ContinueStatement, label: Identifier | undefined): ContinueStatement; + createBreakStatement(label?: string | Identifier): BreakStatement; + updateBreakStatement(node: BreakStatement, label: Identifier | undefined): BreakStatement; + createReturnStatement(expression?: Expression): ReturnStatement; + updateReturnStatement(node: ReturnStatement, expression: Expression | undefined): ReturnStatement; + createWithStatement(expression: Expression, statement: Statement): WithStatement; + updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement; + createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement; + updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement; + createLabeledStatement(label: string | Identifier, statement: Statement): LabeledStatement; + updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement; + createThrowStatement(expression: Expression): ThrowStatement; + updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement; + createTryStatement(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; + updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; + createDebuggerStatement(): DebuggerStatement; + createVariableDeclaration(name: string | BindingName, exclamationToken?: ExclamationToken, type?: TypeNode, initializer?: Expression): VariableDeclaration; + updateVariableDeclaration(node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList; + updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]): VariableDeclarationList; + createFunctionDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; + updateFunctionDeclaration(node: FunctionDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; + createClassDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; + updateClassDeclaration(node: ClassDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; + createInterfaceDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; + updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; + createTypeAliasDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; + updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; + createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]): EnumDeclaration; + updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]): EnumDeclaration; + createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags): ModuleDeclaration; + updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined): ModuleDeclaration; + createModuleBlock(statements: readonly Statement[]): ModuleBlock; + updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]): ModuleBlock; + createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock; + updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]): CaseBlock; + createNamespaceExportDeclaration(name: string | Identifier): NamespaceExportDeclaration; + updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration; + createImportEqualsDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; + updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; + createImportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; + updateImportDeclaration(node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; + createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createNamespaceImport(name: Identifier): NamespaceImport; + updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport; + createNamespaceExport(name: Identifier): NamespaceExport; + updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport; + createNamedImports(elements: readonly ImportSpecifier[]): NamedImports; + updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]): NamedImports; + createImportSpecifier(propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; + updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; + createExportAssignment(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression): ExportAssignment; + updateExportAssignment(node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression): ExportAssignment; + createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression): ExportDeclaration; + updateExportDeclaration(node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined): ExportDeclaration; + createNamedExports(elements: readonly ExportSpecifier[]): NamedExports; + updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]): NamedExports; + createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier): ExportSpecifier; + updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; + createExternalModuleReference(expression: Expression): ExternalModuleReference; + updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; + createJSDocAllType(): JSDocAllType; + createJSDocUnknownType(): JSDocUnknownType; + createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType; + updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType; + createJSDocNullableType(type: TypeNode): JSDocNullableType; + updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType; + createJSDocOptionalType(type: TypeNode): JSDocOptionalType; + updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType; + createJSDocFunctionType(parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType; + updateJSDocFunctionType(node: JSDocFunctionType, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType; + createJSDocVariadicType(type: TypeNode): JSDocVariadicType; + updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType; + createJSDocNamepathType(type: TypeNode): JSDocNamepathType; + updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType; + createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression; + updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression; + createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral; + updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: readonly JSDocPropertyLikeTag[] | undefined, isArrayType: boolean | undefined): JSDocTypeLiteral; + createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature; + updateJSDocSignature(node: JSDocSignature, typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type: JSDocReturnTag | undefined): JSDocSignature; + createJSDocTemplateTag(tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string): JSDocTemplateTag; + updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | undefined): JSDocTemplateTag; + createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocTypedefTag; + updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocTypedefTag; + createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; + updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; + createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; + updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; + createJSDocTypeTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; + updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocTypeTag; + createJSDocReturnTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag; + updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment: string | undefined): JSDocReturnTag; + createJSDocThisTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocThisTag; + updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment: string | undefined): JSDocThisTag; + createJSDocEnumTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocEnumTag; + updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocEnumTag; + createJSDocCallbackTag(tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocCallbackTag; + updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocCallbackTag; + createJSDocAugmentsTag(tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment?: string): JSDocAugmentsTag; + updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment: string | undefined): JSDocAugmentsTag; + createJSDocImplementsTag(tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag; + updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment: string | undefined): JSDocImplementsTag; + createJSDocAuthorTag(tagName: Identifier | undefined, comment?: string): JSDocAuthorTag; + updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier | undefined, comment: string | undefined): JSDocAuthorTag; + createJSDocClassTag(tagName: Identifier | undefined, comment?: string): JSDocClassTag; + updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier | undefined, comment: string | undefined): JSDocClassTag; + createJSDocPublicTag(tagName: Identifier | undefined, comment?: string): JSDocPublicTag; + updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier | undefined, comment: string | undefined): JSDocPublicTag; + createJSDocPrivateTag(tagName: Identifier | undefined, comment?: string): JSDocPrivateTag; + updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier | undefined, comment: string | undefined): JSDocPrivateTag; + createJSDocProtectedTag(tagName: Identifier | undefined, comment?: string): JSDocProtectedTag; + updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier | undefined, comment: string | undefined): JSDocProtectedTag; + createJSDocReadonlyTag(tagName: Identifier | undefined, comment?: string): JSDocReadonlyTag; + updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | undefined): JSDocReadonlyTag; + createJSDocUnknownTag(tagName: Identifier, comment?: string): JSDocUnknownTag; + updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | undefined): JSDocUnknownTag; + createJSDocComment(comment?: string | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc; + updateJSDocComment(node: JSDoc, comment: string | undefined, tags: readonly JSDocTag[] | undefined): JSDoc; + createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; + updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; + createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; + updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; + createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement; + updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement; + createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; + createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; + updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; + createJsxOpeningFragment(): JsxOpeningFragment; + createJsxJsxClosingFragment(): JsxClosingFragment; + updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; + createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression | undefined): JsxAttribute; + updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression | undefined): JsxAttribute; + createJsxAttributes(properties: readonly JsxAttributeLike[]): JsxAttributes; + updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]): JsxAttributes; + createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute; + updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute; + createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined): JsxExpression; + updateJsxExpression(node: JsxExpression, expression: Expression | undefined): JsxExpression; + createCaseClause(expression: Expression, statements: readonly Statement[]): CaseClause; + updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]): CaseClause; + createDefaultClause(statements: readonly Statement[]): DefaultClause; + updateDefaultClause(node: DefaultClause, statements: readonly Statement[]): DefaultClause; + createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]): HeritageClause; + updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]): HeritageClause; + createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause; + updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause; + createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment; + updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment; + createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment; + updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined): ShorthandPropertyAssignment; + createSpreadAssignment(expression: Expression): SpreadAssignment; + updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; + createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; + updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; + createSourceFile(statements: readonly Statement[], endOfFileToken: EndOfFileToken, flags: NodeFlags): SourceFile; + updateSourceFile(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: readonly FileReference[], typeReferences?: readonly FileReference[], hasNoDefaultLib?: boolean, libReferences?: readonly FileReference[]): SourceFile; + createNotEmittedStatement(original: Node): NotEmittedStatement; + createPartiallyEmittedExpression(expression: Expression, original?: Node): PartiallyEmittedExpression; + updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression; + createCommaListExpression(elements: readonly Expression[]): CommaListExpression; + updateCommaListExpression(node: CommaListExpression, elements: readonly Expression[]): CommaListExpression; + createBundle(sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; + updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; + createComma(left: Expression, right: Expression): BinaryExpression; + createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; + createAssignment(left: Expression, right: Expression): AssignmentExpression; + createLogicalOr(left: Expression, right: Expression): BinaryExpression; + createLogicalAnd(left: Expression, right: Expression): BinaryExpression; + createBitwiseOr(left: Expression, right: Expression): BinaryExpression; + createBitwiseXor(left: Expression, right: Expression): BinaryExpression; + createBitwiseAnd(left: Expression, right: Expression): BinaryExpression; + createStrictEquality(left: Expression, right: Expression): BinaryExpression; + createStrictInequality(left: Expression, right: Expression): BinaryExpression; + createEquality(left: Expression, right: Expression): BinaryExpression; + createInequality(left: Expression, right: Expression): BinaryExpression; + createLessThan(left: Expression, right: Expression): BinaryExpression; + createLessThanEquals(left: Expression, right: Expression): BinaryExpression; + createGreaterThan(left: Expression, right: Expression): BinaryExpression; + createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression; + createLeftShift(left: Expression, right: Expression): BinaryExpression; + createRightShift(left: Expression, right: Expression): BinaryExpression; + createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression; + createAdd(left: Expression, right: Expression): BinaryExpression; + createSubtract(left: Expression, right: Expression): BinaryExpression; + createMultiply(left: Expression, right: Expression): BinaryExpression; + createDivide(left: Expression, right: Expression): BinaryExpression; + createModulo(left: Expression, right: Expression): BinaryExpression; + createExponent(left: Expression, right: Expression): BinaryExpression; + createPrefixPlus(operand: Expression): PrefixUnaryExpression; + createPrefixMinus(operand: Expression): PrefixUnaryExpression; + createPrefixIncrement(operand: Expression): PrefixUnaryExpression; + createPrefixDecrement(operand: Expression): PrefixUnaryExpression; + createBitwiseNot(operand: Expression): PrefixUnaryExpression; + createLogicalNot(operand: Expression): PrefixUnaryExpression; + createPostfixIncrement(operand: Expression): PostfixUnaryExpression; + createPostfixDecrement(operand: Expression): PostfixUnaryExpression; + createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; + createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; + createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + createVoidZero(): VoidExpression; + createExportDefault(expression: Expression): ExportAssignment; + createExternalModuleExport(exportName: Identifier): ExportDeclaration; + restoreOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds?: OuterExpressionKinds): Expression; + } + export interface CoreTransformationContext { + readonly factory: NodeFactory; /** Gets the compiler options supplied to the transformer. */ getCompilerOptions(): CompilerOptions; /** Starts a new lexical environment. */ @@ -3026,6 +3510,8 @@ declare namespace ts { hoistFunctionDeclaration(node: FunctionDeclaration): void; /** Hoists a variable declaration to the containing scope. */ hoistVariableDeclaration(node: Identifier): void; + } + export interface TransformationContext extends CoreTransformationContext { /** Records a request for a non-scoped emit helper in the current context. */ requestEmitHelper(helper: EmitHelper): void; /** Gets and resets the requested non-scoped emit helpers. */ @@ -3105,6 +3591,14 @@ declare namespace ts { * A function that accepts and possibly transforms a node. */ export type Visitor = (node: Node) => VisitResult; + export interface NodeVisitor { + (nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; + (nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T | undefined; + } + export interface NodesVisitor { + (nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; + (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + } export type VisitResult = T | T[] | undefined; export interface Printer { /** @@ -3201,6 +3695,7 @@ declare namespace ts { newLength: number; } export interface SyntaxList extends Node { + kind: SyntaxKind.SyntaxList; _children: Node[]; } export enum ListFormat { @@ -3476,7 +3971,7 @@ declare namespace ts { * @param node The original node. * @returns The original parse tree node if found; otherwise, undefined. */ - function getParseTreeNode(node: Node): Node; + function getParseTreeNode(node: Node | undefined): Node | undefined; /** * Gets the original parse tree node for a node. * @@ -3484,7 +3979,7 @@ declare namespace ts { * @param nodeTest A callback used to ensure the correct type of parse tree node is returned. * @returns The original parse tree node if found; otherwise, undefined. */ - function getParseTreeNode(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined; + function getParseTreeNode(node: T | undefined, nodeTest?: (node: Node) => node is T): T | undefined; /** Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' */ function escapeLeadingUnderscores(identifier: string): __String; /** @@ -3584,6 +4079,154 @@ declare namespace ts { */ function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): readonly TypeParameterDeclaration[]; function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined; + function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier; + function isPropertyAccessChain(node: Node): node is PropertyAccessChain; + function isElementAccessChain(node: Node): node is ElementAccessChain; + function isCallChain(node: Node): node is CallChain; + function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain | NonNullChain; + function isNullishCoalesce(node: Node): boolean; + function isConstTypeReference(node: Node): boolean; + function skipPartiallyEmittedExpressions(node: Expression): Expression; + function skipPartiallyEmittedExpressions(node: Node): Node; + function isNonNullChain(node: Node): node is NonNullChain; + function isBreakOrContinueStatement(node: Node): node is BreakOrContinueStatement; + function isNamedExportBindings(node: Node): node is NamedExportBindings; + function isUnparsedTextLike(node: Node): node is UnparsedTextLike; + function isUnparsedNode(node: Node): node is UnparsedNode; + function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag; + /** + * True if node is of some token syntax kind. + * For example, this is true for an IfKeyword but not for an IfStatement. + * Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail. + */ + function isToken(n: Node): boolean; + function isLiteralExpression(node: Node): node is LiteralExpression; + function isTemplateLiteralToken(node: Node): node is TemplateLiteralToken; + function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail; + function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | ExportSpecifier; + function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyCompatibleAliasDeclaration; + function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken; + function isModifier(node: Node): node is Modifier; + function isEntityName(node: Node): node is EntityName; + function isPropertyName(node: Node): node is PropertyName; + function isBindingName(node: Node): node is BindingName; + function isFunctionLike(node: Node): node is SignatureDeclaration; + function isClassElement(node: Node): node is ClassElement; + function isClassLike(node: Node): node is ClassLikeDeclaration; + function isAccessor(node: Node): node is AccessorDeclaration; + function isTypeElement(node: Node): node is TypeElement; + function isClassOrTypeElement(node: Node): node is ClassElement | TypeElement; + function isObjectLiteralElementLike(node: Node): node is ObjectLiteralElementLike; + /** + * Node test that determines whether a node is a valid type node. + * This differs from the `isPartOfTypeNode` function which determines whether a node is *part* + * of a TypeNode. + */ + function isTypeNode(node: Node): node is TypeNode; + function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; + function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; + function isCallLikeExpression(node: Node): node is CallLikeExpression; + function isCallOrNewExpression(node: Node): node is CallExpression | NewExpression; + function isTemplateLiteral(node: Node): node is TemplateLiteral; + function isAssertionExpression(node: Node): node is AssertionExpression; + function isIterationStatement(node: Node, lookInLabeledStatements: false): node is IterationStatement; + function isIterationStatement(node: Node, lookInLabeledStatements: boolean): node is IterationStatement | LabeledStatement; + function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement; + function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause; + /** True if node is of a kind that may contain comment text. */ + function isJSDocCommentContainingNode(node: Node): boolean; + function isSetAccessor(node: Node): node is SetAccessorDeclaration; + function isGetAccessor(node: Node): node is GetAccessorDeclaration; + /** True if has initializer node attached to it. */ + function hasOnlyExpressionInitializer(node: Node): node is HasExpressionInitializer; + function isObjectLiteralElement(node: Node): node is ObjectLiteralElement; + function isStringLiteralLike(node: Node): node is StringLiteralLike; +} +declare namespace ts { + const factory: NodeFactory; + function createUnparsedSourceFile(text: string): UnparsedSource; + function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; + function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; + function createInputFiles(javascriptText: string, declarationText: string): InputFiles; + function createInputFiles(readFileText: (path: string) => string | undefined, javascriptPath: string, javascriptMapPath: string | undefined, declarationPath: string, declarationMapPath: string | undefined, buildInfoPath: string | undefined): InputFiles; + function createInputFiles(javascriptText: string, declarationText: string, javascriptMapPath: string | undefined, javascriptMapText: string | undefined, declarationMapPath: string | undefined, declarationMapText: string | undefined): InputFiles; + /** + * Create an external source map source file reference + */ + function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource; + function setOriginalNode(node: T, original: Node | undefined): T; +} +declare namespace ts { + /** + * Clears any `EmitNode` entries from parse-tree nodes. + * @param sourceFile A source file. + */ + function disposeEmitNodes(sourceFile: SourceFile | undefined): void; + /** + * Sets flags that control emit behavior of a node. + */ + function setEmitFlags(node: T, emitFlags: EmitFlags): T; + /** + * Gets a custom text range to use when emitting source maps. + */ + function getSourceMapRange(node: Node): SourceMapRange; + /** + * Sets a custom text range to use when emitting source maps. + */ + function setSourceMapRange(node: T, range: SourceMapRange | undefined): T; + /** + * Gets the TextRange to use for source maps for a token of a node. + */ + function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined; + /** + * Sets the TextRange to use for source maps for a token of a node. + */ + function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined): T; + /** + * Gets a custom text range to use when emitting comments. + */ + function getCommentRange(node: Node): TextRange; + /** + * Sets a custom text range to use when emitting comments. + */ + function setCommentRange(node: T, range: TextRange): T; + function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined; + function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined): T; + function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T; + function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined; + function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined): T; + function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T; + function moveSyntheticComments(node: T, original: Node): T; + /** + * Gets the constant value to emit for an expression representing an enum. + */ + function getConstantValue(node: AccessExpression): string | number | undefined; + /** + * Sets the constant value to emit for an expression. + */ + function setConstantValue(node: AccessExpression, value: string | number): AccessExpression; + /** + * Adds an EmitHelper to a node. + */ + function addEmitHelper(node: T, helper: EmitHelper): T; + /** + * Add EmitHelpers to a node. + */ + function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T; + /** + * Removes an EmitHelper from a node. + */ + function removeEmitHelper(node: Node, helper: EmitHelper): boolean; + /** + * Gets the EmitHelpers of a node. + */ + function getEmitHelpers(node: Node): EmitHelper[] | undefined; + /** + * Moves matching emit helpers from a source node to a target node. + */ + function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean): void; +} +declare namespace ts { function isNumericLiteral(node: Node): node is NumericLiteral; function isBigIntLiteral(node: Node): node is BigIntLiteral; function isStringLiteral(node: Node): node is StringLiteral; @@ -3597,7 +4240,6 @@ declare namespace ts { function isQualifiedName(node: Node): node is QualifiedName; function isComputedPropertyName(node: Node): node is ComputedPropertyName; function isPrivateIdentifier(node: Node): node is PrivateIdentifier; - function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier; function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration; function isParameter(node: Node): node is ParameterDeclaration; function isDecorator(node: Node): node is Decorator; @@ -3619,6 +4261,8 @@ declare namespace ts { function isTypeLiteralNode(node: Node): node is TypeLiteralNode; function isArrayTypeNode(node: Node): node is ArrayTypeNode; function isTupleTypeNode(node: Node): node is TupleTypeNode; + function isOptionalTypeNode(node: Node): node is OptionalTypeNode; + function isRestTypeNode(node: Node): node is RestTypeNode; function isUnionTypeNode(node: Node): node is UnionTypeNode; function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode; function isConditionalTypeNode(node: Node): node is ConditionalTypeNode; @@ -3636,20 +4280,12 @@ declare namespace ts { function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression; function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression; function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression; - function isPropertyAccessChain(node: Node): node is PropertyAccessChain; function isElementAccessExpression(node: Node): node is ElementAccessExpression; - function isElementAccessChain(node: Node): node is ElementAccessChain; function isCallExpression(node: Node): node is CallExpression; - function isCallChain(node: Node): node is CallChain; - function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain | NonNullChain; - function isNullishCoalesce(node: Node): boolean; function isNewExpression(node: Node): node is NewExpression; function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression; - function isTypeAssertion(node: Node): node is TypeAssertion; - function isConstTypeReference(node: Node): boolean; + function isTypeAssertionExpression(node: Node): node is TypeAssertion; function isParenthesizedExpression(node: Node): node is ParenthesizedExpression; - function skipPartiallyEmittedExpressions(node: Expression): Expression; - function skipPartiallyEmittedExpressions(node: Node): Node; function isFunctionExpression(node: Node): node is FunctionExpression; function isArrowFunction(node: Node): node is ArrowFunction; function isDeleteExpression(node: Node): node is DeleteExpression; @@ -3668,8 +4304,10 @@ declare namespace ts { function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments; function isAsExpression(node: Node): node is AsExpression; function isNonNullExpression(node: Node): node is NonNullExpression; - function isNonNullChain(node: Node): node is NonNullChain; function isMetaProperty(node: Node): node is MetaProperty; + function isSyntheticExpression(node: Node): node is SyntheticExpression; + function isPartiallyEmittedExpression(node: Node): node is PartiallyEmittedExpression; + function isCommaListExpression(node: Node): node is CommaListExpression; function isTemplateSpan(node: Node): node is TemplateSpan; function isSemicolonClassElement(node: Node): node is SemicolonClassElement; function isBlock(node: Node): node is Block; @@ -3684,7 +4322,6 @@ declare namespace ts { function isForOfStatement(node: Node): node is ForOfStatement; function isContinueStatement(node: Node): node is ContinueStatement; function isBreakStatement(node: Node): node is BreakStatement; - function isBreakOrContinueStatement(node: Node): node is BreakOrContinueStatement; function isReturnStatement(node: Node): node is ReturnStatement; function isWithStatement(node: Node): node is WithStatement; function isSwitchStatement(node: Node): node is SwitchStatement; @@ -3708,7 +4345,6 @@ declare namespace ts { function isImportClause(node: Node): node is ImportClause; function isNamespaceImport(node: Node): node is NamespaceImport; function isNamespaceExport(node: Node): node is NamespaceExport; - function isNamedExportBindings(node: Node): node is NamedExportBindings; function isNamedImports(node: Node): node is NamedImports; function isImportSpecifier(node: Node): node is ImportSpecifier; function isExportAssignment(node: Node): node is ExportAssignment; @@ -3716,6 +4352,7 @@ declare namespace ts { function isNamedExports(node: Node): node is NamedExports; function isExportSpecifier(node: Node): node is ExportSpecifier; function isMissingDeclaration(node: Node): node is MissingDeclaration; + function isNotEmittedStatement(node: Node): node is NotEmittedStatement; function isExternalModuleReference(node: Node): node is ExternalModuleReference; function isJsxElement(node: Node): node is JsxElement; function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement; @@ -3736,12 +4373,10 @@ declare namespace ts { function isShorthandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment; function isSpreadAssignment(node: Node): node is SpreadAssignment; function isEnumMember(node: Node): node is EnumMember; + function isUnparsedPrepend(node: Node): node is UnparsedPrepend; function isSourceFile(node: Node): node is SourceFile; function isBundle(node: Node): node is Bundle; function isUnparsedSource(node: Node): node is UnparsedSource; - function isUnparsedPrepend(node: Node): node is UnparsedPrepend; - function isUnparsedTextLike(node: Node): node is UnparsedTextLike; - function isUnparsedNode(node: Node): node is UnparsedNode; function isJSDocTypeExpression(node: Node): node is JSDocTypeExpression; function isJSDocAllType(node: Node): node is JSDocAllType; function isJSDocUnknownType(node: Node): node is JSDocUnknownType; @@ -3750,78 +4385,33 @@ declare namespace ts { function isJSDocOptionalType(node: Node): node is JSDocOptionalType; function isJSDocFunctionType(node: Node): node is JSDocFunctionType; function isJSDocVariadicType(node: Node): node is JSDocVariadicType; + function isJSDocNamepathType(node: Node): node is JSDocNamepathType; function isJSDoc(node: Node): node is JSDoc; - function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag; + function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral; + function isJSDocSignature(node: Node): node is JSDocSignature; function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag; - function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag; + function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag; function isJSDocClassTag(node: Node): node is JSDocClassTag; + function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag; function isJSDocPublicTag(node: Node): node is JSDocPublicTag; function isJSDocPrivateTag(node: Node): node is JSDocPrivateTag; function isJSDocProtectedTag(node: Node): node is JSDocProtectedTag; function isJSDocReadonlyTag(node: Node): node is JSDocReadonlyTag; function isJSDocEnumTag(node: Node): node is JSDocEnumTag; - function isJSDocThisTag(node: Node): node is JSDocThisTag; function isJSDocParameterTag(node: Node): node is JSDocParameterTag; function isJSDocReturnTag(node: Node): node is JSDocReturnTag; + function isJSDocThisTag(node: Node): node is JSDocThisTag; function isJSDocTypeTag(node: Node): node is JSDocTypeTag; function isJSDocTemplateTag(node: Node): node is JSDocTemplateTag; function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag; + function isJSDocUnknownTag(node: Node): node is JSDocUnknownTag; function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag; - function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag; - function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral; - function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag; - function isJSDocSignature(node: Node): node is JSDocSignature; - /** - * True if node is of some token syntax kind. - * For example, this is true for an IfKeyword but not for an IfStatement. - * Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail. - */ - function isToken(n: Node): boolean; - function isLiteralExpression(node: Node): node is LiteralExpression; - type TemplateLiteralToken = NoSubstitutionTemplateLiteral | TemplateHead | TemplateMiddle | TemplateTail; - function isTemplateLiteralToken(node: Node): node is TemplateLiteralToken; - function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail; - function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | ExportSpecifier; - function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyCompatibleAliasDeclaration; - function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken; - function isModifier(node: Node): node is Modifier; - function isEntityName(node: Node): node is EntityName; - function isPropertyName(node: Node): node is PropertyName; - function isBindingName(node: Node): node is BindingName; - function isFunctionLike(node: Node): node is SignatureDeclaration; - function isClassElement(node: Node): node is ClassElement; - function isClassLike(node: Node): node is ClassLikeDeclaration; - function isAccessor(node: Node): node is AccessorDeclaration; - function isTypeElement(node: Node): node is TypeElement; - function isClassOrTypeElement(node: Node): node is ClassElement | TypeElement; - function isObjectLiteralElementLike(node: Node): node is ObjectLiteralElementLike; - /** - * Node test that determines whether a node is a valid type node. - * This differs from the `isPartOfTypeNode` function which determines whether a node is *part* - * of a TypeNode. - */ - function isTypeNode(node: Node): node is TypeNode; - function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; - function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; - function isCallLikeExpression(node: Node): node is CallLikeExpression; - function isCallOrNewExpression(node: Node): node is CallExpression | NewExpression; - function isTemplateLiteral(node: Node): node is TemplateLiteral; - function isAssertionExpression(node: Node): node is AssertionExpression; - function isIterationStatement(node: Node, lookInLabeledStatements: false): node is IterationStatement; - function isIterationStatement(node: Node, lookInLabeledStatements: boolean): node is IterationStatement | LabeledStatement; - function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement; - function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause; - /** True if node is of a kind that may contain comment text. */ - function isJSDocCommentContainingNode(node: Node): boolean; - function isSetAccessor(node: Node): node is SetAccessorDeclaration; - function isGetAccessor(node: Node): node is GetAccessorDeclaration; - /** True if has initializer node attached to it. */ - function hasOnlyExpressionInitializer(node: Node): node is HasExpressionInitializer; - function isObjectLiteralElement(node: Node): node is ObjectLiteralElement; - function isStringLiteralLike(node: Node): node is StringLiteralLike; + function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag; +} +declare namespace ts { + function setTextRange(range: T, location: TextRange | undefined): T; } declare namespace ts { - export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node; /** * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, @@ -3977,476 +4567,6 @@ declare namespace ts { function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; } -declare namespace ts { - function createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray; - /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; - function createLiteral(value: number | PseudoBigInt): NumericLiteral; - function createLiteral(value: boolean): BooleanLiteral; - function createLiteral(value: string | number | PseudoBigInt | boolean): PrimaryExpression; - function createNumericLiteral(value: string, numericLiteralFlags?: TokenFlags): NumericLiteral; - function createBigIntLiteral(value: string): BigIntLiteral; - function createStringLiteral(text: string): StringLiteral; - function createRegularExpressionLiteral(text: string): RegularExpressionLiteral; - function createIdentifier(text: string): Identifier; - function updateIdentifier(node: Identifier): Identifier; - /** Create a unique temporary variable. */ - function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; - /** Create a unique temporary variable for use in a loop. */ - function createLoopVariable(): Identifier; - /** Create a unique name based on the supplied text. */ - function createUniqueName(text: string): Identifier; - /** Create a unique name based on the supplied text. */ - function createOptimisticUniqueName(text: string): Identifier; - /** Create a unique name based on the supplied text. This does not consider names injected by the transformer. */ - function createFileLevelUniqueName(text: string): Identifier; - /** Create a unique name generated for a node. */ - function getGeneratedNameForNode(node: Node | undefined): Identifier; - function createPrivateIdentifier(text: string): PrivateIdentifier; - function createToken(token: TKind): Token; - function createSuper(): SuperExpression; - function createThis(): ThisExpression & Token; - function createNull(): NullLiteral & Token; - function createTrue(): BooleanLiteral & Token; - function createFalse(): BooleanLiteral & Token; - function createModifier(kind: T): Token; - function createModifiersFromModifierFlags(flags: ModifierFlags): Modifier[]; - function createQualifiedName(left: EntityName, right: string | Identifier): QualifiedName; - function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName; - function createComputedPropertyName(expression: Expression): ComputedPropertyName; - function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName; - function createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; - function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined): TypeParameterDeclaration; - function createParameter(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): ParameterDeclaration; - function updateParameter(node: ParameterDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): ParameterDeclaration; - function createDecorator(expression: Expression): Decorator; - function updateDecorator(node: Decorator, expression: Expression): Decorator; - function createPropertySignature(modifiers: readonly Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature; - function updatePropertySignature(node: PropertySignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature; - function createProperty(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; - function updateProperty(node: PropertyDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; - function createMethodSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): MethodSignature; - function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined): MethodSignature; - function createMethod(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; - function updateMethod(node: MethodDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; - function createConstructor(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; - function updateConstructor(node: ConstructorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; - function createGetAccessor(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; - function updateGetAccessor(node: GetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; - function createSetAccessor(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; - function updateSetAccessor(node: SetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; - function createCallSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration; - function updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration; - function createConstructSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration; - function updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration; - function createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; - function updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; - function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode; - function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode; - function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; - function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode; - function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; - function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined): TypeReferenceNode; - function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; - function createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode; - function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode; - function createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode; - function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructorTypeNode; - function createTypeQueryNode(exprName: EntityName): TypeQueryNode; - function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; - function createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; - function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode; - function createArrayTypeNode(elementType: TypeNode): ArrayTypeNode; - function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode; - function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; - function updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; - function createOptionalTypeNode(type: TypeNode): OptionalTypeNode; - function updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode; - function createRestTypeNode(type: TypeNode): RestTypeNode; - function updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode; - function createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode; - function updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode; - function createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode; - function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode; - function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: readonly TypeNode[]): UnionOrIntersectionTypeNode; - function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; - function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; - function createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; - function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; - function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; - function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; - function createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; - function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; - function createNamedTupleMember(dotDotDotToken: Token | undefined, name: Identifier, questionToken: Token | undefined, type: TypeNode): NamedTupleMember; - function updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: Token | undefined, name: Identifier, questionToken: Token | undefined, type: TypeNode): NamedTupleMember; - function createThisTypeNode(): ThisTypeNode; - function createTypeOperatorNode(type: TypeNode): TypeOperatorNode; - function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; - function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; - function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - function createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; - function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; - function createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; - function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; - function createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern; - function updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]): ObjectBindingPattern; - function createArrayBindingPattern(elements: readonly ArrayBindingElement[]): ArrayBindingPattern; - function updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]): ArrayBindingPattern; - function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression): BindingElement; - function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined): BindingElement; - function createArrayLiteral(elements?: readonly Expression[], multiLine?: boolean): ArrayLiteralExpression; - function updateArrayLiteral(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; - function createObjectLiteral(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; - function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; - function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression; - function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression; - function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier): PropertyAccessChain; - function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier): PropertyAccessChain; - function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression; - function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression; - function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain; - function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression): ElementAccessChain; - function createCall(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallExpression; - function updateCall(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallExpression; - function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallChain; - function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallChain; - function createNew(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; - function updateNew(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; - /** @deprecated */ function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function createTaggedTemplate(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; - /** @deprecated */ function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; - function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; - function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; - function createParen(expression: Expression): ParenthesizedExpression; - function updateParen(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression; - function createFunctionExpression(modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[] | undefined, type: TypeNode | undefined, body: Block): FunctionExpression; - function updateFunctionExpression(node: FunctionExpression, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block): FunctionExpression; - function createArrowFunction(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; - function updateArrowFunction(node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: Token, body: ConciseBody): ArrowFunction; - function createDelete(expression: Expression): DeleteExpression; - function updateDelete(node: DeleteExpression, expression: Expression): DeleteExpression; - function createTypeOf(expression: Expression): TypeOfExpression; - function updateTypeOf(node: TypeOfExpression, expression: Expression): TypeOfExpression; - function createVoid(expression: Expression): VoidExpression; - function updateVoid(node: VoidExpression, expression: Expression): VoidExpression; - function createAwait(expression: Expression): AwaitExpression; - function updateAwait(node: AwaitExpression, expression: Expression): AwaitExpression; - function createPrefix(operator: PrefixUnaryOperator, operand: Expression): PrefixUnaryExpression; - function updatePrefix(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression; - function createPostfix(operand: Expression, operator: PostfixUnaryOperator): PostfixUnaryExpression; - function updatePostfix(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression; - function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; - function updateBinary(node: BinaryExpression, left: Expression, right: Expression, operator?: BinaryOperator | BinaryOperatorToken): BinaryExpression; - /** @deprecated */ function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; - function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; - function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; - function createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; - function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; - function createTemplateHead(text: string, rawText?: string): TemplateHead; - function createTemplateMiddle(text: string, rawText?: string): TemplateMiddle; - function createTemplateTail(text: string, rawText?: string): TemplateTail; - function createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; - function createYield(expression?: Expression): YieldExpression; - function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; - function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; - function createSpread(expression: Expression): SpreadElement; - function updateSpread(node: SpreadElement, expression: Expression): SpreadElement; - function createClassExpression(modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; - function updateClassExpression(node: ClassExpression, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; - function createOmittedExpression(): OmittedExpression; - function createExpressionWithTypeArguments(typeArguments: readonly TypeNode[] | undefined, expression: Expression): ExpressionWithTypeArguments; - function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: readonly TypeNode[] | undefined, expression: Expression): ExpressionWithTypeArguments; - function createAsExpression(expression: Expression, type: TypeNode): AsExpression; - function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression; - function createNonNullExpression(expression: Expression): NonNullExpression; - function updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression; - function createNonNullChain(expression: Expression): NonNullChain; - function updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain; - function createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier): MetaProperty; - function updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty; - function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; - function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; - function createSemicolonClassElement(): SemicolonClassElement; - function createBlock(statements: readonly Statement[], multiLine?: boolean): Block; - function updateBlock(node: Block, statements: readonly Statement[]): Block; - function createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]): VariableStatement; - function updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList): VariableStatement; - function createEmptyStatement(): EmptyStatement; - function createExpressionStatement(expression: Expression): ExpressionStatement; - function updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement; - /** @deprecated Use `createExpressionStatement` instead. */ - const createStatement: typeof createExpressionStatement; - /** @deprecated Use `updateExpressionStatement` instead. */ - const updateStatement: typeof updateExpressionStatement; - function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement): IfStatement; - function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined): IfStatement; - function createDo(statement: Statement, expression: Expression): DoStatement; - function updateDo(node: DoStatement, statement: Statement, expression: Expression): DoStatement; - function createWhile(expression: Expression, statement: Statement): WhileStatement; - function updateWhile(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement; - function createFor(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; - function updateFor(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; - function createForIn(initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; - function updateForIn(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; - function createForOf(awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; - function updateForOf(node: ForOfStatement, awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; - function createContinue(label?: string | Identifier): ContinueStatement; - function updateContinue(node: ContinueStatement, label: Identifier | undefined): ContinueStatement; - function createBreak(label?: string | Identifier): BreakStatement; - function updateBreak(node: BreakStatement, label: Identifier | undefined): BreakStatement; - function createReturn(expression?: Expression): ReturnStatement; - function updateReturn(node: ReturnStatement, expression: Expression | undefined): ReturnStatement; - function createWith(expression: Expression, statement: Statement): WithStatement; - function updateWith(node: WithStatement, expression: Expression, statement: Statement): WithStatement; - function createSwitch(expression: Expression, caseBlock: CaseBlock): SwitchStatement; - function updateSwitch(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement; - function createLabel(label: string | Identifier, statement: Statement): LabeledStatement; - function updateLabel(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement; - function createThrow(expression: Expression): ThrowStatement; - function updateThrow(node: ThrowStatement, expression: Expression): ThrowStatement; - function createTry(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; - function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; - function createDebuggerStatement(): DebuggerStatement; - function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression): VariableDeclaration; - function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; - function createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList; - function updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]): VariableDeclarationList; - function createFunctionDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; - function updateFunctionDeclaration(node: FunctionDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; - function createClassDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; - function updateClassDeclaration(node: ClassDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; - function createInterfaceDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; - function updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; - function createTypeAliasDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; - function updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; - function createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]): EnumDeclaration; - function updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]): EnumDeclaration; - function createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags): ModuleDeclaration; - function updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined): ModuleDeclaration; - function createModuleBlock(statements: readonly Statement[]): ModuleBlock; - function updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]): ModuleBlock; - function createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock; - function updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]): CaseBlock; - function createNamespaceExportDeclaration(name: string | Identifier): NamespaceExportDeclaration; - function updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration; - function createImportEqualsDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; - function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; - function createImportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; - function updateImportDeclaration(node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; - function createImportClause(name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly?: boolean): ImportClause; - function updateImportClause(node: ImportClause, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly: boolean): ImportClause; - function createNamespaceImport(name: Identifier): NamespaceImport; - function createNamespaceExport(name: Identifier): NamespaceExport; - function updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport; - function updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport; - function createNamedImports(elements: readonly ImportSpecifier[]): NamedImports; - function updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]): NamedImports; - function createImportSpecifier(propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; - function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; - function createExportAssignment(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression): ExportAssignment; - function updateExportAssignment(node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression): ExportAssignment; - function createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression, isTypeOnly?: boolean): ExportDeclaration; - function updateExportDeclaration(node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined, isTypeOnly: boolean): ExportDeclaration; - function createNamedExports(elements: readonly ExportSpecifier[]): NamedExports; - function updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]): NamedExports; - function createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier): ExportSpecifier; - function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; - function createExternalModuleReference(expression: Expression): ExternalModuleReference; - function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; - function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression; - function createJSDocTypeTag(typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; - function createJSDocReturnTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag; - function createJSDocThisTag(typeExpression?: JSDocTypeExpression): JSDocThisTag; - /** - * @deprecated Use `createJSDocParameterTag` to create jsDoc param tag. - */ - function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag; - function createJSDocClassTag(comment?: string): JSDocClassTag; - function createJSDocComment(comment?: string | undefined, tags?: NodeArray | undefined): JSDoc; - function createJSDocTag(kind: T["kind"], tagName: string, comment?: string): T; - function createJSDocAugmentsTag(classExpression: JSDocAugmentsTag["class"], comment?: string): JSDocAugmentsTag; - function createJSDocEnumTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocEnumTag; - function createJSDocTemplateTag(constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string): JSDocTemplateTag; - function createJSDocTypedefTag(fullName?: JSDocNamespaceDeclaration | Identifier, name?: Identifier, comment?: string, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral): JSDocTypedefTag; - function createJSDocCallbackTag(fullName: JSDocNamespaceDeclaration | Identifier | undefined, name: Identifier | undefined, comment: string | undefined, typeExpression: JSDocSignature): JSDocCallbackTag; - function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature; - function createJSDocPropertyTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string): JSDocPropertyTag; - function createJSDocParameterTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string): JSDocParameterTag; - function createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral; - function createJSDocImplementsTag(classExpression: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag; - function createJSDocAuthorTag(comment?: string): JSDocAuthorTag; - function createJSDocPublicTag(): JSDocPublicTag; - function createJSDocPrivateTag(): JSDocPrivateTag; - function createJSDocProtectedTag(): JSDocProtectedTag; - function createJSDocReadonlyTag(): JSDocReadonlyTag; - function appendJSDocToContainer(node: JSDocContainer, jsdoc: JSDoc): JSDocContainer; - function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; - function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; - function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; - function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; - function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; - function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; - function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement; - function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement; - function createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; - function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; - function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; - function createJsxOpeningFragment(): JsxOpeningFragment; - function createJsxJsxClosingFragment(): JsxClosingFragment; - function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; - function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute; - function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute; - function createJsxAttributes(properties: readonly JsxAttributeLike[]): JsxAttributes; - function updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]): JsxAttributes; - function createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute; - function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute; - function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined): JsxExpression; - function updateJsxExpression(node: JsxExpression, expression: Expression | undefined): JsxExpression; - function createCaseClause(expression: Expression, statements: readonly Statement[]): CaseClause; - function updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]): CaseClause; - function createDefaultClause(statements: readonly Statement[]): DefaultClause; - function updateDefaultClause(node: DefaultClause, statements: readonly Statement[]): DefaultClause; - function createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]): HeritageClause; - function updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]): HeritageClause; - function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause; - function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause; - function createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment; - function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment; - function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment; - function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined): ShorthandPropertyAssignment; - function createSpreadAssignment(expression: Expression): SpreadAssignment; - function updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; - function createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; - function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; - function updateSourceFileNode(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean, libReferences?: SourceFile["libReferenceDirectives"]): SourceFile; - /** - * Creates a shallow, memberwise clone of a node for mutation. - */ - function getMutableClone(node: T): T; - /** - * Creates a synthetic statement to act as a placeholder for a not-emitted statement in - * order to preserve comments. - * - * @param original The original statement. - */ - function createNotEmittedStatement(original: Node): NotEmittedStatement; - /** - * Creates a synthetic expression to act as a placeholder for a not-emitted expression in - * order to preserve comments or sourcemap positions. - * - * @param expression The inner expression to emit. - * @param original The original outer expression. - * @param location The location for the expression. Defaults to the positions from "original" if provided. - */ - function createPartiallyEmittedExpression(expression: Expression, original?: Node): PartiallyEmittedExpression; - function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression; - function createCommaList(elements: readonly Expression[]): CommaListExpression; - function updateCommaList(node: CommaListExpression, elements: readonly Expression[]): CommaListExpression; - function createBundle(sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; - function createUnparsedSourceFile(text: string): UnparsedSource; - function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; - function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; - function createInputFiles(javascriptText: string, declarationText: string): InputFiles; - function createInputFiles(readFileText: (path: string) => string | undefined, javascriptPath: string, javascriptMapPath: string | undefined, declarationPath: string, declarationMapPath: string | undefined, buildInfoPath: string | undefined): InputFiles; - function createInputFiles(javascriptText: string, declarationText: string, javascriptMapPath: string | undefined, javascriptMapText: string | undefined, declarationMapPath: string | undefined, declarationMapText: string | undefined): InputFiles; - function updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; - function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; - function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; - function createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; - function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; - function createComma(left: Expression, right: Expression): Expression; - function createLessThan(left: Expression, right: Expression): Expression; - function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; - function createAssignment(left: Expression, right: Expression): BinaryExpression; - function createStrictEquality(left: Expression, right: Expression): BinaryExpression; - function createStrictInequality(left: Expression, right: Expression): BinaryExpression; - function createAdd(left: Expression, right: Expression): BinaryExpression; - function createSubtract(left: Expression, right: Expression): BinaryExpression; - function createPostfixIncrement(operand: Expression): PostfixUnaryExpression; - function createLogicalAnd(left: Expression, right: Expression): BinaryExpression; - function createLogicalOr(left: Expression, right: Expression): BinaryExpression; - function createNullishCoalesce(left: Expression, right: Expression): BinaryExpression; - function createLogicalNot(operand: Expression): PrefixUnaryExpression; - function createVoidZero(): VoidExpression; - function createExportDefault(expression: Expression): ExportAssignment; - function createExternalModuleExport(exportName: Identifier): ExportDeclaration; - /** - * Clears any EmitNode entries from parse-tree nodes. - * @param sourceFile A source file. - */ - function disposeEmitNodes(sourceFile: SourceFile): void; - function setTextRange(range: T, location: TextRange | undefined): T; - /** - * Sets flags that control emit behavior of a node. - */ - function setEmitFlags(node: T, emitFlags: EmitFlags): T; - /** - * Gets a custom text range to use when emitting source maps. - */ - function getSourceMapRange(node: Node): SourceMapRange; - /** - * Sets a custom text range to use when emitting source maps. - */ - function setSourceMapRange(node: T, range: SourceMapRange | undefined): T; - /** - * Create an external source map source file reference - */ - function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource; - /** - * Gets the TextRange to use for source maps for a token of a node. - */ - function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined; - /** - * Sets the TextRange to use for source maps for a token of a node. - */ - function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined): T; - /** - * Gets a custom text range to use when emitting comments. - */ - function getCommentRange(node: Node): TextRange; - /** - * Sets a custom text range to use when emitting comments. - */ - function setCommentRange(node: T, range: TextRange): T; - function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined; - function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined): T; - function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T; - function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined; - function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined): T; - function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T; - function moveSyntheticComments(node: T, original: Node): T; - /** - * Gets the constant value to emit for an expression. - */ - function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression): string | number | undefined; - /** - * Sets the constant value to emit for an expression. - */ - function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: string | number): PropertyAccessExpression | ElementAccessExpression; - /** - * Adds an EmitHelper to a node. - */ - function addEmitHelper(node: T, helper: EmitHelper): T; - /** - * Add EmitHelpers to a node. - */ - function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T; - /** - * Removes an EmitHelper from a node. - */ - function removeEmitHelper(node: Node, helper: EmitHelper): boolean; - /** - * Gets the EmitHelpers of a node. - */ - function getEmitHelpers(node: Node): EmitHelper[] | undefined; - /** - * Moves matching emit helpers from a source node to a target node. - */ - function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean): void; - function setOriginalNode(node: T, original: Node | undefined): T; -} declare namespace ts { /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. @@ -4456,7 +4576,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; + function visitNode(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -4475,7 +4595,7 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes(nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; + function visitNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -4485,18 +4605,18 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes(nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean): NodeArray; + function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray): NodeArray; - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray | undefined): NodeArray | undefined; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. @@ -9714,6 +9834,762 @@ declare namespace ts.server { responseRequired?: boolean; } } +declare namespace ts { + /** @deprecated Use `factory.createNodeArray` or the factory supplied by your transformation context instead. */ + const createNodeArray: (elements?: readonly T[] | undefined, hasTrailingComma?: boolean | undefined) => NodeArray; + /** @deprecated Use `factory.createNumericLiteral` or the factory supplied by your transformation context instead. */ + const createNumericLiteral: (value: string | number, numericLiteralFlags?: TokenFlags | undefined) => NumericLiteral; + /** @deprecated Use `factory.createBigIntLiteral` or the factory supplied by your transformation context instead. */ + const createBigIntLiteral: (value: string | PseudoBigInt) => BigIntLiteral; + /** @deprecated Use `factory.createStringLiteral` or the factory supplied by your transformation context instead. */ + const createStringLiteral: { + (text: string, isSingleQuote?: boolean | undefined): StringLiteral; + (text: string, isSingleQuote?: boolean | undefined, hasExtendedUnicodeEscape?: boolean | undefined): StringLiteral; + }; + /** @deprecated Use `factory.createStringLiteralFromNode` or the factory supplied by your transformation context instead. */ + const createStringLiteralFromNode: (sourceNode: Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral, isSingleQuote?: boolean | undefined) => StringLiteral; + /** @deprecated Use `factory.createRegularExpressionLiteral` or the factory supplied by your transformation context instead. */ + const createRegularExpressionLiteral: (text: string) => RegularExpressionLiteral; + /** @deprecated Use `factory.createLoopVariable` or the factory supplied by your transformation context instead. */ + const createLoopVariable: () => Identifier; + /** @deprecated Use `factory.createUniqueName` or the factory supplied by your transformation context instead. */ + const createUniqueName: (text: string, flags?: GeneratedIdentifierFlags | undefined) => Identifier; + /** @deprecated Use `factory.createPrivateIdentifier` or the factory supplied by your transformation context instead. */ + const createPrivateIdentifier: (text: string) => PrivateIdentifier; + /** @deprecated Use `factory.createSuper` or the factory supplied by your transformation context instead. */ + const createSuper: () => SuperExpression; + /** @deprecated Use `factory.createThis` or the factory supplied by your transformation context instead. */ + const createThis: () => ThisExpression; + /** @deprecated Use `factory.createNull` or the factory supplied by your transformation context instead. */ + const createNull: () => NullLiteral; + /** @deprecated Use `factory.createTrue` or the factory supplied by your transformation context instead. */ + const createTrue: () => TrueLiteral; + /** @deprecated Use `factory.createFalse` or the factory supplied by your transformation context instead. */ + const createFalse: () => FalseLiteral; + /** @deprecated Use `factory.createModifier` or the factory supplied by your transformation context instead. */ + const createModifier: (kind: T) => ModifierToken; + /** @deprecated Use `factory.createModifiersFromModifierFlags` or the factory supplied by your transformation context instead. */ + const createModifiersFromModifierFlags: (flags: ModifierFlags) => Modifier[]; + /** @deprecated Use `factory.createQualifiedName` or the factory supplied by your transformation context instead. */ + const createQualifiedName: (left: EntityName, right: string | Identifier) => QualifiedName; + /** @deprecated Use `factory.updateQualifiedName` or the factory supplied by your transformation context instead. */ + const updateQualifiedName: (node: QualifiedName, left: EntityName, right: Identifier) => QualifiedName; + /** @deprecated Use `factory.createComputedPropertyName` or the factory supplied by your transformation context instead. */ + const createComputedPropertyName: (expression: Expression) => ComputedPropertyName; + /** @deprecated Use `factory.updateComputedPropertyName` or the factory supplied by your transformation context instead. */ + const updateComputedPropertyName: (node: ComputedPropertyName, expression: Expression) => ComputedPropertyName; + /** @deprecated Use `factory.createTypeParameterDeclaration` or the factory supplied by your transformation context instead. */ + const createTypeParameterDeclaration: (name: string | Identifier, constraint?: TypeNode | undefined, defaultType?: TypeNode | undefined) => TypeParameterDeclaration; + /** @deprecated Use `factory.updateTypeParameterDeclaration` or the factory supplied by your transformation context instead. */ + const updateTypeParameterDeclaration: (node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) => TypeParameterDeclaration; + /** @deprecated Use `factory.createParameterDeclaration` or the factory supplied by your transformation context instead. */ + const createParameter: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | Identifier | ObjectBindingPattern | ArrayBindingPattern, questionToken?: QuestionToken | undefined, type?: TypeNode | undefined, initializer?: Expression | undefined) => ParameterDeclaration; + /** @deprecated Use `factory.updateParameterDeclaration` or the factory supplied by your transformation context instead. */ + const updateParameter: (node: ParameterDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | Identifier | ObjectBindingPattern | ArrayBindingPattern, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) => ParameterDeclaration; + /** @deprecated Use `factory.createDecorator` or the factory supplied by your transformation context instead. */ + const createDecorator: (expression: Expression) => Decorator; + /** @deprecated Use `factory.updateDecorator` or the factory supplied by your transformation context instead. */ + const updateDecorator: (node: Decorator, expression: Expression) => Decorator; + /** @deprecated Use `factory.createPropertyDeclaration` or the factory supplied by your transformation context instead. */ + const createProperty: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) => PropertyDeclaration; + /** @deprecated Use `factory.updatePropertyDeclaration` or the factory supplied by your transformation context instead. */ + const updateProperty: (node: PropertyDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) => PropertyDeclaration; + /** @deprecated Use `factory.createMethodDeclaration` or the factory supplied by your transformation context instead. */ + const createMethod: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => MethodDeclaration; + /** @deprecated Use `factory.updateMethodDeclaration` or the factory supplied by your transformation context instead. */ + const updateMethod: (node: MethodDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => MethodDeclaration; + /** @deprecated Use `factory.createConstructorDeclaration` or the factory supplied by your transformation context instead. */ + const createConstructor: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined) => ConstructorDeclaration; + /** @deprecated Use `factory.updateConstructorDeclaration` or the factory supplied by your transformation context instead. */ + const updateConstructor: (node: ConstructorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined) => ConstructorDeclaration; + /** @deprecated Use `factory.createGetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + const createGetAccessor: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => GetAccessorDeclaration; + /** @deprecated Use `factory.updateGetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + const updateGetAccessor: (node: GetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => GetAccessorDeclaration; + /** @deprecated Use `factory.createSetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + const createSetAccessor: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, parameters: readonly ParameterDeclaration[], body: Block | undefined) => SetAccessorDeclaration; + /** @deprecated Use `factory.updateSetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + const updateSetAccessor: (node: SetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined) => SetAccessorDeclaration; + /** @deprecated Use `factory.createCallSignature` or the factory supplied by your transformation context instead. */ + const createCallSignature: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) => CallSignatureDeclaration; + /** @deprecated Use `factory.updateCallSignature` or the factory supplied by your transformation context instead. */ + const updateCallSignature: (node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) => CallSignatureDeclaration; + /** @deprecated Use `factory.createConstructSignature` or the factory supplied by your transformation context instead. */ + const createConstructSignature: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) => ConstructSignatureDeclaration; + /** @deprecated Use `factory.updateConstructSignature` or the factory supplied by your transformation context instead. */ + const updateConstructSignature: (node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) => ConstructSignatureDeclaration; + /** @deprecated Use `factory.updateIndexSignature` or the factory supplied by your transformation context instead. */ + const updateIndexSignature: (node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => IndexSignatureDeclaration; + /** @deprecated Use `factory.createKeywordTypeNode` or the factory supplied by your transformation context instead. */ + const createKeywordTypeNode: (kind: TKind) => KeywordTypeNode; + /** @deprecated Use `factory.createTypePredicateNode` or the factory supplied by your transformation context instead. */ + const createTypePredicateNodeWithModifier: (assertsModifier: AssertsKeyword | undefined, parameterName: string | Identifier | ThisTypeNode, type: TypeNode | undefined) => TypePredicateNode; + /** @deprecated Use `factory.updateTypePredicateNode` or the factory supplied by your transformation context instead. */ + const updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) => TypePredicateNode; + /** @deprecated Use `factory.createTypeReferenceNode` or the factory supplied by your transformation context instead. */ + const createTypeReferenceNode: (typeName: string | Identifier | QualifiedName, typeArguments?: readonly TypeNode[] | undefined) => TypeReferenceNode; + /** @deprecated Use `factory.updateTypeReferenceNode` or the factory supplied by your transformation context instead. */ + const updateTypeReferenceNode: (node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) => TypeReferenceNode; + /** @deprecated Use `factory.createFunctionTypeNode` or the factory supplied by your transformation context instead. */ + const createFunctionTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => FunctionTypeNode; + /** @deprecated Use `factory.updateFunctionTypeNode` or the factory supplied by your transformation context instead. */ + const updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => FunctionTypeNode; + /** @deprecated Use `factory.createConstructorTypeNode` or the factory supplied by your transformation context instead. */ + const createConstructorTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => ConstructorTypeNode; + /** @deprecated Use `factory.updateConstructorTypeNode` or the factory supplied by your transformation context instead. */ + const updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => ConstructorTypeNode; + /** @deprecated Use `factory.createTypeQueryNode` or the factory supplied by your transformation context instead. */ + const createTypeQueryNode: (exprName: EntityName) => TypeQueryNode; + /** @deprecated Use `factory.updateTypeQueryNode` or the factory supplied by your transformation context instead. */ + const updateTypeQueryNode: (node: TypeQueryNode, exprName: EntityName) => TypeQueryNode; + /** @deprecated Use `factory.createTypeLiteralNode` or the factory supplied by your transformation context instead. */ + const createTypeLiteralNode: (members: readonly TypeElement[] | undefined) => TypeLiteralNode; + /** @deprecated Use `factory.updateTypeLiteralNode` or the factory supplied by your transformation context instead. */ + const updateTypeLiteralNode: (node: TypeLiteralNode, members: NodeArray) => TypeLiteralNode; + /** @deprecated Use `factory.createArrayTypeNode` or the factory supplied by your transformation context instead. */ + const createArrayTypeNode: (elementType: TypeNode) => ArrayTypeNode; + /** @deprecated Use `factory.updateArrayTypeNode` or the factory supplied by your transformation context instead. */ + const updateArrayTypeNode: (node: ArrayTypeNode, elementType: TypeNode) => ArrayTypeNode; + /** @deprecated Use `factory.createTupleTypeNode` or the factory supplied by your transformation context instead. */ + const createTupleTypeNode: (elements: readonly (TypeNode | NamedTupleMember)[]) => TupleTypeNode; + /** @deprecated Use `factory.updateTupleTypeNode` or the factory supplied by your transformation context instead. */ + const updateTupleTypeNode: (node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]) => TupleTypeNode; + /** @deprecated Use `factory.createOptionalTypeNode` or the factory supplied by your transformation context instead. */ + const createOptionalTypeNode: (type: TypeNode) => OptionalTypeNode; + /** @deprecated Use `factory.updateOptionalTypeNode` or the factory supplied by your transformation context instead. */ + const updateOptionalTypeNode: (node: OptionalTypeNode, type: TypeNode) => OptionalTypeNode; + /** @deprecated Use `factory.createRestTypeNode` or the factory supplied by your transformation context instead. */ + const createRestTypeNode: (type: TypeNode) => RestTypeNode; + /** @deprecated Use `factory.updateRestTypeNode` or the factory supplied by your transformation context instead. */ + const updateRestTypeNode: (node: RestTypeNode, type: TypeNode) => RestTypeNode; + /** @deprecated Use `factory.createUnionTypeNode` or the factory supplied by your transformation context instead. */ + const createUnionTypeNode: (types: readonly TypeNode[]) => UnionTypeNode; + /** @deprecated Use `factory.updateUnionTypeNode` or the factory supplied by your transformation context instead. */ + const updateUnionTypeNode: (node: UnionTypeNode, types: NodeArray) => UnionTypeNode; + /** @deprecated Use `factory.createIntersectionTypeNode` or the factory supplied by your transformation context instead. */ + const createIntersectionTypeNode: (types: readonly TypeNode[]) => IntersectionTypeNode; + /** @deprecated Use `factory.updateIntersectionTypeNode` or the factory supplied by your transformation context instead. */ + const updateIntersectionTypeNode: (node: IntersectionTypeNode, types: NodeArray) => IntersectionTypeNode; + /** @deprecated Use `factory.createConditionalTypeNode` or the factory supplied by your transformation context instead. */ + const createConditionalTypeNode: (checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) => ConditionalTypeNode; + /** @deprecated Use `factory.updateConditionalTypeNode` or the factory supplied by your transformation context instead. */ + const updateConditionalTypeNode: (node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) => ConditionalTypeNode; + /** @deprecated Use `factory.createInferTypeNode` or the factory supplied by your transformation context instead. */ + const createInferTypeNode: (typeParameter: TypeParameterDeclaration) => InferTypeNode; + /** @deprecated Use `factory.updateInferTypeNode` or the factory supplied by your transformation context instead. */ + const updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) => InferTypeNode; + /** @deprecated Use `factory.createImportTypeNode` or the factory supplied by your transformation context instead. */ + const createImportTypeNode: (argument: TypeNode, qualifier?: Identifier | QualifiedName | undefined, typeArguments?: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; + /** @deprecated Use `factory.updateImportTypeNode` or the factory supplied by your transformation context instead. */ + const updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: Identifier | QualifiedName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; + /** @deprecated Use `factory.createParenthesizedType` or the factory supplied by your transformation context instead. */ + const createParenthesizedType: (type: TypeNode) => ParenthesizedTypeNode; + /** @deprecated Use `factory.updateParenthesizedType` or the factory supplied by your transformation context instead. */ + const updateParenthesizedType: (node: ParenthesizedTypeNode, type: TypeNode) => ParenthesizedTypeNode; + /** @deprecated Use `factory.createThisTypeNode` or the factory supplied by your transformation context instead. */ + const createThisTypeNode: () => ThisTypeNode; + /** @deprecated Use `factory.updateTypeOperatorNode` or the factory supplied by your transformation context instead. */ + const updateTypeOperatorNode: (node: TypeOperatorNode, type: TypeNode) => TypeOperatorNode; + /** @deprecated Use `factory.createIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */ + const createIndexedAccessTypeNode: (objectType: TypeNode, indexType: TypeNode) => IndexedAccessTypeNode; + /** @deprecated Use `factory.updateIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */ + const updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) => IndexedAccessTypeNode; + /** @deprecated Use `factory.createMappedTypeNode` or the factory supplied by your transformation context instead. */ + const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode; + /** @deprecated Use `factory.updateMappedTypeNode` or the factory supplied by your transformation context instead. */ + const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode; + /** @deprecated Use `factory.createLiteralTypeNode` or the factory supplied by your transformation context instead. */ + const createLiteralTypeNode: (literal: LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral) => LiteralTypeNode; + /** @deprecated Use `factory.updateLiteralTypeNode` or the factory supplied by your transformation context instead. */ + const updateLiteralTypeNode: (node: LiteralTypeNode, literal: LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral) => LiteralTypeNode; + /** @deprecated Use `factory.createObjectBindingPattern` or the factory supplied by your transformation context instead. */ + const createObjectBindingPattern: (elements: readonly BindingElement[]) => ObjectBindingPattern; + /** @deprecated Use `factory.updateObjectBindingPattern` or the factory supplied by your transformation context instead. */ + const updateObjectBindingPattern: (node: ObjectBindingPattern, elements: readonly BindingElement[]) => ObjectBindingPattern; + /** @deprecated Use `factory.createArrayBindingPattern` or the factory supplied by your transformation context instead. */ + const createArrayBindingPattern: (elements: readonly ArrayBindingElement[]) => ArrayBindingPattern; + /** @deprecated Use `factory.updateArrayBindingPattern` or the factory supplied by your transformation context instead. */ + const updateArrayBindingPattern: (node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]) => ArrayBindingPattern; + /** @deprecated Use `factory.createBindingElement` or the factory supplied by your transformation context instead. */ + const createBindingElement: (dotDotDotToken: DotDotDotToken | undefined, propertyName: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | undefined, name: string | Identifier | ObjectBindingPattern | ArrayBindingPattern, initializer?: Expression | undefined) => BindingElement; + /** @deprecated Use `factory.updateBindingElement` or the factory supplied by your transformation context instead. */ + const updateBindingElement: (node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | undefined, name: BindingName, initializer: Expression | undefined) => BindingElement; + /** @deprecated Use `factory.createArrayLiteral` or the factory supplied by your transformation context instead. */ + const createArrayLiteral: (elements?: readonly Expression[] | undefined, multiLine?: boolean | undefined) => ArrayLiteralExpression; + /** @deprecated Use `factory.updateArrayLiteral` or the factory supplied by your transformation context instead. */ + const updateArrayLiteral: (node: ArrayLiteralExpression, elements: readonly Expression[]) => ArrayLiteralExpression; + /** @deprecated Use `factory.createObjectLiteral` or the factory supplied by your transformation context instead. */ + const createObjectLiteral: (properties?: readonly ObjectLiteralElementLike[] | undefined, multiLine?: boolean | undefined) => ObjectLiteralExpression; + /** @deprecated Use `factory.updateObjectLiteral` or the factory supplied by your transformation context instead. */ + const updateObjectLiteral: (node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]) => ObjectLiteralExpression; + /** @deprecated Use `factory.createPropertyAccess` or the factory supplied by your transformation context instead. */ + const createPropertyAccess: (expression: Expression, name: string | Identifier | PrivateIdentifier) => PropertyAccessExpression; + /** @deprecated Use `factory.updatePropertyAccess` or the factory supplied by your transformation context instead. */ + const updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) => PropertyAccessExpression; + /** @deprecated Use `factory.createPropertyAccessChain` or the factory supplied by your transformation context instead. */ + const createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier) => PropertyAccessChain; + /** @deprecated Use `factory.updatePropertyAccessChain` or the factory supplied by your transformation context instead. */ + const updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier) => PropertyAccessChain; + /** @deprecated Use `factory.createElementAccess` or the factory supplied by your transformation context instead. */ + const createElementAccess: (expression: Expression, index: number | Expression) => ElementAccessExpression; + /** @deprecated Use `factory.updateElementAccess` or the factory supplied by your transformation context instead. */ + const updateElementAccess: (node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) => ElementAccessExpression; + /** @deprecated Use `factory.createElementAccessChain` or the factory supplied by your transformation context instead. */ + const createElementAccessChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression) => ElementAccessChain; + /** @deprecated Use `factory.updateElementAccessChain` or the factory supplied by your transformation context instead. */ + const updateElementAccessChain: (node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression) => ElementAccessChain; + /** @deprecated Use `factory.createCall` or the factory supplied by your transformation context instead. */ + const createCall: (expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) => CallExpression; + /** @deprecated Use `factory.updateCall` or the factory supplied by your transformation context instead. */ + const updateCall: (node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) => CallExpression; + /** @deprecated Use `factory.createCallChain` or the factory supplied by your transformation context instead. */ + const createCallChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) => CallChain; + /** @deprecated Use `factory.updateCallChain` or the factory supplied by your transformation context instead. */ + const updateCallChain: (node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) => CallChain; + /** @deprecated Use `factory.createNew` or the factory supplied by your transformation context instead. */ + const createNew: (expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) => NewExpression; + /** @deprecated Use `factory.updateNew` or the factory supplied by your transformation context instead. */ + const updateNew: (node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) => NewExpression; + /** @deprecated Use `factory.createTypeAssertion` or the factory supplied by your transformation context instead. */ + const createTypeAssertion: (type: TypeNode, expression: Expression) => TypeAssertion; + /** @deprecated Use `factory.updateTypeAssertion` or the factory supplied by your transformation context instead. */ + const updateTypeAssertion: (node: TypeAssertion, type: TypeNode, expression: Expression) => TypeAssertion; + /** @deprecated Use `factory.createParen` or the factory supplied by your transformation context instead. */ + const createParen: (expression: Expression) => ParenthesizedExpression; + /** @deprecated Use `factory.updateParen` or the factory supplied by your transformation context instead. */ + const updateParen: (node: ParenthesizedExpression, expression: Expression) => ParenthesizedExpression; + /** @deprecated Use `factory.createFunctionExpression` or the factory supplied by your transformation context instead. */ + const createFunctionExpression: (modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[] | undefined, type: TypeNode | undefined, body: Block) => FunctionExpression; + /** @deprecated Use `factory.updateFunctionExpression` or the factory supplied by your transformation context instead. */ + const updateFunctionExpression: (node: FunctionExpression, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block) => FunctionExpression; + /** @deprecated Use `factory.createDelete` or the factory supplied by your transformation context instead. */ + const createDelete: (expression: Expression) => DeleteExpression; + /** @deprecated Use `factory.updateDelete` or the factory supplied by your transformation context instead. */ + const updateDelete: (node: DeleteExpression, expression: Expression) => DeleteExpression; + /** @deprecated Use `factory.createTypeOf` or the factory supplied by your transformation context instead. */ + const createTypeOf: (expression: Expression) => TypeOfExpression; + /** @deprecated Use `factory.updateTypeOf` or the factory supplied by your transformation context instead. */ + const updateTypeOf: (node: TypeOfExpression, expression: Expression) => TypeOfExpression; + /** @deprecated Use `factory.createVoid` or the factory supplied by your transformation context instead. */ + const createVoid: (expression: Expression) => VoidExpression; + /** @deprecated Use `factory.updateVoid` or the factory supplied by your transformation context instead. */ + const updateVoid: (node: VoidExpression, expression: Expression) => VoidExpression; + /** @deprecated Use `factory.createAwait` or the factory supplied by your transformation context instead. */ + const createAwait: (expression: Expression) => AwaitExpression; + /** @deprecated Use `factory.updateAwait` or the factory supplied by your transformation context instead. */ + const updateAwait: (node: AwaitExpression, expression: Expression) => AwaitExpression; + /** @deprecated Use `factory.createPrefix` or the factory supplied by your transformation context instead. */ + const createPrefix: (operator: PrefixUnaryOperator, operand: Expression) => PrefixUnaryExpression; + /** @deprecated Use `factory.updatePrefix` or the factory supplied by your transformation context instead. */ + const updatePrefix: (node: PrefixUnaryExpression, operand: Expression) => PrefixUnaryExpression; + /** @deprecated Use `factory.createPostfix` or the factory supplied by your transformation context instead. */ + const createPostfix: (operand: Expression, operator: PostfixUnaryOperator) => PostfixUnaryExpression; + /** @deprecated Use `factory.updatePostfix` or the factory supplied by your transformation context instead. */ + const updatePostfix: (node: PostfixUnaryExpression, operand: Expression) => PostfixUnaryExpression; + /** @deprecated Use `factory.createBinary` or the factory supplied by your transformation context instead. */ + const createBinary: (left: Expression, operator: SyntaxKind.CommaToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.EqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.AsteriskToken | SyntaxKind.AsteriskAsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.QuestionQuestionToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | BinaryOperatorToken, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.updateConditional` or the factory supplied by your transformation context instead. */ + const updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) => ConditionalExpression; + /** @deprecated Use `factory.createTemplateExpression` or the factory supplied by your transformation context instead. */ + const createTemplateExpression: (head: TemplateHead, templateSpans: readonly TemplateSpan[]) => TemplateExpression; + /** @deprecated Use `factory.updateTemplateExpression` or the factory supplied by your transformation context instead. */ + const updateTemplateExpression: (node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]) => TemplateExpression; + /** @deprecated Use `factory.createTemplateHead` or the factory supplied by your transformation context instead. */ + const createTemplateHead: { + (text: string, rawText?: string | undefined, templateFlags?: TokenFlags | undefined): TemplateHead; + (text: string | undefined, rawText: string, templateFlags?: TokenFlags | undefined): TemplateHead; + }; + /** @deprecated Use `factory.createTemplateMiddle` or the factory supplied by your transformation context instead. */ + const createTemplateMiddle: { + (text: string, rawText?: string | undefined, templateFlags?: TokenFlags | undefined): TemplateMiddle; + (text: string | undefined, rawText: string, templateFlags?: TokenFlags | undefined): TemplateMiddle; + }; + /** @deprecated Use `factory.createTemplateTail` or the factory supplied by your transformation context instead. */ + const createTemplateTail: { + (text: string, rawText?: string | undefined, templateFlags?: TokenFlags | undefined): TemplateTail; + (text: string | undefined, rawText: string, templateFlags?: TokenFlags | undefined): TemplateTail; + }; + /** @deprecated Use `factory.createNoSubstitutionTemplateLiteral` or the factory supplied by your transformation context instead. */ + const createNoSubstitutionTemplateLiteral: { + (text: string, rawText?: string | undefined): NoSubstitutionTemplateLiteral; + (text: string | undefined, rawText: string): NoSubstitutionTemplateLiteral; + }; + /** @deprecated Use `factory.updateYield` or the factory supplied by your transformation context instead. */ + const updateYield: (node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression | undefined) => YieldExpression; + /** @deprecated Use `factory.createSpread` or the factory supplied by your transformation context instead. */ + const createSpread: (expression: Expression) => SpreadElement; + /** @deprecated Use `factory.updateSpread` or the factory supplied by your transformation context instead. */ + const updateSpread: (node: SpreadElement, expression: Expression) => SpreadElement; + /** @deprecated Use `factory.createOmittedExpression` or the factory supplied by your transformation context instead. */ + const createOmittedExpression: () => OmittedExpression; + /** @deprecated Use `factory.createAsExpression` or the factory supplied by your transformation context instead. */ + const createAsExpression: (expression: Expression, type: TypeNode) => AsExpression; + /** @deprecated Use `factory.updateAsExpression` or the factory supplied by your transformation context instead. */ + const updateAsExpression: (node: AsExpression, expression: Expression, type: TypeNode) => AsExpression; + /** @deprecated Use `factory.createNonNullExpression` or the factory supplied by your transformation context instead. */ + const createNonNullExpression: (expression: Expression) => NonNullExpression; + /** @deprecated Use `factory.updateNonNullExpression` or the factory supplied by your transformation context instead. */ + const updateNonNullExpression: (node: NonNullExpression, expression: Expression) => NonNullExpression; + /** @deprecated Use `factory.createNonNullChain` or the factory supplied by your transformation context instead. */ + const createNonNullChain: (expression: Expression) => NonNullChain; + /** @deprecated Use `factory.updateNonNullChain` or the factory supplied by your transformation context instead. */ + const updateNonNullChain: (node: NonNullChain, expression: Expression) => NonNullChain; + /** @deprecated Use `factory.createMetaProperty` or the factory supplied by your transformation context instead. */ + const createMetaProperty: (keywordToken: SyntaxKind.ImportKeyword | SyntaxKind.NewKeyword, name: Identifier) => MetaProperty; + /** @deprecated Use `factory.updateMetaProperty` or the factory supplied by your transformation context instead. */ + const updateMetaProperty: (node: MetaProperty, name: Identifier) => MetaProperty; + /** @deprecated Use `factory.createTemplateSpan` or the factory supplied by your transformation context instead. */ + const createTemplateSpan: (expression: Expression, literal: TemplateMiddle | TemplateTail) => TemplateSpan; + /** @deprecated Use `factory.updateTemplateSpan` or the factory supplied by your transformation context instead. */ + const updateTemplateSpan: (node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) => TemplateSpan; + /** @deprecated Use `factory.createSemicolonClassElement` or the factory supplied by your transformation context instead. */ + const createSemicolonClassElement: () => SemicolonClassElement; + /** @deprecated Use `factory.createBlock` or the factory supplied by your transformation context instead. */ + const createBlock: (statements: readonly Statement[], multiLine?: boolean | undefined) => Block; + /** @deprecated Use `factory.updateBlock` or the factory supplied by your transformation context instead. */ + const updateBlock: (node: Block, statements: readonly Statement[]) => Block; + /** @deprecated Use `factory.createVariableStatement` or the factory supplied by your transformation context instead. */ + const createVariableStatement: (modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]) => VariableStatement; + /** @deprecated Use `factory.updateVariableStatement` or the factory supplied by your transformation context instead. */ + const updateVariableStatement: (node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList) => VariableStatement; + /** @deprecated Use `factory.createEmptyStatement` or the factory supplied by your transformation context instead. */ + const createEmptyStatement: () => EmptyStatement; + /** @deprecated Use `factory.createExpressionStatement` or the factory supplied by your transformation context instead. */ + const createExpressionStatement: (expression: Expression) => ExpressionStatement; + /** @deprecated Use `factory.updateExpressionStatement` or the factory supplied by your transformation context instead. */ + const updateExpressionStatement: (node: ExpressionStatement, expression: Expression) => ExpressionStatement; + /** @deprecated Use `factory.createExpressionStatement` or the factory supplied by your transformation context instead. */ + const createStatement: (expression: Expression) => ExpressionStatement; + /** @deprecated Use `factory.updateExpressionStatement` or the factory supplied by your transformation context instead. */ + const updateStatement: (node: ExpressionStatement, expression: Expression) => ExpressionStatement; + /** @deprecated Use `factory.createIf` or the factory supplied by your transformation context instead. */ + const createIf: (expression: Expression, thenStatement: Statement, elseStatement?: Statement | undefined) => IfStatement; + /** @deprecated Use `factory.updateIf` or the factory supplied by your transformation context instead. */ + const updateIf: (node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined) => IfStatement; + /** @deprecated Use `factory.createDo` or the factory supplied by your transformation context instead. */ + const createDo: (statement: Statement, expression: Expression) => DoStatement; + /** @deprecated Use `factory.updateDo` or the factory supplied by your transformation context instead. */ + const updateDo: (node: DoStatement, statement: Statement, expression: Expression) => DoStatement; + /** @deprecated Use `factory.createWhile` or the factory supplied by your transformation context instead. */ + const createWhile: (expression: Expression, statement: Statement) => WhileStatement; + /** @deprecated Use `factory.updateWhile` or the factory supplied by your transformation context instead. */ + const updateWhile: (node: WhileStatement, expression: Expression, statement: Statement) => WhileStatement; + /** @deprecated Use `factory.createFor` or the factory supplied by your transformation context instead. */ + const createFor: (initializer: Expression | VariableDeclarationList | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) => ForStatement; + /** @deprecated Use `factory.updateFor` or the factory supplied by your transformation context instead. */ + const updateFor: (node: ForStatement, initializer: Expression | VariableDeclarationList | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) => ForStatement; + /** @deprecated Use `factory.createForIn` or the factory supplied by your transformation context instead. */ + const createForIn: (initializer: ForInitializer, expression: Expression, statement: Statement) => ForInStatement; + /** @deprecated Use `factory.updateForIn` or the factory supplied by your transformation context instead. */ + const updateForIn: (node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) => ForInStatement; + /** @deprecated Use `factory.createForOf` or the factory supplied by your transformation context instead. */ + const createForOf: (awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) => ForOfStatement; + /** @deprecated Use `factory.updateForOf` or the factory supplied by your transformation context instead. */ + const updateForOf: (node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) => ForOfStatement; + /** @deprecated Use `factory.createContinue` or the factory supplied by your transformation context instead. */ + const createContinue: (label?: string | Identifier | undefined) => ContinueStatement; + /** @deprecated Use `factory.updateContinue` or the factory supplied by your transformation context instead. */ + const updateContinue: (node: ContinueStatement, label: Identifier | undefined) => ContinueStatement; + /** @deprecated Use `factory.createBreak` or the factory supplied by your transformation context instead. */ + const createBreak: (label?: string | Identifier | undefined) => BreakStatement; + /** @deprecated Use `factory.updateBreak` or the factory supplied by your transformation context instead. */ + const updateBreak: (node: BreakStatement, label: Identifier | undefined) => BreakStatement; + /** @deprecated Use `factory.createReturn` or the factory supplied by your transformation context instead. */ + const createReturn: (expression?: Expression | undefined) => ReturnStatement; + /** @deprecated Use `factory.updateReturn` or the factory supplied by your transformation context instead. */ + const updateReturn: (node: ReturnStatement, expression: Expression | undefined) => ReturnStatement; + /** @deprecated Use `factory.createWith` or the factory supplied by your transformation context instead. */ + const createWith: (expression: Expression, statement: Statement) => WithStatement; + /** @deprecated Use `factory.updateWith` or the factory supplied by your transformation context instead. */ + const updateWith: (node: WithStatement, expression: Expression, statement: Statement) => WithStatement; + /** @deprecated Use `factory.createSwitch` or the factory supplied by your transformation context instead. */ + const createSwitch: (expression: Expression, caseBlock: CaseBlock) => SwitchStatement; + /** @deprecated Use `factory.updateSwitch` or the factory supplied by your transformation context instead. */ + const updateSwitch: (node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) => SwitchStatement; + /** @deprecated Use `factory.createLabel` or the factory supplied by your transformation context instead. */ + const createLabel: (label: string | Identifier, statement: Statement) => LabeledStatement; + /** @deprecated Use `factory.updateLabel` or the factory supplied by your transformation context instead. */ + const updateLabel: (node: LabeledStatement, label: Identifier, statement: Statement) => LabeledStatement; + /** @deprecated Use `factory.createThrow` or the factory supplied by your transformation context instead. */ + const createThrow: (expression: Expression) => ThrowStatement; + /** @deprecated Use `factory.updateThrow` or the factory supplied by your transformation context instead. */ + const updateThrow: (node: ThrowStatement, expression: Expression) => ThrowStatement; + /** @deprecated Use `factory.createTry` or the factory supplied by your transformation context instead. */ + const createTry: (tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) => TryStatement; + /** @deprecated Use `factory.updateTry` or the factory supplied by your transformation context instead. */ + const updateTry: (node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) => TryStatement; + /** @deprecated Use `factory.createDebuggerStatement` or the factory supplied by your transformation context instead. */ + const createDebuggerStatement: () => DebuggerStatement; + /** @deprecated Use `factory.createVariableDeclarationList` or the factory supplied by your transformation context instead. */ + const createVariableDeclarationList: (declarations: readonly VariableDeclaration[], flags?: NodeFlags | undefined) => VariableDeclarationList; + /** @deprecated Use `factory.updateVariableDeclarationList` or the factory supplied by your transformation context instead. */ + const updateVariableDeclarationList: (node: VariableDeclarationList, declarations: readonly VariableDeclaration[]) => VariableDeclarationList; + /** @deprecated Use `factory.createFunctionDeclaration` or the factory supplied by your transformation context instead. */ + const createFunctionDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => FunctionDeclaration; + /** @deprecated Use `factory.updateFunctionDeclaration` or the factory supplied by your transformation context instead. */ + const updateFunctionDeclaration: (node: FunctionDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => FunctionDeclaration; + /** @deprecated Use `factory.createClassDeclaration` or the factory supplied by your transformation context instead. */ + const createClassDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]) => ClassDeclaration; + /** @deprecated Use `factory.updateClassDeclaration` or the factory supplied by your transformation context instead. */ + const updateClassDeclaration: (node: ClassDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]) => ClassDeclaration; + /** @deprecated Use `factory.createInterfaceDeclaration` or the factory supplied by your transformation context instead. */ + const createInterfaceDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]) => InterfaceDeclaration; + /** @deprecated Use `factory.updateInterfaceDeclaration` or the factory supplied by your transformation context instead. */ + const updateInterfaceDeclaration: (node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]) => InterfaceDeclaration; + /** @deprecated Use `factory.createTypeAliasDeclaration` or the factory supplied by your transformation context instead. */ + const createTypeAliasDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode) => TypeAliasDeclaration; + /** @deprecated Use `factory.updateTypeAliasDeclaration` or the factory supplied by your transformation context instead. */ + const updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode) => TypeAliasDeclaration; + /** @deprecated Use `factory.createEnumDeclaration` or the factory supplied by your transformation context instead. */ + const createEnumDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]) => EnumDeclaration; + /** @deprecated Use `factory.updateEnumDeclaration` or the factory supplied by your transformation context instead. */ + const updateEnumDeclaration: (node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]) => EnumDeclaration; + /** @deprecated Use `factory.createModuleDeclaration` or the factory supplied by your transformation context instead. */ + const createModuleDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined, flags?: NodeFlags | undefined) => ModuleDeclaration; + /** @deprecated Use `factory.updateModuleDeclaration` or the factory supplied by your transformation context instead. */ + const updateModuleDeclaration: (node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined) => ModuleDeclaration; + /** @deprecated Use `factory.createModuleBlock` or the factory supplied by your transformation context instead. */ + const createModuleBlock: (statements: readonly Statement[]) => ModuleBlock; + /** @deprecated Use `factory.updateModuleBlock` or the factory supplied by your transformation context instead. */ + const updateModuleBlock: (node: ModuleBlock, statements: readonly Statement[]) => ModuleBlock; + /** @deprecated Use `factory.createCaseBlock` or the factory supplied by your transformation context instead. */ + const createCaseBlock: (clauses: readonly CaseOrDefaultClause[]) => CaseBlock; + /** @deprecated Use `factory.updateCaseBlock` or the factory supplied by your transformation context instead. */ + const updateCaseBlock: (node: CaseBlock, clauses: readonly CaseOrDefaultClause[]) => CaseBlock; + /** @deprecated Use `factory.createNamespaceExportDeclaration` or the factory supplied by your transformation context instead. */ + const createNamespaceExportDeclaration: (name: string | Identifier) => NamespaceExportDeclaration; + /** @deprecated Use `factory.updateNamespaceExportDeclaration` or the factory supplied by your transformation context instead. */ + const updateNamespaceExportDeclaration: (node: NamespaceExportDeclaration, name: Identifier) => NamespaceExportDeclaration; + /** @deprecated Use `factory.createImportEqualsDeclaration` or the factory supplied by your transformation context instead. */ + const createImportEqualsDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference) => ImportEqualsDeclaration; + /** @deprecated Use `factory.updateImportEqualsDeclaration` or the factory supplied by your transformation context instead. */ + const updateImportEqualsDeclaration: (node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference) => ImportEqualsDeclaration; + /** @deprecated Use `factory.createImportDeclaration` or the factory supplied by your transformation context instead. */ + const createImportDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression) => ImportDeclaration; + /** @deprecated Use `factory.updateImportDeclaration` or the factory supplied by your transformation context instead. */ + const updateImportDeclaration: (node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression) => ImportDeclaration; + /** @deprecated Use `factory.createNamespaceImport` or the factory supplied by your transformation context instead. */ + const createNamespaceImport: (name: Identifier) => NamespaceImport; + /** @deprecated Use `factory.updateNamespaceImport` or the factory supplied by your transformation context instead. */ + const updateNamespaceImport: (node: NamespaceImport, name: Identifier) => NamespaceImport; + /** @deprecated Use `factory.createNamedImports` or the factory supplied by your transformation context instead. */ + const createNamedImports: (elements: readonly ImportSpecifier[]) => NamedImports; + /** @deprecated Use `factory.updateNamedImports` or the factory supplied by your transformation context instead. */ + const updateNamedImports: (node: NamedImports, elements: readonly ImportSpecifier[]) => NamedImports; + /** @deprecated Use `factory.createImportSpecifier` or the factory supplied by your transformation context instead. */ + const createImportSpecifier: (propertyName: Identifier | undefined, name: Identifier) => ImportSpecifier; + /** @deprecated Use `factory.updateImportSpecifier` or the factory supplied by your transformation context instead. */ + const updateImportSpecifier: (node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier) => ImportSpecifier; + /** @deprecated Use `factory.createExportAssignment` or the factory supplied by your transformation context instead. */ + const createExportAssignment: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression) => ExportAssignment; + /** @deprecated Use `factory.updateExportAssignment` or the factory supplied by your transformation context instead. */ + const updateExportAssignment: (node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression) => ExportAssignment; + /** @deprecated Use `factory.createNamedExports` or the factory supplied by your transformation context instead. */ + const createNamedExports: (elements: readonly ExportSpecifier[]) => NamedExports; + /** @deprecated Use `factory.updateNamedExports` or the factory supplied by your transformation context instead. */ + const updateNamedExports: (node: NamedExports, elements: readonly ExportSpecifier[]) => NamedExports; + /** @deprecated Use `factory.createExportSpecifier` or the factory supplied by your transformation context instead. */ + const createExportSpecifier: (propertyName: string | Identifier | undefined, name: string | Identifier) => ExportSpecifier; + /** @deprecated Use `factory.updateExportSpecifier` or the factory supplied by your transformation context instead. */ + const updateExportSpecifier: (node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier) => ExportSpecifier; + /** @deprecated Use `factory.createExternalModuleReference` or the factory supplied by your transformation context instead. */ + const createExternalModuleReference: (expression: Expression) => ExternalModuleReference; + /** @deprecated Use `factory.updateExternalModuleReference` or the factory supplied by your transformation context instead. */ + const updateExternalModuleReference: (node: ExternalModuleReference, expression: Expression) => ExternalModuleReference; + /** @deprecated Use `factory.createJSDocTypeExpression` or the factory supplied by your transformation context instead. */ + const createJSDocTypeExpression: (type: TypeNode) => JSDocTypeExpression; + /** @deprecated Use `factory.createJSDocTypeTag` or the factory supplied by your transformation context instead. */ + const createJSDocTypeTag: (tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string | undefined) => JSDocTypeTag; + /** @deprecated Use `factory.createJSDocReturnTag` or the factory supplied by your transformation context instead. */ + const createJSDocReturnTag: (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocReturnTag; + /** @deprecated Use `factory.createJSDocThisTag` or the factory supplied by your transformation context instead. */ + const createJSDocThisTag: (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocThisTag; + /** @deprecated Use `factory.createJSDocComment` or the factory supplied by your transformation context instead. */ + const createJSDocComment: (comment?: string | undefined, tags?: readonly JSDocTag[] | undefined) => JSDoc; + /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ + const createJSDocParameterTag: (tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocParameterTag; + /** @deprecated Use `factory.createJSDocClassTag` or the factory supplied by your transformation context instead. */ + const createJSDocClassTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocClassTag; + /** @deprecated Use `factory.createJSDocAugmentsTag` or the factory supplied by your transformation context instead. */ + const createJSDocAugmentsTag: (tagName: Identifier | undefined, className: ExpressionWithTypeArguments & { + readonly expression: Identifier | PropertyAccessEntityNameExpression; + }, comment?: string | undefined) => JSDocAugmentsTag; + /** @deprecated Use `factory.createJSDocEnumTag` or the factory supplied by your transformation context instead. */ + const createJSDocEnumTag: (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocEnumTag; + /** @deprecated Use `factory.createJSDocTemplateTag` or the factory supplied by your transformation context instead. */ + const createJSDocTemplateTag: (tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string | undefined) => JSDocTemplateTag; + /** @deprecated Use `factory.createJSDocTypedefTag` or the factory supplied by your transformation context instead. */ + const createJSDocTypedefTag: (tagName: Identifier | undefined, typeExpression?: JSDocTypeLiteral | JSDocTypeExpression | undefined, fullName?: Identifier | JSDocNamespaceDeclaration | undefined, comment?: string | undefined) => JSDocTypedefTag; + /** @deprecated Use `factory.createJSDocCallbackTag` or the factory supplied by your transformation context instead. */ + const createJSDocCallbackTag: (tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration | undefined, comment?: string | undefined) => JSDocCallbackTag; + /** @deprecated Use `factory.createJSDocSignature` or the factory supplied by your transformation context instead. */ + const createJSDocSignature: (typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag | undefined) => JSDocSignature; + /** @deprecated Use `factory.createJSDocPropertyTag` or the factory supplied by your transformation context instead. */ + const createJSDocPropertyTag: (tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocPropertyTag; + /** @deprecated Use `factory.createJSDocTypeLiteral` or the factory supplied by your transformation context instead. */ + const createJSDocTypeLiteral: (jsDocPropertyTags?: readonly JSDocPropertyLikeTag[] | undefined, isArrayType?: boolean | undefined) => JSDocTypeLiteral; + /** @deprecated Use `factory.createJSDocImplementsTag` or the factory supplied by your transformation context instead. */ + const createJSDocImplementsTag: (tagName: Identifier | undefined, className: ExpressionWithTypeArguments & { + readonly expression: Identifier | PropertyAccessEntityNameExpression; + }, comment?: string | undefined) => JSDocImplementsTag; + /** @deprecated Use `factory.createJSDocAuthorTag` or the factory supplied by your transformation context instead. */ + const createJSDocAuthorTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocAuthorTag; + /** @deprecated Use `factory.createJSDocPublicTag` or the factory supplied by your transformation context instead. */ + const createJSDocPublicTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocPublicTag; + /** @deprecated Use `factory.createJSDocPrivateTag` or the factory supplied by your transformation context instead. */ + const createJSDocPrivateTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocPrivateTag; + /** @deprecated Use `factory.createJSDocProtectedTag` or the factory supplied by your transformation context instead. */ + const createJSDocProtectedTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocProtectedTag; + /** @deprecated Use `factory.createJSDocReadonlyTag` or the factory supplied by your transformation context instead. */ + const createJSDocReadonlyTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocReadonlyTag; + /** @deprecated Use `factory.createJSDocUnknownTag` or the factory supplied by your transformation context instead. */ + const createJSDocTag: (tagName: Identifier, comment?: string | undefined) => JSDocUnknownTag; + /** @deprecated Use `factory.createJsxElement` or the factory supplied by your transformation context instead. */ + const createJsxElement: (openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) => JsxElement; + /** @deprecated Use `factory.updateJsxElement` or the factory supplied by your transformation context instead. */ + const updateJsxElement: (node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) => JsxElement; + /** @deprecated Use `factory.createJsxSelfClosingElement` or the factory supplied by your transformation context instead. */ + const createJsxSelfClosingElement: (tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) => JsxSelfClosingElement; + /** @deprecated Use `factory.updateJsxSelfClosingElement` or the factory supplied by your transformation context instead. */ + const updateJsxSelfClosingElement: (node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) => JsxSelfClosingElement; + /** @deprecated Use `factory.createJsxOpeningElement` or the factory supplied by your transformation context instead. */ + const createJsxOpeningElement: (tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) => JsxOpeningElement; + /** @deprecated Use `factory.updateJsxOpeningElement` or the factory supplied by your transformation context instead. */ + const updateJsxOpeningElement: (node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) => JsxOpeningElement; + /** @deprecated Use `factory.createJsxClosingElement` or the factory supplied by your transformation context instead. */ + const createJsxClosingElement: (tagName: JsxTagNameExpression) => JsxClosingElement; + /** @deprecated Use `factory.updateJsxClosingElement` or the factory supplied by your transformation context instead. */ + const updateJsxClosingElement: (node: JsxClosingElement, tagName: JsxTagNameExpression) => JsxClosingElement; + /** @deprecated Use `factory.createJsxFragment` or the factory supplied by your transformation context instead. */ + const createJsxFragment: (openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) => JsxFragment; + /** @deprecated Use `factory.createJsxText` or the factory supplied by your transformation context instead. */ + const createJsxText: (text: string, containsOnlyTriviaWhiteSpaces?: boolean | undefined) => JsxText; + /** @deprecated Use `factory.updateJsxText` or the factory supplied by your transformation context instead. */ + const updateJsxText: (node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean | undefined) => JsxText; + /** @deprecated Use `factory.createJsxOpeningFragment` or the factory supplied by your transformation context instead. */ + const createJsxOpeningFragment: () => JsxOpeningFragment; + /** @deprecated Use `factory.createJsxJsxClosingFragment` or the factory supplied by your transformation context instead. */ + const createJsxJsxClosingFragment: () => JsxClosingFragment; + /** @deprecated Use `factory.updateJsxFragment` or the factory supplied by your transformation context instead. */ + const updateJsxFragment: (node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) => JsxFragment; + /** @deprecated Use `factory.createJsxAttribute` or the factory supplied by your transformation context instead. */ + const createJsxAttribute: (name: Identifier, initializer: StringLiteral | JsxExpression | undefined) => JsxAttribute; + /** @deprecated Use `factory.updateJsxAttribute` or the factory supplied by your transformation context instead. */ + const updateJsxAttribute: (node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression | undefined) => JsxAttribute; + /** @deprecated Use `factory.createJsxAttributes` or the factory supplied by your transformation context instead. */ + const createJsxAttributes: (properties: readonly JsxAttributeLike[]) => JsxAttributes; + /** @deprecated Use `factory.updateJsxAttributes` or the factory supplied by your transformation context instead. */ + const updateJsxAttributes: (node: JsxAttributes, properties: readonly JsxAttributeLike[]) => JsxAttributes; + /** @deprecated Use `factory.createJsxSpreadAttribute` or the factory supplied by your transformation context instead. */ + const createJsxSpreadAttribute: (expression: Expression) => JsxSpreadAttribute; + /** @deprecated Use `factory.updateJsxSpreadAttribute` or the factory supplied by your transformation context instead. */ + const updateJsxSpreadAttribute: (node: JsxSpreadAttribute, expression: Expression) => JsxSpreadAttribute; + /** @deprecated Use `factory.createJsxExpression` or the factory supplied by your transformation context instead. */ + const createJsxExpression: (dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) => JsxExpression; + /** @deprecated Use `factory.updateJsxExpression` or the factory supplied by your transformation context instead. */ + const updateJsxExpression: (node: JsxExpression, expression: Expression | undefined) => JsxExpression; + /** @deprecated Use `factory.createCaseClause` or the factory supplied by your transformation context instead. */ + const createCaseClause: (expression: Expression, statements: readonly Statement[]) => CaseClause; + /** @deprecated Use `factory.updateCaseClause` or the factory supplied by your transformation context instead. */ + const updateCaseClause: (node: CaseClause, expression: Expression, statements: readonly Statement[]) => CaseClause; + /** @deprecated Use `factory.createDefaultClause` or the factory supplied by your transformation context instead. */ + const createDefaultClause: (statements: readonly Statement[]) => DefaultClause; + /** @deprecated Use `factory.updateDefaultClause` or the factory supplied by your transformation context instead. */ + const updateDefaultClause: (node: DefaultClause, statements: readonly Statement[]) => DefaultClause; + /** @deprecated Use `factory.createHeritageClause` or the factory supplied by your transformation context instead. */ + const createHeritageClause: (token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword, types: readonly ExpressionWithTypeArguments[]) => HeritageClause; + /** @deprecated Use `factory.updateHeritageClause` or the factory supplied by your transformation context instead. */ + const updateHeritageClause: (node: HeritageClause, types: readonly ExpressionWithTypeArguments[]) => HeritageClause; + /** @deprecated Use `factory.createCatchClause` or the factory supplied by your transformation context instead. */ + const createCatchClause: (variableDeclaration: string | VariableDeclaration | undefined, block: Block) => CatchClause; + /** @deprecated Use `factory.updateCatchClause` or the factory supplied by your transformation context instead. */ + const updateCatchClause: (node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block) => CatchClause; + /** @deprecated Use `factory.createPropertyAssignment` or the factory supplied by your transformation context instead. */ + const createPropertyAssignment: (name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, initializer: Expression) => PropertyAssignment; + /** @deprecated Use `factory.updatePropertyAssignment` or the factory supplied by your transformation context instead. */ + const updatePropertyAssignment: (node: PropertyAssignment, name: PropertyName, initializer: Expression) => PropertyAssignment; + /** @deprecated Use `factory.createShorthandPropertyAssignment` or the factory supplied by your transformation context instead. */ + const createShorthandPropertyAssignment: (name: string | Identifier, objectAssignmentInitializer?: Expression | undefined) => ShorthandPropertyAssignment; + /** @deprecated Use `factory.updateShorthandPropertyAssignment` or the factory supplied by your transformation context instead. */ + const updateShorthandPropertyAssignment: (node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) => ShorthandPropertyAssignment; + /** @deprecated Use `factory.createSpreadAssignment` or the factory supplied by your transformation context instead. */ + const createSpreadAssignment: (expression: Expression) => SpreadAssignment; + /** @deprecated Use `factory.updateSpreadAssignment` or the factory supplied by your transformation context instead. */ + const updateSpreadAssignment: (node: SpreadAssignment, expression: Expression) => SpreadAssignment; + /** @deprecated Use `factory.createEnumMember` or the factory supplied by your transformation context instead. */ + const createEnumMember: (name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, initializer?: Expression | undefined) => EnumMember; + /** @deprecated Use `factory.updateEnumMember` or the factory supplied by your transformation context instead. */ + const updateEnumMember: (node: EnumMember, name: PropertyName, initializer: Expression | undefined) => EnumMember; + /** @deprecated Use `factory.updateSourceFile` or the factory supplied by your transformation context instead. */ + const updateSourceFileNode: (node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean | undefined, referencedFiles?: readonly FileReference[] | undefined, typeReferences?: readonly FileReference[] | undefined, hasNoDefaultLib?: boolean | undefined, libReferences?: readonly FileReference[] | undefined) => SourceFile; + /** @deprecated Use `factory.createNotEmittedStatement` or the factory supplied by your transformation context instead. */ + const createNotEmittedStatement: (original: Node) => NotEmittedStatement; + /** @deprecated Use `factory.createPartiallyEmittedExpression` or the factory supplied by your transformation context instead. */ + const createPartiallyEmittedExpression: (expression: Expression, original?: Node | undefined) => PartiallyEmittedExpression; + /** @deprecated Use `factory.updatePartiallyEmittedExpression` or the factory supplied by your transformation context instead. */ + const updatePartiallyEmittedExpression: (node: PartiallyEmittedExpression, expression: Expression) => PartiallyEmittedExpression; + /** @deprecated Use `factory.createCommaList` or the factory supplied by your transformation context instead. */ + const createCommaList: (elements: readonly Expression[]) => CommaListExpression; + /** @deprecated Use `factory.updateCommaList` or the factory supplied by your transformation context instead. */ + const updateCommaList: (node: CommaListExpression, elements: readonly Expression[]) => CommaListExpression; + /** @deprecated Use `factory.createBundle` or the factory supplied by your transformation context instead. */ + const createBundle: (sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[] | undefined) => Bundle; + /** @deprecated Use `factory.updateBundle` or the factory supplied by your transformation context instead. */ + const updateBundle: (node: Bundle, sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[] | undefined) => Bundle; + /** @deprecated Use `factory.createImmediatelyInvokedFunctionExpression` or the factory supplied by your transformation context instead. */ + const createImmediatelyInvokedFunctionExpression: { + (statements: readonly Statement[]): CallExpression; + (statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + }; + /** @deprecated Use `factory.createImmediatelyInvokedArrowFunction` or the factory supplied by your transformation context instead. */ + const createImmediatelyInvokedArrowFunction: { + (statements: readonly Statement[]): CallExpression; + (statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + }; + /** @deprecated Use `factory.createVoidZero` or the factory supplied by your transformation context instead. */ + const createVoidZero: () => VoidExpression; + /** @deprecated Use `factory.createExportDefault` or the factory supplied by your transformation context instead. */ + const createExportDefault: (expression: Expression) => ExportAssignment; + /** @deprecated Use `factory.createExternalModuleExport` or the factory supplied by your transformation context instead. */ + const createExternalModuleExport: (exportName: Identifier) => ExportDeclaration; + /** @deprecated Use `factory.createNamespaceExport` or the factory supplied by your transformation context instead. */ + const createNamespaceExport: (name: Identifier) => NamespaceExport; + /** @deprecated Use `factory.updateNamespaceExport` or the factory supplied by your transformation context instead. */ + const updateNamespaceExport: (node: NamespaceExport, name: Identifier) => NamespaceExport; + /** @deprecated Use `factory.createToken` or the factory supplied by your transformation context instead. */ + const createToken: (kind: TKind) => Token; + /** @deprecated Use `factory.createIdentifier` or the factory supplied by your transformation context instead. */ + const createIdentifier: (text: string) => Identifier; + /** @deprecated Use `factory.createTempVariable` or the factory supplied by your transformation context instead. */ + const createTempVariable: (recordTempVariable: ((node: Identifier) => void) | undefined) => Identifier; + /** @deprecated Use `factory.getGeneratedNameForNode` or the factory supplied by your transformation context instead. */ + const getGeneratedNameForNode: (node: Node | undefined) => Identifier; + /** @deprecated Use `factory.createUniqueName(text, GeneratedIdentifierFlags.Optimistic)` or the factory supplied by your transformation context instead. */ + const createOptimisticUniqueName: (text: string) => Identifier; + /** @deprecated Use `factory.createUniqueName(text, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)` or the factory supplied by your transformation context instead. */ + const createFileLevelUniqueName: (text: string) => Identifier; + /** @deprecated Use `factory.createIndexSignature` or the factory supplied by your transformation context instead. */ + const createIndexSignature: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => IndexSignatureDeclaration; + /** @deprecated Use `factory.createTypePredicateNode` or the factory supplied by your transformation context instead. */ + const createTypePredicateNode: (parameterName: Identifier | ThisTypeNode | string, type: TypeNode) => TypePredicateNode; + /** @deprecated Use `factory.updateTypePredicateNode` or the factory supplied by your transformation context instead. */ + const updateTypePredicateNode: (node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) => TypePredicateNode; + /** @deprecated Use `factory.createStringLiteral`, `factory.createStringLiteralFromNode`, `factory.createNumericLiteral`, `factory.createBigIntLiteral`, `factory.createTrue`, `factory.createFalse`, or the factory supplied by your transformation context instead. */ + const createLiteral: { + (value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; + (value: number | PseudoBigInt): NumericLiteral; + (value: boolean): BooleanLiteral; + (value: string | number | PseudoBigInt | boolean): PrimaryExpression; + }; + /** @deprecated Use `factory.createMethodSignature` or the factory supplied by your transformation context instead. */ + const createMethodSignature: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined) => MethodSignature; + /** @deprecated Use `factory.updateMethodSignature` or the factory supplied by your transformation context instead. */ + const updateMethodSignature: (node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined) => MethodSignature; + /** @deprecated Use `factory.createTypeOperatorNode` or the factory supplied by your transformation context instead. */ + const createTypeOperatorNode: { + (type: TypeNode): TypeOperatorNode; + (operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; + }; + /** @deprecated Use `factory.createTaggedTemplate` or the factory supplied by your transformation context instead. */ + const createTaggedTemplate: { + (tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + (tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + }; + /** @deprecated Use `factory.updateTaggedTemplate` or the factory supplied by your transformation context instead. */ + const updateTaggedTemplate: { + (node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + (node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + }; + /** @deprecated Use `factory.updateBinary` or the factory supplied by your transformation context instead. */ + const updateBinary: (node: BinaryExpression, left: Expression, right: Expression, operator?: BinaryOperator | BinaryOperatorToken) => BinaryExpression; + /** @deprecated Use `factory.createConditional` or the factory supplied by your transformation context instead. */ + const createConditional: { + (condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; + (condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; + }; + /** @deprecated Use `factory.createYield` or the factory supplied by your transformation context instead. */ + const createYield: { + (expression?: Expression | undefined): YieldExpression; + (asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; + }; + /** @deprecated Use `factory.createClassExpression` or the factory supplied by your transformation context instead. */ + const createClassExpression: (modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]) => ClassExpression; + /** @deprecated Use `factory.updateClassExpression` or the factory supplied by your transformation context instead. */ + const updateClassExpression: (node: ClassExpression, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]) => ClassExpression; + /** @deprecated Use `factory.createPropertySignature` or the factory supplied by your transformation context instead. */ + const createPropertySignature: (modifiers: readonly Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer?: Expression | undefined) => PropertySignature; + /** @deprecated Use `factory.updatePropertySignature` or the factory supplied by your transformation context instead. */ + const updatePropertySignature: (node: PropertySignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) => PropertySignature; + /** @deprecated Use `factory.createExpressionWithTypeArguments` or the factory supplied by your transformation context instead. */ + const createExpressionWithTypeArguments: (typeArguments: readonly TypeNode[] | undefined, expression: Expression) => ExpressionWithTypeArguments; + /** @deprecated Use `factory.updateExpressionWithTypeArguments` or the factory supplied by your transformation context instead. */ + const updateExpressionWithTypeArguments: (node: ExpressionWithTypeArguments, typeArguments: readonly TypeNode[] | undefined, expression: Expression) => ExpressionWithTypeArguments; + /** @deprecated Use `factory.createArrowFunction` or the factory supplied by your transformation context instead. */ + const createArrowFunction: { + (modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; + (modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + }; + /** @deprecated Use `factory.updateArrowFunction` or the factory supplied by your transformation context instead. */ + const updateArrowFunction: { + (node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody): ArrowFunction; + (node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + }; + /** @deprecated Use `factory.createVariableDeclaration` or the factory supplied by your transformation context instead. */ + const createVariableDeclaration: { + (name: string | BindingName, type?: TypeNode | undefined, initializer?: Expression | undefined): VariableDeclaration; + (name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + }; + /** @deprecated Use `factory.updateVariableDeclaration` or the factory supplied by your transformation context instead. */ + const updateVariableDeclaration: { + (node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + (node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + }; + /** @deprecated Use `factory.createImportClause` or the factory supplied by your transformation context instead. */ + const createImportClause: (name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly?: any) => ImportClause; + /** @deprecated Use `factory.updateImportClause` or the factory supplied by your transformation context instead. */ + const updateImportClause: (node: ImportClause, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly: boolean) => ImportClause; + /** @deprecated Use `factory.createExportDeclaration` or the factory supplied by your transformation context instead. */ + const createExportDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression | undefined, isTypeOnly?: any) => ExportDeclaration; + /** @deprecated Use `factory.updateExportDeclaration` or the factory supplied by your transformation context instead. */ + const updateExportDeclaration: (node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined, isTypeOnly: boolean) => ExportDeclaration; + /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ + const createJSDocParamTag: (name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocParameterTag; + /** @deprecated Use `factory.createComma` or the factory supplied by your transformation context instead. */ + const createComma: (left: Expression, right: Expression) => Expression; + /** @deprecated Use `factory.createLessThan` or the factory supplied by your transformation context instead. */ + const createLessThan: (left: Expression, right: Expression) => Expression; + /** @deprecated Use `factory.createAssignment` or the factory supplied by your transformation context instead. */ + const createAssignment: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createStrictEquality` or the factory supplied by your transformation context instead. */ + const createStrictEquality: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createStrictInequality` or the factory supplied by your transformation context instead. */ + const createStrictInequality: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createAdd` or the factory supplied by your transformation context instead. */ + const createAdd: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createSubtract` or the factory supplied by your transformation context instead. */ + const createSubtract: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createLogicalAnd` or the factory supplied by your transformation context instead. */ + const createLogicalAnd: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createLogicalOr` or the factory supplied by your transformation context instead. */ + const createLogicalOr: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createPostfixIncrement` or the factory supplied by your transformation context instead. */ + const createPostfixIncrement: (operand: Expression) => PostfixUnaryExpression; + /** @deprecated Use `factory.createLogicalNot` or the factory supplied by your transformation context instead. */ + const createLogicalNot: (operand: Expression) => PrefixUnaryExpression; + /** @deprecated Use an appropriate `factory` method instead. */ + const createNode: (kind: SyntaxKind, pos?: any, end?: any) => Node; + /** + * Creates a shallow, memberwise clone of a node ~for mutation~ with its `pos`, `end`, and `parent` set. + * + * NOTE: It is unsafe to change any properties of a `Node` that relate to its AST children, as those changes won't be + * captured with respect to transformations. + * + * @deprecated Use `factory.cloneNode` instead and use `setCommentRange` or `setSourceMapRange` and avoid setting `parent`. + */ + const getMutableClone: (node: T) => T; + /** @deprecated Use `isTypeAssertionExpression` instead. */ + const isTypeAssertion: (node: Node) => node is TypeAssertion; +} export = ts; export as namespace ts; \ No newline at end of file diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 24b2ff120026d..0b62806635ec9 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -70,9 +70,10 @@ declare namespace ts { pos: number; end: number; } - export type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; - export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword; - export type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; + export interface ReadonlyTextRange { + readonly pos: number; + readonly end: number; + } export enum SyntaxKind { Unknown = 0, EndOfFileToken = 1, @@ -443,6 +444,16 @@ declare namespace ts { FirstJSDocTagNode = 310, LastJSDocTagNode = 327, } + export type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; + export type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; + export type PseudoLiteralSyntaxKind = SyntaxKind.TemplateHead | SyntaxKind.TemplateMiddle | SyntaxKind.TemplateTail; + export type PunctuationSyntaxKind = SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.CloseParenToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.DotToken | SyntaxKind.DotDotDotToken | SyntaxKind.SemicolonToken | SyntaxKind.CommaToken | SyntaxKind.QuestionDotToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanSlashToken | SyntaxKind.GreaterThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.EqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.EqualsGreaterThanToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.AsteriskToken | SyntaxKind.AsteriskAsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.ExclamationToken | SyntaxKind.TildeToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.QuestionQuestionToken | SyntaxKind.QuestionToken | SyntaxKind.ColonToken | SyntaxKind.AtToken | SyntaxKind.BacktickToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken; + export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword; + export type ModifierSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.ConstKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.ExportKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.StaticKeyword; + export type KeywordTypeSyntaxKind = SyntaxKind.AnyKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VoidKeyword; + export type TokenSyntaxKind = SyntaxKind.Unknown | SyntaxKind.EndOfFileToken | TriviaSyntaxKind | LiteralSyntaxKind | PseudoLiteralSyntaxKind | PunctuationSyntaxKind | SyntaxKind.Identifier | KeywordSyntaxKind; + export type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; + export type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; export enum NodeFlags { None = 0, Let = 1, @@ -503,60 +514,91 @@ declare namespace ts { IntrinsicIndexedElement = 2, IntrinsicElement = 3 } - export interface Node extends TextRange { - kind: SyntaxKind; - flags: NodeFlags; - decorators?: NodeArray; - modifiers?: ModifiersArray; - parent: Node; + export interface Node extends ReadonlyTextRange { + readonly kind: SyntaxKind; + readonly flags: NodeFlags; + readonly decorators?: NodeArray; + readonly modifiers?: ModifiersArray; + readonly parent: Node; } export interface JSDocContainer { } - export type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | EndOfFileToken; + export type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | EndOfFileToken; export type HasType = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertySignature | PropertyDeclaration | TypePredicateNode | ParenthesizedTypeNode | TypeOperatorNode | MappedTypeNode | AssertionExpression | TypeAliasDeclaration | JSDocTypeExpression | JSDocNonNullableType | JSDocNullableType | JSDocOptionalType | JSDocVariadicType; export type HasTypeArguments = CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement | JsxSelfClosingElement; export type HasInitializer = HasExpressionInitializer | ForStatement | ForInStatement | ForOfStatement | JsxAttribute; export type HasExpressionInitializer = VariableDeclaration | ParameterDeclaration | BindingElement | PropertySignature | PropertyDeclaration | PropertyAssignment | EnumMember; - export interface NodeArray extends ReadonlyArray, TextRange { + export interface NodeArray extends ReadonlyArray, ReadonlyTextRange { hasTrailingComma?: boolean; } export interface Token extends Node { - kind: TKind; - } - export type DotToken = Token; - export type DotDotDotToken = Token; - export type QuestionToken = Token; - export type QuestionDotToken = Token; - export type ExclamationToken = Token; - export type ColonToken = Token; - export type EqualsToken = Token; - export type AsteriskToken = Token; - export type EqualsGreaterThanToken = Token; + readonly kind: TKind; + } export type EndOfFileToken = Token & JSDocContainer; - export type ReadonlyToken = Token; - export type AwaitKeywordToken = Token; - export type PlusToken = Token; - export type MinusToken = Token; - export type AssertsToken = Token; - export type Modifier = Token | Token | Token | Token | Token | Token | Token | Token | Token | Token | Token; + export interface PunctuationToken extends Token { + } + export type DotToken = PunctuationToken; + export type DotDotDotToken = PunctuationToken; + export type QuestionToken = PunctuationToken; + export type ExclamationToken = PunctuationToken; + export type ColonToken = PunctuationToken; + export type EqualsToken = PunctuationToken; + export type AsteriskToken = PunctuationToken; + export type EqualsGreaterThanToken = PunctuationToken; + export type PlusToken = PunctuationToken; + export type MinusToken = PunctuationToken; + export type QuestionDotToken = PunctuationToken; + export interface KeywordToken extends Token { + } + export type AssertsKeyword = KeywordToken; + export type AwaitKeyword = KeywordToken; + /** @deprecated Use `AwaitKeyword` instead. */ + export type AwaitKeywordToken = AwaitKeyword; + /** @deprecated Use `AssertsKeyword` instead. */ + export type AssertsToken = AssertsKeyword; + export interface ModifierToken extends KeywordToken { + } + export type AbstractKeyword = ModifierToken; + export type AsyncKeyword = ModifierToken; + export type ConstKeyword = ModifierToken; + export type DeclareKeyword = ModifierToken; + export type DefaultKeyword = ModifierToken; + export type ExportKeyword = ModifierToken; + export type PrivateKeyword = ModifierToken; + export type ProtectedKeyword = ModifierToken; + export type PublicKeyword = ModifierToken; + export type ReadonlyKeyword = ModifierToken; + export type StaticKeyword = ModifierToken; + /** @deprecated Use `ReadonlyKeyword` instead. */ + export type ReadonlyToken = ReadonlyKeyword; + export type Modifier = AbstractKeyword | AsyncKeyword | ConstKeyword | DeclareKeyword | DefaultKeyword | ExportKeyword | PrivateKeyword | ProtectedKeyword | PublicKeyword | ReadonlyKeyword | StaticKeyword; + export type AccessibilityModifier = PublicKeyword | PrivateKeyword | ProtectedKeyword; + export type ParameterPropertyModifier = AccessibilityModifier | ReadonlyKeyword; + export type ClassMemberModifier = AccessibilityModifier | ReadonlyKeyword | StaticKeyword; export type ModifiersArray = NodeArray; + export enum GeneratedIdentifierFlags { + None = 0, + ReservedInNestedScopes = 8, + Optimistic = 16, + FileLevel = 32 + } export interface Identifier extends PrimaryExpression, Declaration { - kind: SyntaxKind.Identifier; + readonly kind: SyntaxKind.Identifier; /** * Prefer to use `id.unescapedText`. (Note: This is available only in services, not internally to the TypeScript compiler.) * Text of identifier, but if the identifier begins with two underscores, this will begin with three. */ - escapedText: __String; - originalKeywordKind?: SyntaxKind; + readonly escapedText: __String; + readonly originalKeywordKind?: SyntaxKind; isInJSDocNamespace?: boolean; } export interface TransientIdentifier extends Identifier { resolvedSymbol: Symbol; } export interface QualifiedName extends Node { - kind: SyntaxKind.QualifiedName; - left: EntityName; - right: Identifier; + readonly kind: SyntaxKind.QualifiedName; + readonly left: EntityName; + readonly right: Identifier; } export type EntityName = Identifier | QualifiedName; export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier; @@ -565,135 +607,136 @@ declare namespace ts { _declarationBrand: any; } export interface NamedDeclaration extends Declaration { - name?: DeclarationName; + readonly name?: DeclarationName; } export interface DeclarationStatement extends NamedDeclaration, Statement { - name?: Identifier | StringLiteral | NumericLiteral; + readonly name?: Identifier | StringLiteral | NumericLiteral; } export interface ComputedPropertyName extends Node { - parent: Declaration; - kind: SyntaxKind.ComputedPropertyName; - expression: Expression; + readonly kind: SyntaxKind.ComputedPropertyName; + readonly parent: Declaration; + readonly expression: Expression; } export interface PrivateIdentifier extends Node { - kind: SyntaxKind.PrivateIdentifier; - escapedText: __String; + readonly kind: SyntaxKind.PrivateIdentifier; + readonly escapedText: __String; } export interface Decorator extends Node { - kind: SyntaxKind.Decorator; - parent: NamedDeclaration; - expression: LeftHandSideExpression; + readonly kind: SyntaxKind.Decorator; + readonly parent: NamedDeclaration; + readonly expression: LeftHandSideExpression; } export interface TypeParameterDeclaration extends NamedDeclaration { - kind: SyntaxKind.TypeParameter; - parent: DeclarationWithTypeParameterChildren | InferTypeNode; - name: Identifier; + readonly kind: SyntaxKind.TypeParameter; + readonly parent: DeclarationWithTypeParameterChildren | InferTypeNode; + readonly name: Identifier; /** Note: Consider calling `getEffectiveConstraintOfTypeParameter` */ - constraint?: TypeNode; - default?: TypeNode; + readonly constraint?: TypeNode; + readonly default?: TypeNode; expression?: Expression; } export interface SignatureDeclarationBase extends NamedDeclaration, JSDocContainer { - kind: SignatureDeclaration["kind"]; - name?: PropertyName; - typeParameters?: NodeArray; - parameters: NodeArray; - type?: TypeNode; + readonly kind: SignatureDeclaration["kind"]; + readonly name?: PropertyName; + readonly typeParameters?: NodeArray; + readonly parameters: NodeArray; + readonly type?: TypeNode; } export type SignatureDeclaration = CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | AccessorDeclaration | FunctionExpression | ArrowFunction; export interface CallSignatureDeclaration extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.CallSignature; + readonly kind: SyntaxKind.CallSignature; } export interface ConstructSignatureDeclaration extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.ConstructSignature; + readonly kind: SyntaxKind.ConstructSignature; } export type BindingName = Identifier | BindingPattern; export interface VariableDeclaration extends NamedDeclaration { - kind: SyntaxKind.VariableDeclaration; - parent: VariableDeclarationList | CatchClause; - name: BindingName; - exclamationToken?: ExclamationToken; - type?: TypeNode; - initializer?: Expression; + readonly kind: SyntaxKind.VariableDeclaration; + readonly parent: VariableDeclarationList | CatchClause; + readonly name: BindingName; + readonly exclamationToken?: ExclamationToken; + readonly type?: TypeNode; + readonly initializer?: Expression; } export interface VariableDeclarationList extends Node { - kind: SyntaxKind.VariableDeclarationList; - parent: VariableStatement | ForStatement | ForOfStatement | ForInStatement; - declarations: NodeArray; + readonly kind: SyntaxKind.VariableDeclarationList; + readonly parent: VariableStatement | ForStatement | ForOfStatement | ForInStatement; + readonly declarations: NodeArray; } export interface ParameterDeclaration extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.Parameter; - parent: SignatureDeclaration; - dotDotDotToken?: DotDotDotToken; - name: BindingName; - questionToken?: QuestionToken; - type?: TypeNode; - initializer?: Expression; + readonly kind: SyntaxKind.Parameter; + readonly parent: SignatureDeclaration; + readonly dotDotDotToken?: DotDotDotToken; + readonly name: BindingName; + readonly questionToken?: QuestionToken; + readonly type?: TypeNode; + readonly initializer?: Expression; } export interface BindingElement extends NamedDeclaration { - kind: SyntaxKind.BindingElement; - parent: BindingPattern; - propertyName?: PropertyName; - dotDotDotToken?: DotDotDotToken; - name: BindingName; - initializer?: Expression; + readonly kind: SyntaxKind.BindingElement; + readonly parent: BindingPattern; + readonly propertyName?: PropertyName; + readonly dotDotDotToken?: DotDotDotToken; + readonly name: BindingName; + readonly initializer?: Expression; } export interface PropertySignature extends TypeElement, JSDocContainer { - kind: SyntaxKind.PropertySignature; - name: PropertyName; - questionToken?: QuestionToken; - type?: TypeNode; + readonly kind: SyntaxKind.PropertySignature; + readonly name: PropertyName; + readonly questionToken?: QuestionToken; + readonly type?: TypeNode; initializer?: Expression; } export interface PropertyDeclaration extends ClassElement, JSDocContainer { - kind: SyntaxKind.PropertyDeclaration; - parent: ClassLikeDeclaration; - name: PropertyName; - questionToken?: QuestionToken; - exclamationToken?: ExclamationToken; - type?: TypeNode; - initializer?: Expression; + readonly kind: SyntaxKind.PropertyDeclaration; + readonly parent: ClassLikeDeclaration; + readonly name: PropertyName; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly type?: TypeNode; + readonly initializer?: Expression; } export interface ObjectLiteralElement extends NamedDeclaration { _objectLiteralBrand: any; - name?: PropertyName; + readonly name?: PropertyName; } /** Unlike ObjectLiteralElement, excludes JSXAttribute and JSXSpreadAttribute. */ export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | MethodDeclaration | AccessorDeclaration; export interface PropertyAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.PropertyAssignment; - name: PropertyName; - questionToken?: QuestionToken; - initializer: Expression; + readonly kind: SyntaxKind.PropertyAssignment; + readonly parent: ObjectLiteralExpression; + readonly name: PropertyName; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly initializer: Expression; } export interface ShorthandPropertyAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.ShorthandPropertyAssignment; - name: Identifier; - questionToken?: QuestionToken; - exclamationToken?: ExclamationToken; - equalsToken?: Token; - objectAssignmentInitializer?: Expression; + readonly kind: SyntaxKind.ShorthandPropertyAssignment; + readonly parent: ObjectLiteralExpression; + readonly name: Identifier; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly equalsToken?: EqualsToken; + readonly objectAssignmentInitializer?: Expression; } export interface SpreadAssignment extends ObjectLiteralElement, JSDocContainer { - parent: ObjectLiteralExpression; - kind: SyntaxKind.SpreadAssignment; - expression: Expression; + readonly kind: SyntaxKind.SpreadAssignment; + readonly parent: ObjectLiteralExpression; + readonly expression: Expression; } export type VariableLikeDeclaration = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyDeclaration | PropertyAssignment | PropertySignature | JsxAttribute | ShorthandPropertyAssignment | EnumMember | JSDocPropertyTag | JSDocParameterTag; export interface PropertyLikeDeclaration extends NamedDeclaration { - name: PropertyName; + readonly name: PropertyName; } export interface ObjectBindingPattern extends Node { - kind: SyntaxKind.ObjectBindingPattern; - parent: VariableDeclaration | ParameterDeclaration | BindingElement; - elements: NodeArray; + readonly kind: SyntaxKind.ObjectBindingPattern; + readonly parent: VariableDeclaration | ParameterDeclaration | BindingElement; + readonly elements: NodeArray; } export interface ArrayBindingPattern extends Node { - kind: SyntaxKind.ArrayBindingPattern; - parent: VariableDeclaration | ParameterDeclaration | BindingElement; - elements: NodeArray; + readonly kind: SyntaxKind.ArrayBindingPattern; + readonly parent: VariableDeclaration | ParameterDeclaration | BindingElement; + readonly elements: NodeArray; } export type BindingPattern = ObjectBindingPattern | ArrayBindingPattern; export type ArrayBindingElement = BindingElement | OmittedExpression; @@ -707,187 +750,189 @@ declare namespace ts { */ export interface FunctionLikeDeclarationBase extends SignatureDeclarationBase { _functionLikeDeclarationBrand: any; - asteriskToken?: AsteriskToken; - questionToken?: QuestionToken; - exclamationToken?: ExclamationToken; - body?: Block | Expression; + readonly asteriskToken?: AsteriskToken; + readonly questionToken?: QuestionToken; + readonly exclamationToken?: ExclamationToken; + readonly body?: Block | Expression; } export type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction; /** @deprecated Use SignatureDeclaration */ export type FunctionLike = SignatureDeclaration; export interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { - kind: SyntaxKind.FunctionDeclaration; - name?: Identifier; - body?: FunctionBody; + readonly kind: SyntaxKind.FunctionDeclaration; + readonly name?: Identifier; + readonly body?: FunctionBody; } export interface MethodSignature extends SignatureDeclarationBase, TypeElement { - kind: SyntaxKind.MethodSignature; - parent: ObjectTypeDeclaration; - name: PropertyName; + readonly kind: SyntaxKind.MethodSignature; + readonly parent: ObjectTypeDeclaration; + readonly name: PropertyName; } export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.MethodDeclaration; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.MethodDeclaration; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; } export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement, JSDocContainer { - kind: SyntaxKind.Constructor; - parent: ClassLikeDeclaration; - body?: FunctionBody; + readonly kind: SyntaxKind.Constructor; + readonly parent: ClassLikeDeclaration; + readonly body?: FunctionBody; } /** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */ export interface SemicolonClassElement extends ClassElement { - kind: SyntaxKind.SemicolonClassElement; - parent: ClassLikeDeclaration; + readonly kind: SyntaxKind.SemicolonClassElement; + readonly parent: ClassLikeDeclaration; } export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.GetAccessor; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.GetAccessor; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; } export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - kind: SyntaxKind.SetAccessor; - parent: ClassLikeDeclaration | ObjectLiteralExpression; - name: PropertyName; - body?: FunctionBody; + readonly kind: SyntaxKind.SetAccessor; + readonly parent: ClassLikeDeclaration | ObjectLiteralExpression; + readonly name: PropertyName; + readonly body?: FunctionBody; } export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration; export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { - kind: SyntaxKind.IndexSignature; - parent: ObjectTypeDeclaration; + readonly kind: SyntaxKind.IndexSignature; + readonly parent: ObjectTypeDeclaration; + readonly type: TypeNode; } export interface TypeNode extends Node { _typeNodeBrand: any; } - export interface KeywordTypeNode extends TypeNode { - kind: SyntaxKind.AnyKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.NumberKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword | SyntaxKind.NeverKeyword; + export interface KeywordTypeNode extends KeywordToken, TypeNode { + readonly kind: TKind; } export interface ImportTypeNode extends NodeWithTypeArguments { - kind: SyntaxKind.ImportType; - isTypeOf?: boolean; - argument: TypeNode; - qualifier?: EntityName; + readonly kind: SyntaxKind.ImportType; + readonly isTypeOf: boolean; + readonly argument: TypeNode; + readonly qualifier?: EntityName; } export interface ThisTypeNode extends TypeNode { - kind: SyntaxKind.ThisType; + readonly kind: SyntaxKind.ThisType; } export type FunctionOrConstructorTypeNode = FunctionTypeNode | ConstructorTypeNode; export interface FunctionOrConstructorTypeNodeBase extends TypeNode, SignatureDeclarationBase { - kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType; - type: TypeNode; + readonly kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType; + readonly type: TypeNode; } export interface FunctionTypeNode extends FunctionOrConstructorTypeNodeBase { - kind: SyntaxKind.FunctionType; + readonly kind: SyntaxKind.FunctionType; } export interface ConstructorTypeNode extends FunctionOrConstructorTypeNodeBase { - kind: SyntaxKind.ConstructorType; + readonly kind: SyntaxKind.ConstructorType; } export interface NodeWithTypeArguments extends TypeNode { - typeArguments?: NodeArray; + readonly typeArguments?: NodeArray; } export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments; export interface TypeReferenceNode extends NodeWithTypeArguments { - kind: SyntaxKind.TypeReference; - typeName: EntityName; + readonly kind: SyntaxKind.TypeReference; + readonly typeName: EntityName; } export interface TypePredicateNode extends TypeNode { - kind: SyntaxKind.TypePredicate; - parent: SignatureDeclaration | JSDocTypeExpression; - assertsModifier?: AssertsToken; - parameterName: Identifier | ThisTypeNode; - type?: TypeNode; + readonly kind: SyntaxKind.TypePredicate; + readonly parent: SignatureDeclaration | JSDocTypeExpression; + readonly assertsModifier?: AssertsToken; + readonly parameterName: Identifier | ThisTypeNode; + readonly type?: TypeNode; } export interface TypeQueryNode extends TypeNode { - kind: SyntaxKind.TypeQuery; - exprName: EntityName; + readonly kind: SyntaxKind.TypeQuery; + readonly exprName: EntityName; } export interface TypeLiteralNode extends TypeNode, Declaration { - kind: SyntaxKind.TypeLiteral; - members: NodeArray; + readonly kind: SyntaxKind.TypeLiteral; + readonly members: NodeArray; } export interface ArrayTypeNode extends TypeNode { - kind: SyntaxKind.ArrayType; - elementType: TypeNode; + readonly kind: SyntaxKind.ArrayType; + readonly elementType: TypeNode; } export interface TupleTypeNode extends TypeNode { - kind: SyntaxKind.TupleType; - elements: NodeArray; + readonly kind: SyntaxKind.TupleType; + readonly elements: NodeArray; } export interface NamedTupleMember extends TypeNode, JSDocContainer, Declaration { - kind: SyntaxKind.NamedTupleMember; - dotDotDotToken?: Token; - name: Identifier; - questionToken?: Token; - type: TypeNode; + readonly kind: SyntaxKind.NamedTupleMember; + readonly dotDotDotToken?: Token; + readonly name: Identifier; + readonly questionToken?: Token; + readonly type: TypeNode; } export interface OptionalTypeNode extends TypeNode { - kind: SyntaxKind.OptionalType; - type: TypeNode; + readonly kind: SyntaxKind.OptionalType; + readonly type: TypeNode; } export interface RestTypeNode extends TypeNode { - kind: SyntaxKind.RestType; - type: TypeNode; + readonly kind: SyntaxKind.RestType; + readonly type: TypeNode; } export type UnionOrIntersectionTypeNode = UnionTypeNode | IntersectionTypeNode; export interface UnionTypeNode extends TypeNode { - kind: SyntaxKind.UnionType; - types: NodeArray; + readonly kind: SyntaxKind.UnionType; + readonly types: NodeArray; } export interface IntersectionTypeNode extends TypeNode { - kind: SyntaxKind.IntersectionType; - types: NodeArray; + readonly kind: SyntaxKind.IntersectionType; + readonly types: NodeArray; } export interface ConditionalTypeNode extends TypeNode { - kind: SyntaxKind.ConditionalType; - checkType: TypeNode; - extendsType: TypeNode; - trueType: TypeNode; - falseType: TypeNode; + readonly kind: SyntaxKind.ConditionalType; + readonly checkType: TypeNode; + readonly extendsType: TypeNode; + readonly trueType: TypeNode; + readonly falseType: TypeNode; } export interface InferTypeNode extends TypeNode { - kind: SyntaxKind.InferType; - typeParameter: TypeParameterDeclaration; + readonly kind: SyntaxKind.InferType; + readonly typeParameter: TypeParameterDeclaration; } export interface ParenthesizedTypeNode extends TypeNode { - kind: SyntaxKind.ParenthesizedType; - type: TypeNode; + readonly kind: SyntaxKind.ParenthesizedType; + readonly type: TypeNode; } export interface TypeOperatorNode extends TypeNode { - kind: SyntaxKind.TypeOperator; - operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword; - type: TypeNode; + readonly kind: SyntaxKind.TypeOperator; + readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword; + readonly type: TypeNode; } export interface IndexedAccessTypeNode extends TypeNode { - kind: SyntaxKind.IndexedAccessType; - objectType: TypeNode; - indexType: TypeNode; + readonly kind: SyntaxKind.IndexedAccessType; + readonly objectType: TypeNode; + readonly indexType: TypeNode; } export interface MappedTypeNode extends TypeNode, Declaration { - kind: SyntaxKind.MappedType; - readonlyToken?: ReadonlyToken | PlusToken | MinusToken; - typeParameter: TypeParameterDeclaration; - questionToken?: QuestionToken | PlusToken | MinusToken; - type?: TypeNode; + readonly kind: SyntaxKind.MappedType; + readonly readonlyToken?: ReadonlyToken | PlusToken | MinusToken; + readonly typeParameter: TypeParameterDeclaration; + readonly questionToken?: QuestionToken | PlusToken | MinusToken; + readonly type?: TypeNode; } export interface LiteralTypeNode extends TypeNode { - kind: SyntaxKind.LiteralType; - literal: BooleanLiteral | LiteralExpression | PrefixUnaryExpression; + readonly kind: SyntaxKind.LiteralType; + readonly literal: NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression; } export interface StringLiteral extends LiteralExpression, Declaration { - kind: SyntaxKind.StringLiteral; + readonly kind: SyntaxKind.StringLiteral; } export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral; + export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral; export interface Expression extends Node { _expressionBrand: any; } export interface OmittedExpression extends Expression { - kind: SyntaxKind.OmittedExpression; + readonly kind: SyntaxKind.OmittedExpression; } export interface PartiallyEmittedExpression extends LeftHandSideExpression { - kind: SyntaxKind.PartiallyEmittedExpression; - expression: Expression; + readonly kind: SyntaxKind.PartiallyEmittedExpression; + readonly expression: Expression; } export interface UnaryExpression extends Expression { _unaryExpressionBrand: any; @@ -899,15 +944,15 @@ declare namespace ts { } export type PrefixUnaryOperator = SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken; export interface PrefixUnaryExpression extends UpdateExpression { - kind: SyntaxKind.PrefixUnaryExpression; - operator: PrefixUnaryOperator; - operand: UnaryExpression; + readonly kind: SyntaxKind.PrefixUnaryExpression; + readonly operator: PrefixUnaryOperator; + readonly operand: UnaryExpression; } export type PostfixUnaryOperator = SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken; export interface PostfixUnaryExpression extends UpdateExpression { - kind: SyntaxKind.PostfixUnaryExpression; - operand: LeftHandSideExpression; - operator: PostfixUnaryOperator; + readonly kind: SyntaxKind.PostfixUnaryExpression; + readonly operand: LeftHandSideExpression; + readonly operator: PostfixUnaryOperator; } export interface LeftHandSideExpression extends UpdateExpression { _leftHandSideExpressionBrand: any; @@ -918,47 +963,51 @@ declare namespace ts { export interface PrimaryExpression extends MemberExpression { _primaryExpressionBrand: any; } - export interface NullLiteral extends PrimaryExpression, TypeNode { - kind: SyntaxKind.NullKeyword; + export interface NullLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.NullKeyword; } - export interface BooleanLiteral extends PrimaryExpression, TypeNode { - kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword; + export interface TrueLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.TrueKeyword; } - export interface ThisExpression extends PrimaryExpression, KeywordTypeNode { - kind: SyntaxKind.ThisKeyword; + export interface FalseLiteral extends PrimaryExpression { + readonly kind: SyntaxKind.FalseKeyword; + } + export type BooleanLiteral = TrueLiteral | FalseLiteral; + export interface ThisExpression extends PrimaryExpression { + readonly kind: SyntaxKind.ThisKeyword; } export interface SuperExpression extends PrimaryExpression { - kind: SyntaxKind.SuperKeyword; + readonly kind: SyntaxKind.SuperKeyword; } export interface ImportExpression extends PrimaryExpression { - kind: SyntaxKind.ImportKeyword; + readonly kind: SyntaxKind.ImportKeyword; } export interface DeleteExpression extends UnaryExpression { - kind: SyntaxKind.DeleteExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.DeleteExpression; + readonly expression: UnaryExpression; } export interface TypeOfExpression extends UnaryExpression { - kind: SyntaxKind.TypeOfExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.TypeOfExpression; + readonly expression: UnaryExpression; } export interface VoidExpression extends UnaryExpression { - kind: SyntaxKind.VoidExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.VoidExpression; + readonly expression: UnaryExpression; } export interface AwaitExpression extends UnaryExpression { - kind: SyntaxKind.AwaitExpression; - expression: UnaryExpression; + readonly kind: SyntaxKind.AwaitExpression; + readonly expression: UnaryExpression; } export interface YieldExpression extends Expression { - kind: SyntaxKind.YieldExpression; - asteriskToken?: AsteriskToken; - expression?: Expression; + readonly kind: SyntaxKind.YieldExpression; + readonly asteriskToken?: AsteriskToken; + readonly expression?: Expression; } export interface SyntheticExpression extends Expression { - kind: SyntaxKind.SyntheticExpression; - isSpread: boolean; - type: Type; - tupleNameSource?: ParameterDeclaration | NamedTupleMember; + readonly kind: SyntaxKind.SyntheticExpression; + readonly isSpread: boolean; + readonly type: Type; + readonly tupleNameSource?: ParameterDeclaration | NamedTupleMember; } export type ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken; export type MultiplicativeOperator = SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken; @@ -982,24 +1031,26 @@ declare namespace ts { export type LogicalOrCoalescingAssignmentOperator = SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.QuestionQuestionEqualsToken; export type BinaryOperatorToken = Token; export interface BinaryExpression extends Expression, Declaration { - kind: SyntaxKind.BinaryExpression; - left: Expression; - operatorToken: BinaryOperatorToken; - right: Expression; + readonly kind: SyntaxKind.BinaryExpression; + readonly left: Expression; + readonly operatorToken: BinaryOperatorToken; + readonly right: Expression; } export type AssignmentOperatorToken = Token; export interface AssignmentExpression extends BinaryExpression { - left: LeftHandSideExpression; - operatorToken: TOperator; + readonly left: LeftHandSideExpression; + readonly operatorToken: TOperator; } export interface ObjectDestructuringAssignment extends AssignmentExpression { - left: ObjectLiteralExpression; + readonly left: ObjectLiteralExpression; } export interface ArrayDestructuringAssignment extends AssignmentExpression { - left: ArrayLiteralExpression; + readonly left: ArrayLiteralExpression; } export type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment; - export type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; + export type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | ObjectBindingOrAssignmentElement | ArrayBindingOrAssignmentElement; + export type ObjectBindingOrAssignmentElement = BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment; + export type ArrayBindingOrAssignmentElement = BindingElement | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; export type BindingOrAssignmentElementRestIndicator = DotDotDotToken | SpreadElement | SpreadAssignment; export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; export type ObjectBindingOrAssignmentPattern = ObjectBindingPattern | ObjectLiteralExpression; @@ -1007,25 +1058,25 @@ declare namespace ts { export type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression; export type BindingOrAssignmentPattern = ObjectBindingOrAssignmentPattern | ArrayBindingOrAssignmentPattern; export interface ConditionalExpression extends Expression { - kind: SyntaxKind.ConditionalExpression; - condition: Expression; - questionToken: QuestionToken; - whenTrue: Expression; - colonToken: ColonToken; - whenFalse: Expression; + readonly kind: SyntaxKind.ConditionalExpression; + readonly condition: Expression; + readonly questionToken: QuestionToken; + readonly whenTrue: Expression; + readonly colonToken: ColonToken; + readonly whenFalse: Expression; } export type FunctionBody = Block; export type ConciseBody = FunctionBody | Expression; export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { - kind: SyntaxKind.FunctionExpression; - name?: Identifier; - body: FunctionBody; + readonly kind: SyntaxKind.FunctionExpression; + readonly name?: Identifier; + readonly body: FunctionBody; } export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase, JSDocContainer { - kind: SyntaxKind.ArrowFunction; - equalsGreaterThanToken: EqualsGreaterThanToken; - body: ConciseBody; - name: never; + readonly kind: SyntaxKind.ArrowFunction; + readonly equalsGreaterThanToken: EqualsGreaterThanToken; + readonly body: ConciseBody; + readonly name: never; } export interface LiteralLikeNode extends Node { text: string; @@ -1039,10 +1090,10 @@ declare namespace ts { _literalExpressionBrand: any; } export interface RegularExpressionLiteral extends LiteralExpression { - kind: SyntaxKind.RegularExpressionLiteral; + readonly kind: SyntaxKind.RegularExpressionLiteral; } export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode, Declaration { - kind: SyntaxKind.NoSubstitutionTemplateLiteral; + readonly kind: SyntaxKind.NoSubstitutionTemplateLiteral; } export enum TokenFlags { None = 0, @@ -1053,47 +1104,50 @@ declare namespace ts { OctalSpecifier = 256, } export interface NumericLiteral extends LiteralExpression, Declaration { - kind: SyntaxKind.NumericLiteral; + readonly kind: SyntaxKind.NumericLiteral; } export interface BigIntLiteral extends LiteralExpression { - kind: SyntaxKind.BigIntLiteral; + readonly kind: SyntaxKind.BigIntLiteral; } + export type LiteralToken = NumericLiteral | BigIntLiteral | StringLiteral | JsxText | RegularExpressionLiteral | NoSubstitutionTemplateLiteral; export interface TemplateHead extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateHead; - parent: TemplateExpression; + readonly kind: SyntaxKind.TemplateHead; + readonly parent: TemplateExpression; } export interface TemplateMiddle extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateMiddle; - parent: TemplateSpan; + readonly kind: SyntaxKind.TemplateMiddle; + readonly parent: TemplateSpan; } export interface TemplateTail extends TemplateLiteralLikeNode { - kind: SyntaxKind.TemplateTail; - parent: TemplateSpan; + readonly kind: SyntaxKind.TemplateTail; + readonly parent: TemplateSpan; } - export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral; + export type PseudoLiteralToken = TemplateHead | TemplateMiddle | TemplateTail; + export type TemplateLiteralToken = NoSubstitutionTemplateLiteral | PseudoLiteralToken; export interface TemplateExpression extends PrimaryExpression { - kind: SyntaxKind.TemplateExpression; - head: TemplateHead; - templateSpans: NodeArray; + readonly kind: SyntaxKind.TemplateExpression; + readonly head: TemplateHead; + readonly templateSpans: NodeArray; } + export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral; export interface TemplateSpan extends Node { - kind: SyntaxKind.TemplateSpan; - parent: TemplateExpression; - expression: Expression; - literal: TemplateMiddle | TemplateTail; + readonly kind: SyntaxKind.TemplateSpan; + readonly parent: TemplateExpression; + readonly expression: Expression; + readonly literal: TemplateMiddle | TemplateTail; } export interface ParenthesizedExpression extends PrimaryExpression, JSDocContainer { - kind: SyntaxKind.ParenthesizedExpression; - expression: Expression; + readonly kind: SyntaxKind.ParenthesizedExpression; + readonly expression: Expression; } export interface ArrayLiteralExpression extends PrimaryExpression { - kind: SyntaxKind.ArrayLiteralExpression; - elements: NodeArray; + readonly kind: SyntaxKind.ArrayLiteralExpression; + readonly elements: NodeArray; } export interface SpreadElement extends Expression { - kind: SyntaxKind.SpreadElement; - parent: ArrayLiteralExpression | CallExpression | NewExpression; - expression: Expression; + readonly kind: SyntaxKind.SpreadElement; + readonly parent: ArrayLiteralExpression | CallExpression | NewExpression; + readonly expression: Expression; } /** * This interface is a base interface for ObjectLiteralExpression and JSXAttributes to extend from. JSXAttributes is similar to @@ -1102,388 +1156,389 @@ declare namespace ts { * ObjectLiteralElement (e.g. PropertyAssignment, ShorthandPropertyAssignment etc.) */ export interface ObjectLiteralExpressionBase extends PrimaryExpression, Declaration { - properties: NodeArray; + readonly properties: NodeArray; } export interface ObjectLiteralExpression extends ObjectLiteralExpressionBase { - kind: SyntaxKind.ObjectLiteralExpression; + readonly kind: SyntaxKind.ObjectLiteralExpression; } export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression; export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; + export type AccessExpression = PropertyAccessExpression | ElementAccessExpression; export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration { - kind: SyntaxKind.PropertyAccessExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - name: Identifier | PrivateIdentifier; + readonly kind: SyntaxKind.PropertyAccessExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly name: Identifier | PrivateIdentifier; } export interface PropertyAccessChain extends PropertyAccessExpression { _optionalChainBrand: any; - name: Identifier; + readonly name: Identifier | PrivateIdentifier; } export interface SuperPropertyAccessExpression extends PropertyAccessExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { _propertyAccessExpressionLikeQualifiedNameBrand?: any; - expression: EntityNameExpression; - name: Identifier; + readonly expression: EntityNameExpression; + readonly name: Identifier; } export interface ElementAccessExpression extends MemberExpression { - kind: SyntaxKind.ElementAccessExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - argumentExpression: Expression; + readonly kind: SyntaxKind.ElementAccessExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly argumentExpression: Expression; } export interface ElementAccessChain extends ElementAccessExpression { _optionalChainBrand: any; } export interface SuperElementAccessExpression extends ElementAccessExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } export type SuperProperty = SuperPropertyAccessExpression | SuperElementAccessExpression; export interface CallExpression extends LeftHandSideExpression, Declaration { - kind: SyntaxKind.CallExpression; - expression: LeftHandSideExpression; - questionDotToken?: QuestionDotToken; - typeArguments?: NodeArray; - arguments: NodeArray; + readonly kind: SyntaxKind.CallExpression; + readonly expression: LeftHandSideExpression; + readonly questionDotToken?: QuestionDotToken; + readonly typeArguments?: NodeArray; + readonly arguments: NodeArray; } export interface CallChain extends CallExpression { _optionalChainBrand: any; } export type OptionalChain = PropertyAccessChain | ElementAccessChain | CallChain | NonNullChain; export interface SuperCall extends CallExpression { - expression: SuperExpression; + readonly expression: SuperExpression; } export interface ImportCall extends CallExpression { - expression: ImportExpression; + readonly expression: ImportExpression; } export interface ExpressionWithTypeArguments extends NodeWithTypeArguments { - kind: SyntaxKind.ExpressionWithTypeArguments; - parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; - expression: LeftHandSideExpression; + readonly kind: SyntaxKind.ExpressionWithTypeArguments; + readonly parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; + readonly expression: LeftHandSideExpression; } export interface NewExpression extends PrimaryExpression, Declaration { - kind: SyntaxKind.NewExpression; - expression: LeftHandSideExpression; - typeArguments?: NodeArray; - arguments?: NodeArray; + readonly kind: SyntaxKind.NewExpression; + readonly expression: LeftHandSideExpression; + readonly typeArguments?: NodeArray; + readonly arguments?: NodeArray; } export interface TaggedTemplateExpression extends MemberExpression { - kind: SyntaxKind.TaggedTemplateExpression; - tag: LeftHandSideExpression; - typeArguments?: NodeArray; - template: TemplateLiteral; + readonly kind: SyntaxKind.TaggedTemplateExpression; + readonly tag: LeftHandSideExpression; + readonly typeArguments?: NodeArray; + readonly template: TemplateLiteral; } export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; export interface AsExpression extends Expression { - kind: SyntaxKind.AsExpression; - expression: Expression; - type: TypeNode; + readonly kind: SyntaxKind.AsExpression; + readonly expression: Expression; + readonly type: TypeNode; } export interface TypeAssertion extends UnaryExpression { - kind: SyntaxKind.TypeAssertionExpression; - type: TypeNode; - expression: UnaryExpression; + readonly kind: SyntaxKind.TypeAssertionExpression; + readonly type: TypeNode; + readonly expression: UnaryExpression; } export type AssertionExpression = TypeAssertion | AsExpression; export interface NonNullExpression extends LeftHandSideExpression { - kind: SyntaxKind.NonNullExpression; - expression: Expression; + readonly kind: SyntaxKind.NonNullExpression; + readonly expression: Expression; } export interface NonNullChain extends NonNullExpression { _optionalChainBrand: any; } export interface MetaProperty extends PrimaryExpression { - kind: SyntaxKind.MetaProperty; - keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; - name: Identifier; + readonly kind: SyntaxKind.MetaProperty; + readonly keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; + readonly name: Identifier; } export interface JsxElement extends PrimaryExpression { - kind: SyntaxKind.JsxElement; - openingElement: JsxOpeningElement; - children: NodeArray; - closingElement: JsxClosingElement; + readonly kind: SyntaxKind.JsxElement; + readonly openingElement: JsxOpeningElement; + readonly children: NodeArray; + readonly closingElement: JsxClosingElement; } export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; export type JsxTagNameExpression = Identifier | ThisExpression | JsxTagNamePropertyAccess; export interface JsxTagNamePropertyAccess extends PropertyAccessExpression { - expression: JsxTagNameExpression; + readonly expression: JsxTagNameExpression; } export interface JsxAttributes extends ObjectLiteralExpressionBase { - kind: SyntaxKind.JsxAttributes; - parent: JsxOpeningLikeElement; + readonly kind: SyntaxKind.JsxAttributes; + readonly parent: JsxOpeningLikeElement; } export interface JsxOpeningElement extends Expression { - kind: SyntaxKind.JsxOpeningElement; - parent: JsxElement; - tagName: JsxTagNameExpression; - typeArguments?: NodeArray; - attributes: JsxAttributes; + readonly kind: SyntaxKind.JsxOpeningElement; + readonly parent: JsxElement; + readonly tagName: JsxTagNameExpression; + readonly typeArguments?: NodeArray; + readonly attributes: JsxAttributes; } export interface JsxSelfClosingElement extends PrimaryExpression { - kind: SyntaxKind.JsxSelfClosingElement; - tagName: JsxTagNameExpression; - typeArguments?: NodeArray; - attributes: JsxAttributes; + readonly kind: SyntaxKind.JsxSelfClosingElement; + readonly tagName: JsxTagNameExpression; + readonly typeArguments?: NodeArray; + readonly attributes: JsxAttributes; } export interface JsxFragment extends PrimaryExpression { - kind: SyntaxKind.JsxFragment; - openingFragment: JsxOpeningFragment; - children: NodeArray; - closingFragment: JsxClosingFragment; + readonly kind: SyntaxKind.JsxFragment; + readonly openingFragment: JsxOpeningFragment; + readonly children: NodeArray; + readonly closingFragment: JsxClosingFragment; } export interface JsxOpeningFragment extends Expression { - kind: SyntaxKind.JsxOpeningFragment; - parent: JsxFragment; + readonly kind: SyntaxKind.JsxOpeningFragment; + readonly parent: JsxFragment; } export interface JsxClosingFragment extends Expression { - kind: SyntaxKind.JsxClosingFragment; - parent: JsxFragment; + readonly kind: SyntaxKind.JsxClosingFragment; + readonly parent: JsxFragment; } export interface JsxAttribute extends ObjectLiteralElement { - kind: SyntaxKind.JsxAttribute; - parent: JsxAttributes; - name: Identifier; - initializer?: StringLiteral | JsxExpression; + readonly kind: SyntaxKind.JsxAttribute; + readonly parent: JsxAttributes; + readonly name: Identifier; + readonly initializer?: StringLiteral | JsxExpression; } export interface JsxSpreadAttribute extends ObjectLiteralElement { - kind: SyntaxKind.JsxSpreadAttribute; - parent: JsxAttributes; - expression: Expression; + readonly kind: SyntaxKind.JsxSpreadAttribute; + readonly parent: JsxAttributes; + readonly expression: Expression; } export interface JsxClosingElement extends Node { - kind: SyntaxKind.JsxClosingElement; - parent: JsxElement; - tagName: JsxTagNameExpression; + readonly kind: SyntaxKind.JsxClosingElement; + readonly parent: JsxElement; + readonly tagName: JsxTagNameExpression; } export interface JsxExpression extends Expression { - kind: SyntaxKind.JsxExpression; - parent: JsxElement | JsxAttributeLike; - dotDotDotToken?: Token; - expression?: Expression; + readonly kind: SyntaxKind.JsxExpression; + readonly parent: JsxElement | JsxAttributeLike; + readonly dotDotDotToken?: Token; + readonly expression?: Expression; } export interface JsxText extends LiteralLikeNode { - kind: SyntaxKind.JsxText; - containsOnlyTriviaWhiteSpaces: boolean; - parent: JsxElement; + readonly kind: SyntaxKind.JsxText; + readonly parent: JsxElement; + readonly containsOnlyTriviaWhiteSpaces: boolean; } export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment; export interface Statement extends Node { _statementBrand: any; } export interface NotEmittedStatement extends Statement { - kind: SyntaxKind.NotEmittedStatement; + readonly kind: SyntaxKind.NotEmittedStatement; } /** * A list of comma-separated expressions. This node is only created by transformations. */ export interface CommaListExpression extends Expression { - kind: SyntaxKind.CommaListExpression; - elements: NodeArray; + readonly kind: SyntaxKind.CommaListExpression; + readonly elements: NodeArray; } export interface EmptyStatement extends Statement { - kind: SyntaxKind.EmptyStatement; + readonly kind: SyntaxKind.EmptyStatement; } export interface DebuggerStatement extends Statement { - kind: SyntaxKind.DebuggerStatement; + readonly kind: SyntaxKind.DebuggerStatement; } export interface MissingDeclaration extends DeclarationStatement { - kind: SyntaxKind.MissingDeclaration; - name?: Identifier; + readonly kind: SyntaxKind.MissingDeclaration; + readonly name?: Identifier; } export type BlockLike = SourceFile | Block | ModuleBlock | CaseOrDefaultClause; export interface Block extends Statement { - kind: SyntaxKind.Block; - statements: NodeArray; + readonly kind: SyntaxKind.Block; + readonly statements: NodeArray; } export interface VariableStatement extends Statement, JSDocContainer { - kind: SyntaxKind.VariableStatement; - declarationList: VariableDeclarationList; + readonly kind: SyntaxKind.VariableStatement; + readonly declarationList: VariableDeclarationList; } export interface ExpressionStatement extends Statement, JSDocContainer { - kind: SyntaxKind.ExpressionStatement; - expression: Expression; + readonly kind: SyntaxKind.ExpressionStatement; + readonly expression: Expression; } export interface IfStatement extends Statement { - kind: SyntaxKind.IfStatement; - expression: Expression; - thenStatement: Statement; - elseStatement?: Statement; + readonly kind: SyntaxKind.IfStatement; + readonly expression: Expression; + readonly thenStatement: Statement; + readonly elseStatement?: Statement; } export interface IterationStatement extends Statement { - statement: Statement; + readonly statement: Statement; } export interface DoStatement extends IterationStatement { - kind: SyntaxKind.DoStatement; - expression: Expression; + readonly kind: SyntaxKind.DoStatement; + readonly expression: Expression; } export interface WhileStatement extends IterationStatement { - kind: SyntaxKind.WhileStatement; - expression: Expression; + readonly kind: SyntaxKind.WhileStatement; + readonly expression: Expression; } export type ForInitializer = VariableDeclarationList | Expression; export interface ForStatement extends IterationStatement { - kind: SyntaxKind.ForStatement; - initializer?: ForInitializer; - condition?: Expression; - incrementor?: Expression; + readonly kind: SyntaxKind.ForStatement; + readonly initializer?: ForInitializer; + readonly condition?: Expression; + readonly incrementor?: Expression; } export type ForInOrOfStatement = ForInStatement | ForOfStatement; export interface ForInStatement extends IterationStatement { - kind: SyntaxKind.ForInStatement; - initializer: ForInitializer; - expression: Expression; + readonly kind: SyntaxKind.ForInStatement; + readonly initializer: ForInitializer; + readonly expression: Expression; } export interface ForOfStatement extends IterationStatement { - kind: SyntaxKind.ForOfStatement; - awaitModifier?: AwaitKeywordToken; - initializer: ForInitializer; - expression: Expression; + readonly kind: SyntaxKind.ForOfStatement; + readonly awaitModifier?: AwaitKeywordToken; + readonly initializer: ForInitializer; + readonly expression: Expression; } export interface BreakStatement extends Statement { - kind: SyntaxKind.BreakStatement; - label?: Identifier; + readonly kind: SyntaxKind.BreakStatement; + readonly label?: Identifier; } export interface ContinueStatement extends Statement { - kind: SyntaxKind.ContinueStatement; - label?: Identifier; + readonly kind: SyntaxKind.ContinueStatement; + readonly label?: Identifier; } export type BreakOrContinueStatement = BreakStatement | ContinueStatement; export interface ReturnStatement extends Statement { - kind: SyntaxKind.ReturnStatement; - expression?: Expression; + readonly kind: SyntaxKind.ReturnStatement; + readonly expression?: Expression; } export interface WithStatement extends Statement { - kind: SyntaxKind.WithStatement; - expression: Expression; - statement: Statement; + readonly kind: SyntaxKind.WithStatement; + readonly expression: Expression; + readonly statement: Statement; } export interface SwitchStatement extends Statement { - kind: SyntaxKind.SwitchStatement; - expression: Expression; - caseBlock: CaseBlock; + readonly kind: SyntaxKind.SwitchStatement; + readonly expression: Expression; + readonly caseBlock: CaseBlock; possiblyExhaustive?: boolean; } export interface CaseBlock extends Node { - kind: SyntaxKind.CaseBlock; - parent: SwitchStatement; - clauses: NodeArray; + readonly kind: SyntaxKind.CaseBlock; + readonly parent: SwitchStatement; + readonly clauses: NodeArray; } export interface CaseClause extends Node { - kind: SyntaxKind.CaseClause; - parent: CaseBlock; - expression: Expression; - statements: NodeArray; + readonly kind: SyntaxKind.CaseClause; + readonly parent: CaseBlock; + readonly expression: Expression; + readonly statements: NodeArray; } export interface DefaultClause extends Node { - kind: SyntaxKind.DefaultClause; - parent: CaseBlock; - statements: NodeArray; + readonly kind: SyntaxKind.DefaultClause; + readonly parent: CaseBlock; + readonly statements: NodeArray; } export type CaseOrDefaultClause = CaseClause | DefaultClause; export interface LabeledStatement extends Statement, JSDocContainer { - kind: SyntaxKind.LabeledStatement; - label: Identifier; - statement: Statement; + readonly kind: SyntaxKind.LabeledStatement; + readonly label: Identifier; + readonly statement: Statement; } export interface ThrowStatement extends Statement { - kind: SyntaxKind.ThrowStatement; - expression?: Expression; + readonly kind: SyntaxKind.ThrowStatement; + readonly expression?: Expression; } export interface TryStatement extends Statement { - kind: SyntaxKind.TryStatement; - tryBlock: Block; - catchClause?: CatchClause; - finallyBlock?: Block; + readonly kind: SyntaxKind.TryStatement; + readonly tryBlock: Block; + readonly catchClause?: CatchClause; + readonly finallyBlock?: Block; } export interface CatchClause extends Node { - kind: SyntaxKind.CatchClause; - parent: TryStatement; - variableDeclaration?: VariableDeclaration; - block: Block; + readonly kind: SyntaxKind.CatchClause; + readonly parent: TryStatement; + readonly variableDeclaration?: VariableDeclaration; + readonly block: Block; } export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode; export type DeclarationWithTypeParameters = DeclarationWithTypeParameterChildren | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; export type DeclarationWithTypeParameterChildren = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; - name?: Identifier; - typeParameters?: NodeArray; - heritageClauses?: NodeArray; - members: NodeArray; + readonly kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; + readonly name?: Identifier; + readonly typeParameters?: NodeArray; + readonly heritageClauses?: NodeArray; + readonly members: NodeArray; } export interface ClassDeclaration extends ClassLikeDeclarationBase, DeclarationStatement { - kind: SyntaxKind.ClassDeclaration; + readonly kind: SyntaxKind.ClassDeclaration; /** May be undefined in `export default class { ... }`. */ - name?: Identifier; + readonly name?: Identifier; } export interface ClassExpression extends ClassLikeDeclarationBase, PrimaryExpression { - kind: SyntaxKind.ClassExpression; + readonly kind: SyntaxKind.ClassExpression; } export type ClassLikeDeclaration = ClassDeclaration | ClassExpression; export interface ClassElement extends NamedDeclaration { _classElementBrand: any; - name?: PropertyName; + readonly name?: PropertyName; } export interface TypeElement extends NamedDeclaration { _typeElementBrand: any; - name?: PropertyName; - questionToken?: QuestionToken; + readonly name?: PropertyName; + readonly questionToken?: QuestionToken; } export interface InterfaceDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.InterfaceDeclaration; - name: Identifier; - typeParameters?: NodeArray; - heritageClauses?: NodeArray; - members: NodeArray; + readonly kind: SyntaxKind.InterfaceDeclaration; + readonly name: Identifier; + readonly typeParameters?: NodeArray; + readonly heritageClauses?: NodeArray; + readonly members: NodeArray; } export interface HeritageClause extends Node { - kind: SyntaxKind.HeritageClause; - parent: InterfaceDeclaration | ClassLikeDeclaration; - token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword; - types: NodeArray; + readonly kind: SyntaxKind.HeritageClause; + readonly parent: InterfaceDeclaration | ClassLikeDeclaration; + readonly token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword; + readonly types: NodeArray; } export interface TypeAliasDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.TypeAliasDeclaration; - name: Identifier; - typeParameters?: NodeArray; - type: TypeNode; + readonly kind: SyntaxKind.TypeAliasDeclaration; + readonly name: Identifier; + readonly typeParameters?: NodeArray; + readonly type: TypeNode; } export interface EnumMember extends NamedDeclaration, JSDocContainer { - kind: SyntaxKind.EnumMember; - parent: EnumDeclaration; - name: PropertyName; - initializer?: Expression; + readonly kind: SyntaxKind.EnumMember; + readonly parent: EnumDeclaration; + readonly name: PropertyName; + readonly initializer?: Expression; } export interface EnumDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.EnumDeclaration; - name: Identifier; - members: NodeArray; + readonly kind: SyntaxKind.EnumDeclaration; + readonly name: Identifier; + readonly members: NodeArray; } export type ModuleName = Identifier | StringLiteral; export type ModuleBody = NamespaceBody | JSDocNamespaceBody; export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ModuleDeclaration; - parent: ModuleBody | SourceFile; - name: ModuleName; - body?: ModuleBody | JSDocNamespaceDeclaration; + readonly kind: SyntaxKind.ModuleDeclaration; + readonly parent: ModuleBody | SourceFile; + readonly name: ModuleName; + readonly body?: ModuleBody | JSDocNamespaceDeclaration; } export type NamespaceBody = ModuleBlock | NamespaceDeclaration; export interface NamespaceDeclaration extends ModuleDeclaration { - name: Identifier; - body: NamespaceBody; + readonly name: Identifier; + readonly body: NamespaceBody; } export type JSDocNamespaceBody = Identifier | JSDocNamespaceDeclaration; export interface JSDocNamespaceDeclaration extends ModuleDeclaration { - name: Identifier; - body?: JSDocNamespaceBody; + readonly name: Identifier; + readonly body?: JSDocNamespaceBody; } export interface ModuleBlock extends Node, Statement { - kind: SyntaxKind.ModuleBlock; - parent: ModuleDeclaration; - statements: NodeArray; + readonly kind: SyntaxKind.ModuleBlock; + readonly parent: ModuleDeclaration; + readonly statements: NodeArray; } export type ModuleReference = EntityName | ExternalModuleReference; /** @@ -1492,77 +1547,77 @@ declare namespace ts { * - import x = M.x; */ export interface ImportEqualsDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ImportEqualsDeclaration; - parent: SourceFile | ModuleBlock; - name: Identifier; - moduleReference: ModuleReference; + readonly kind: SyntaxKind.ImportEqualsDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly name: Identifier; + readonly moduleReference: ModuleReference; } export interface ExternalModuleReference extends Node { - kind: SyntaxKind.ExternalModuleReference; - parent: ImportEqualsDeclaration; - expression: Expression; - } - export interface ImportDeclaration extends Statement { - kind: SyntaxKind.ImportDeclaration; - parent: SourceFile | ModuleBlock; - importClause?: ImportClause; + readonly kind: SyntaxKind.ExternalModuleReference; + readonly parent: ImportEqualsDeclaration; + readonly expression: Expression; + } + export interface ImportDeclaration extends Statement, JSDocContainer { + readonly kind: SyntaxKind.ImportDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly importClause?: ImportClause; /** If this is not a StringLiteral it will be a grammar error. */ - moduleSpecifier: Expression; + readonly moduleSpecifier: Expression; } export type NamedImportBindings = NamespaceImport | NamedImports; export type NamedExportBindings = NamespaceExport | NamedExports; export interface ImportClause extends NamedDeclaration { - kind: SyntaxKind.ImportClause; - parent: ImportDeclaration; - isTypeOnly: boolean; - name?: Identifier; - namedBindings?: NamedImportBindings; + readonly kind: SyntaxKind.ImportClause; + readonly parent: ImportDeclaration; + readonly isTypeOnly: boolean; + readonly name?: Identifier; + readonly namedBindings?: NamedImportBindings; } export interface NamespaceImport extends NamedDeclaration { - kind: SyntaxKind.NamespaceImport; - parent: ImportClause; - name: Identifier; + readonly kind: SyntaxKind.NamespaceImport; + readonly parent: ImportClause; + readonly name: Identifier; } export interface NamespaceExport extends NamedDeclaration { - kind: SyntaxKind.NamespaceExport; - parent: ExportDeclaration; - name: Identifier; + readonly kind: SyntaxKind.NamespaceExport; + readonly parent: ExportDeclaration; + readonly name: Identifier; } - export interface NamespaceExportDeclaration extends DeclarationStatement { - kind: SyntaxKind.NamespaceExportDeclaration; - name: Identifier; + export interface NamespaceExportDeclaration extends DeclarationStatement, JSDocContainer { + readonly kind: SyntaxKind.NamespaceExportDeclaration; + readonly name: Identifier; } export interface ExportDeclaration extends DeclarationStatement, JSDocContainer { - kind: SyntaxKind.ExportDeclaration; - parent: SourceFile | ModuleBlock; - isTypeOnly: boolean; + readonly kind: SyntaxKind.ExportDeclaration; + readonly parent: SourceFile | ModuleBlock; + readonly isTypeOnly: boolean; /** Will not be assigned in the case of `export * from "foo";` */ - exportClause?: NamedExportBindings; + readonly exportClause?: NamedExportBindings; /** If this is not a StringLiteral it will be a grammar error. */ - moduleSpecifier?: Expression; + readonly moduleSpecifier?: Expression; } export interface NamedImports extends Node { - kind: SyntaxKind.NamedImports; - parent: ImportClause; - elements: NodeArray; + readonly kind: SyntaxKind.NamedImports; + readonly parent: ImportClause; + readonly elements: NodeArray; } export interface NamedExports extends Node { - kind: SyntaxKind.NamedExports; - parent: ExportDeclaration; - elements: NodeArray; + readonly kind: SyntaxKind.NamedExports; + readonly parent: ExportDeclaration; + readonly elements: NodeArray; } export type NamedImportsOrExports = NamedImports | NamedExports; export interface ImportSpecifier extends NamedDeclaration { - kind: SyntaxKind.ImportSpecifier; - parent: NamedImports; - propertyName?: Identifier; - name: Identifier; + readonly kind: SyntaxKind.ImportSpecifier; + readonly parent: NamedImports; + readonly propertyName?: Identifier; + readonly name: Identifier; } export interface ExportSpecifier extends NamedDeclaration { - kind: SyntaxKind.ExportSpecifier; - parent: NamedExports; - propertyName?: Identifier; - name: Identifier; + readonly kind: SyntaxKind.ExportSpecifier; + readonly parent: NamedExports; + readonly propertyName?: Identifier; + readonly name: Identifier; } export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier; export type TypeOnlyCompatibleAliasDeclaration = ImportClause | NamespaceImport | ImportOrExportSpecifier; @@ -1570,11 +1625,11 @@ declare namespace ts { * This is either an `export =` or an `export default` declaration. * Unless `isExportEquals` is set, this node was parsed as an `export default`. */ - export interface ExportAssignment extends DeclarationStatement { - kind: SyntaxKind.ExportAssignment; - parent: SourceFile; - isExportEquals?: boolean; - expression: Expression; + export interface ExportAssignment extends DeclarationStatement, JSDocContainer { + readonly kind: SyntaxKind.ExportAssignment; + readonly parent: SourceFile; + readonly isExportEquals?: boolean; + readonly expression: Expression; } export interface FileReference extends TextRange { fileName: string; @@ -1594,151 +1649,151 @@ declare namespace ts { hasLeadingNewline?: boolean; } export interface JSDocTypeExpression extends TypeNode { - kind: SyntaxKind.JSDocTypeExpression; - type: TypeNode; + readonly kind: SyntaxKind.JSDocTypeExpression; + readonly type: TypeNode; } export interface JSDocType extends TypeNode { _jsDocTypeBrand: any; } export interface JSDocAllType extends JSDocType { - kind: SyntaxKind.JSDocAllType; + readonly kind: SyntaxKind.JSDocAllType; } export interface JSDocUnknownType extends JSDocType { - kind: SyntaxKind.JSDocUnknownType; + readonly kind: SyntaxKind.JSDocUnknownType; } export interface JSDocNonNullableType extends JSDocType { - kind: SyntaxKind.JSDocNonNullableType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNonNullableType; + readonly type: TypeNode; } export interface JSDocNullableType extends JSDocType { - kind: SyntaxKind.JSDocNullableType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNullableType; + readonly type: TypeNode; } export interface JSDocOptionalType extends JSDocType { - kind: SyntaxKind.JSDocOptionalType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocOptionalType; + readonly type: TypeNode; } export interface JSDocFunctionType extends JSDocType, SignatureDeclarationBase { - kind: SyntaxKind.JSDocFunctionType; + readonly kind: SyntaxKind.JSDocFunctionType; } export interface JSDocVariadicType extends JSDocType { - kind: SyntaxKind.JSDocVariadicType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocVariadicType; + readonly type: TypeNode; } export interface JSDocNamepathType extends JSDocType { - kind: SyntaxKind.JSDocNamepathType; - type: TypeNode; + readonly kind: SyntaxKind.JSDocNamepathType; + readonly type: TypeNode; } export type JSDocTypeReferencingNode = JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType; export interface JSDoc extends Node { - kind: SyntaxKind.JSDocComment; - parent: HasJSDoc; - tags?: NodeArray; - comment?: string; + readonly kind: SyntaxKind.JSDocComment; + readonly parent: HasJSDoc; + readonly tags?: NodeArray; + readonly comment?: string; } export interface JSDocTag extends Node { - parent: JSDoc | JSDocTypeLiteral; - tagName: Identifier; - comment?: string; + readonly parent: JSDoc | JSDocTypeLiteral; + readonly tagName: Identifier; + readonly comment?: string; } export interface JSDocUnknownTag extends JSDocTag { - kind: SyntaxKind.JSDocTag; + readonly kind: SyntaxKind.JSDocTag; } /** * Note that `@extends` is a synonym of `@augments`. * Both tags are represented by this interface. */ export interface JSDocAugmentsTag extends JSDocTag { - kind: SyntaxKind.JSDocAugmentsTag; - class: ExpressionWithTypeArguments & { - expression: Identifier | PropertyAccessEntityNameExpression; + readonly kind: SyntaxKind.JSDocAugmentsTag; + readonly class: ExpressionWithTypeArguments & { + readonly expression: Identifier | PropertyAccessEntityNameExpression; }; } export interface JSDocImplementsTag extends JSDocTag { - kind: SyntaxKind.JSDocImplementsTag; - class: ExpressionWithTypeArguments & { - expression: Identifier | PropertyAccessEntityNameExpression; + readonly kind: SyntaxKind.JSDocImplementsTag; + readonly class: ExpressionWithTypeArguments & { + readonly expression: Identifier | PropertyAccessEntityNameExpression; }; } export interface JSDocAuthorTag extends JSDocTag { - kind: SyntaxKind.JSDocAuthorTag; + readonly kind: SyntaxKind.JSDocAuthorTag; } export interface JSDocClassTag extends JSDocTag { - kind: SyntaxKind.JSDocClassTag; + readonly kind: SyntaxKind.JSDocClassTag; } export interface JSDocPublicTag extends JSDocTag { - kind: SyntaxKind.JSDocPublicTag; + readonly kind: SyntaxKind.JSDocPublicTag; } export interface JSDocPrivateTag extends JSDocTag { - kind: SyntaxKind.JSDocPrivateTag; + readonly kind: SyntaxKind.JSDocPrivateTag; } export interface JSDocProtectedTag extends JSDocTag { - kind: SyntaxKind.JSDocProtectedTag; + readonly kind: SyntaxKind.JSDocProtectedTag; } export interface JSDocReadonlyTag extends JSDocTag { - kind: SyntaxKind.JSDocReadonlyTag; + readonly kind: SyntaxKind.JSDocReadonlyTag; } export interface JSDocEnumTag extends JSDocTag, Declaration { - parent: JSDoc; - kind: SyntaxKind.JSDocEnumTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocEnumTag; + readonly parent: JSDoc; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocThisTag extends JSDocTag { - kind: SyntaxKind.JSDocThisTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocThisTag; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocTemplateTag extends JSDocTag { - kind: SyntaxKind.JSDocTemplateTag; - constraint: JSDocTypeExpression | undefined; - typeParameters: NodeArray; + readonly kind: SyntaxKind.JSDocTemplateTag; + readonly constraint: JSDocTypeExpression | undefined; + readonly typeParameters: NodeArray; } export interface JSDocReturnTag extends JSDocTag { - kind: SyntaxKind.JSDocReturnTag; - typeExpression?: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocReturnTag; + readonly typeExpression?: JSDocTypeExpression; } export interface JSDocTypeTag extends JSDocTag { - kind: SyntaxKind.JSDocTypeTag; - typeExpression: JSDocTypeExpression; + readonly kind: SyntaxKind.JSDocTypeTag; + readonly typeExpression: JSDocTypeExpression; } export interface JSDocTypedefTag extends JSDocTag, NamedDeclaration { - parent: JSDoc; - kind: SyntaxKind.JSDocTypedefTag; - fullName?: JSDocNamespaceDeclaration | Identifier; - name?: Identifier; - typeExpression?: JSDocTypeExpression | JSDocTypeLiteral; + readonly kind: SyntaxKind.JSDocTypedefTag; + readonly parent: JSDoc; + readonly fullName?: JSDocNamespaceDeclaration | Identifier; + readonly name?: Identifier; + readonly typeExpression?: JSDocTypeExpression | JSDocTypeLiteral; } export interface JSDocCallbackTag extends JSDocTag, NamedDeclaration { - parent: JSDoc; - kind: SyntaxKind.JSDocCallbackTag; - fullName?: JSDocNamespaceDeclaration | Identifier; - name?: Identifier; - typeExpression: JSDocSignature; + readonly kind: SyntaxKind.JSDocCallbackTag; + readonly parent: JSDoc; + readonly fullName?: JSDocNamespaceDeclaration | Identifier; + readonly name?: Identifier; + readonly typeExpression: JSDocSignature; } export interface JSDocSignature extends JSDocType, Declaration { - kind: SyntaxKind.JSDocSignature; - typeParameters?: readonly JSDocTemplateTag[]; - parameters: readonly JSDocParameterTag[]; - type: JSDocReturnTag | undefined; + readonly kind: SyntaxKind.JSDocSignature; + readonly typeParameters?: readonly JSDocTemplateTag[]; + readonly parameters: readonly JSDocParameterTag[]; + readonly type: JSDocReturnTag | undefined; } export interface JSDocPropertyLikeTag extends JSDocTag, Declaration { - parent: JSDoc; - name: EntityName; - typeExpression?: JSDocTypeExpression; + readonly parent: JSDoc; + readonly name: EntityName; + readonly typeExpression?: JSDocTypeExpression; /** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */ - isNameFirst: boolean; - isBracketed: boolean; + readonly isNameFirst: boolean; + readonly isBracketed: boolean; } export interface JSDocPropertyTag extends JSDocPropertyLikeTag { - kind: SyntaxKind.JSDocPropertyTag; + readonly kind: SyntaxKind.JSDocPropertyTag; } export interface JSDocParameterTag extends JSDocPropertyLikeTag { - kind: SyntaxKind.JSDocParameterTag; + readonly kind: SyntaxKind.JSDocParameterTag; } export interface JSDocTypeLiteral extends JSDocType { - kind: SyntaxKind.JSDocTypeLiteral; - jsDocPropertyTags?: readonly JSDocPropertyLikeTag[]; + readonly kind: SyntaxKind.JSDocTypeLiteral; + readonly jsDocPropertyTags?: readonly JSDocPropertyLikeTag[]; /** If true, then this type literal represents an *array* of its type. */ - isArrayType?: boolean; + readonly isArrayType: boolean; } export enum FlowFlags { Unreachable = 1, @@ -1805,9 +1860,9 @@ declare namespace ts { name?: string; } export interface SourceFile extends Declaration { - kind: SyntaxKind.SourceFile; - statements: NodeArray; - endOfFileToken: Token; + readonly kind: SyntaxKind.SourceFile; + readonly statements: NodeArray; + readonly endOfFileToken: Token; fileName: string; text: string; amdDependencies: readonly AmdDependency[]; @@ -1829,12 +1884,12 @@ declare namespace ts { languageVersion: ScriptTarget; } export interface Bundle extends Node { - kind: SyntaxKind.Bundle; - prepends: readonly (InputFiles | UnparsedSource)[]; - sourceFiles: readonly SourceFile[]; + readonly kind: SyntaxKind.Bundle; + readonly prepends: readonly (InputFiles | UnparsedSource)[]; + readonly sourceFiles: readonly SourceFile[]; } export interface InputFiles extends Node { - kind: SyntaxKind.InputFiles; + readonly kind: SyntaxKind.InputFiles; javascriptPath?: string; javascriptText: string; javascriptMapPath?: string; @@ -1845,10 +1900,10 @@ declare namespace ts { declarationMapText?: string; } export interface UnparsedSource extends Node { - kind: SyntaxKind.UnparsedSource; + readonly kind: SyntaxKind.UnparsedSource; fileName: string; text: string; - prologues: readonly UnparsedPrologue[]; + readonly prologues: readonly UnparsedPrologue[]; helpers: readonly UnscopedEmitHelper[] | undefined; referencedFiles: readonly FileReference[]; typeReferenceDirectives: readonly string[] | undefined; @@ -1856,48 +1911,49 @@ declare namespace ts { hasNoDefaultLib?: boolean; sourceMapPath?: string; sourceMapText?: string; - syntheticReferences?: readonly UnparsedSyntheticReference[]; - texts: readonly UnparsedSourceText[]; + readonly syntheticReferences?: readonly UnparsedSyntheticReference[]; + readonly texts: readonly UnparsedSourceText[]; } export type UnparsedSourceText = UnparsedPrepend | UnparsedTextLike; export type UnparsedNode = UnparsedPrologue | UnparsedSourceText | UnparsedSyntheticReference; export interface UnparsedSection extends Node { - kind: SyntaxKind; - data?: string; - parent: UnparsedSource; + readonly kind: SyntaxKind; + readonly parent: UnparsedSource; + readonly data?: string; } export interface UnparsedPrologue extends UnparsedSection { - kind: SyntaxKind.UnparsedPrologue; - data: string; - parent: UnparsedSource; + readonly kind: SyntaxKind.UnparsedPrologue; + readonly parent: UnparsedSource; + readonly data: string; } export interface UnparsedPrepend extends UnparsedSection { - kind: SyntaxKind.UnparsedPrepend; - data: string; - parent: UnparsedSource; - texts: readonly UnparsedTextLike[]; + readonly kind: SyntaxKind.UnparsedPrepend; + readonly parent: UnparsedSource; + readonly data: string; + readonly texts: readonly UnparsedTextLike[]; } export interface UnparsedTextLike extends UnparsedSection { - kind: SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText; - parent: UnparsedSource; + readonly kind: SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText; + readonly parent: UnparsedSource; } export interface UnparsedSyntheticReference extends UnparsedSection { - kind: SyntaxKind.UnparsedSyntheticReference; - parent: UnparsedSource; + readonly kind: SyntaxKind.UnparsedSyntheticReference; + readonly parent: UnparsedSource; } export interface JsonSourceFile extends SourceFile { - statements: NodeArray; + readonly statements: NodeArray; } export interface TsConfigSourceFile extends JsonSourceFile { extendedSourceFiles?: string[]; } export interface JsonMinusNumericLiteral extends PrefixUnaryExpression { - kind: SyntaxKind.PrefixUnaryExpression; - operator: SyntaxKind.MinusToken; - operand: NumericLiteral; + readonly kind: SyntaxKind.PrefixUnaryExpression; + readonly operator: SyntaxKind.MinusToken; + readonly operand: NumericLiteral; } + export type JsonObjectExpression = ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | BooleanLiteral | NullLiteral; export interface JsonObjectExpressionStatement extends ExpressionStatement { - expression: ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | BooleanLiteral | NullLiteral; + readonly expression: JsonObjectExpression; } export interface ScriptReferenceHost { getCompilerOptions(): CompilerOptions; @@ -3011,7 +3067,435 @@ declare namespace ts { EmbeddedStatement = 5, JsxAttributeValue = 6 } - export interface TransformationContext { + export enum OuterExpressionKinds { + Parentheses = 1, + TypeAssertions = 2, + NonNullAssertions = 4, + PartiallyEmittedExpressions = 8, + Assertions = 6, + All = 15 + } + export type TypeOfTag = "undefined" | "number" | "bigint" | "boolean" | "string" | "symbol" | "object" | "function"; + export interface NodeFactory { + createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray; + createNumericLiteral(value: string | number, numericLiteralFlags?: TokenFlags): NumericLiteral; + createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral; + createStringLiteral(text: string, isSingleQuote?: boolean): StringLiteral; + createStringLiteralFromNode(sourceNode: PropertyNameLiteral, isSingleQuote?: boolean): StringLiteral; + createRegularExpressionLiteral(text: string): RegularExpressionLiteral; + createIdentifier(text: string): Identifier; + /** Create a unique temporary variable. */ + createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; + /** Create a unique temporary variable for use in a loop. */ + createLoopVariable(): Identifier; + /** Create a unique name based on the supplied text. */ + createUniqueName(text: string, flags?: GeneratedIdentifierFlags): Identifier; + /** Create a unique name generated for a node. */ + getGeneratedNameForNode(node: Node | undefined): Identifier; + createPrivateIdentifier(text: string): PrivateIdentifier; + createToken(token: SyntaxKind.SuperKeyword): SuperExpression; + createToken(token: SyntaxKind.ThisKeyword): ThisExpression; + createToken(token: SyntaxKind.NullKeyword): NullLiteral; + createToken(token: SyntaxKind.TrueKeyword): TrueLiteral; + createToken(token: SyntaxKind.FalseKeyword): FalseLiteral; + createToken(token: TKind): PunctuationToken; + createToken(token: TKind): KeywordTypeNode; + createToken(token: TKind): ModifierToken; + createToken(token: TKind): KeywordToken; + createToken(token: TKind): Token; + createSuper(): SuperExpression; + createThis(): ThisExpression; + createNull(): NullLiteral; + createTrue(): TrueLiteral; + createFalse(): FalseLiteral; + createModifier(kind: T): ModifierToken; + createModifiersFromModifierFlags(flags: ModifierFlags): Modifier[]; + createQualifiedName(left: EntityName, right: string | Identifier): QualifiedName; + updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName; + createComputedPropertyName(expression: Expression): ComputedPropertyName; + updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName; + createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; + updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined): TypeParameterDeclaration; + createParameterDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): ParameterDeclaration; + updateParameterDeclaration(node: ParameterDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): ParameterDeclaration; + createDecorator(expression: Expression): Decorator; + updateDecorator(node: Decorator, expression: Expression): Decorator; + createPropertySignature(modifiers: readonly Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined): PropertySignature; + updatePropertySignature(node: PropertySignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined): PropertySignature; + createPropertyDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + updatePropertyDeclaration(node: PropertyDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; + createMethodSignature(modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): MethodSignature; + updateMethodSignature(node: MethodSignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): MethodSignature; + createMethodDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; + updateMethodDeclaration(node: MethodDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; + createConstructorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; + updateConstructorDeclaration(node: ConstructorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; + createGetAccessorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; + updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; + createSetAccessorDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; + updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; + createCallSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration; + updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration; + createConstructSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration; + updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration; + createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; + updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; + createKeywordTypeNode(kind: TKind): KeywordTypeNode; + createTypePredicateNode(assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; + createTypeReferenceNode(typeName: string | EntityName, typeArguments?: readonly TypeNode[]): TypeReferenceNode; + updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; + createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; + updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; + createTypeQueryNode(exprName: EntityName): TypeQueryNode; + updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; + createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; + updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode; + createArrayTypeNode(elementType: TypeNode): ArrayTypeNode; + updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode; + createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; + updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; + createNamedTupleMember(dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode): NamedTupleMember; + updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken | undefined, name: Identifier, questionToken: QuestionToken | undefined, type: TypeNode): NamedTupleMember; + createOptionalTypeNode(type: TypeNode): OptionalTypeNode; + updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode; + createRestTypeNode(type: TypeNode): RestTypeNode; + updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode; + createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode; + updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode; + createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode; + updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode; + createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; + updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; + createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; + updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; + createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; + updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean): ImportTypeNode; + createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; + updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; + createThisTypeNode(): ThisTypeNode; + createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; + updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; + createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; + updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; + createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; + updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; + createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern; + updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]): ObjectBindingPattern; + createArrayBindingPattern(elements: readonly ArrayBindingElement[]): ArrayBindingPattern; + updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]): ArrayBindingPattern; + createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression): BindingElement; + updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined): BindingElement; + createArrayLiteralExpression(elements?: readonly Expression[], multiLine?: boolean): ArrayLiteralExpression; + updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; + createObjectLiteralExpression(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; + updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; + createPropertyAccessExpression(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression; + updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression; + createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier): PropertyAccessChain; + updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier): PropertyAccessChain; + createElementAccessExpression(expression: Expression, index: number | Expression): ElementAccessExpression; + updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression; + createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain; + updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression): ElementAccessChain; + createCallExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallExpression; + updateCallExpression(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallExpression; + createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallChain; + updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallChain; + createNewExpression(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; + updateNewExpression(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; + createTaggedTemplateExpression(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; + updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; + createParenthesizedExpression(expression: Expression): ParenthesizedExpression; + updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression; + createFunctionExpression(modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[] | undefined, type: TypeNode | undefined, body: Block): FunctionExpression; + updateFunctionExpression(node: FunctionExpression, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block): FunctionExpression; + createArrowFunction(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; + updateArrowFunction(node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody): ArrowFunction; + createDeleteExpression(expression: Expression): DeleteExpression; + updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression; + createTypeOfExpression(expression: Expression): TypeOfExpression; + updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression; + createVoidExpression(expression: Expression): VoidExpression; + updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression; + createAwaitExpression(expression: Expression): AwaitExpression; + updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression; + createPrefixUnaryExpression(operator: PrefixUnaryOperator, operand: Expression): PrefixUnaryExpression; + updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression; + createPostfixUnaryExpression(operand: Expression, operator: PostfixUnaryOperator): PostfixUnaryExpression; + updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression; + createBinaryExpression(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; + updateBinaryExpression(node: BinaryExpression, left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; + createConditionalExpression(condition: Expression, questionToken: QuestionToken | undefined, whenTrue: Expression, colonToken: ColonToken | undefined, whenFalse: Expression): ConditionalExpression; + updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; + createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; + updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; + createTemplateHead(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateHead; + createTemplateHead(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateHead; + createTemplateMiddle(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateMiddle; + createTemplateMiddle(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateMiddle; + createTemplateTail(text: string, rawText?: string, templateFlags?: TokenFlags): TemplateTail; + createTemplateTail(text: string | undefined, rawText: string, templateFlags?: TokenFlags): TemplateTail; + createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; + createNoSubstitutionTemplateLiteral(text: string | undefined, rawText: string): NoSubstitutionTemplateLiteral; + createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression; + createYieldExpression(asteriskToken: undefined, expression: Expression | undefined): YieldExpression; + updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression | undefined): YieldExpression; + createSpreadElement(expression: Expression): SpreadElement; + updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement; + createClassExpression(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; + updateClassExpression(node: ClassExpression, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; + createOmittedExpression(): OmittedExpression; + createExpressionWithTypeArguments(expression: Expression, typeArguments: readonly TypeNode[] | undefined): ExpressionWithTypeArguments; + updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: readonly TypeNode[] | undefined): ExpressionWithTypeArguments; + createAsExpression(expression: Expression, type: TypeNode): AsExpression; + updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression; + createNonNullExpression(expression: Expression): NonNullExpression; + updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression; + createNonNullChain(expression: Expression): NonNullChain; + updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain; + createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier): MetaProperty; + updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty; + createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; + updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; + createSemicolonClassElement(): SemicolonClassElement; + createBlock(statements: readonly Statement[], multiLine?: boolean): Block; + updateBlock(node: Block, statements: readonly Statement[]): Block; + createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]): VariableStatement; + updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList): VariableStatement; + createEmptyStatement(): EmptyStatement; + createExpressionStatement(expression: Expression): ExpressionStatement; + updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement; + createIfStatement(expression: Expression, thenStatement: Statement, elseStatement?: Statement): IfStatement; + updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined): IfStatement; + createDoStatement(statement: Statement, expression: Expression): DoStatement; + updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement; + createWhileStatement(expression: Expression, statement: Statement): WhileStatement; + updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement; + createForStatement(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; + updateForStatement(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; + createForInStatement(initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; + updateForInStatement(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; + createForOfStatement(awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; + updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; + createContinueStatement(label?: string | Identifier): ContinueStatement; + updateContinueStatement(node: ContinueStatement, label: Identifier | undefined): ContinueStatement; + createBreakStatement(label?: string | Identifier): BreakStatement; + updateBreakStatement(node: BreakStatement, label: Identifier | undefined): BreakStatement; + createReturnStatement(expression?: Expression): ReturnStatement; + updateReturnStatement(node: ReturnStatement, expression: Expression | undefined): ReturnStatement; + createWithStatement(expression: Expression, statement: Statement): WithStatement; + updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement; + createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement; + updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement; + createLabeledStatement(label: string | Identifier, statement: Statement): LabeledStatement; + updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement; + createThrowStatement(expression: Expression): ThrowStatement; + updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement; + createTryStatement(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; + updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; + createDebuggerStatement(): DebuggerStatement; + createVariableDeclaration(name: string | BindingName, exclamationToken?: ExclamationToken, type?: TypeNode, initializer?: Expression): VariableDeclaration; + updateVariableDeclaration(node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList; + updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]): VariableDeclarationList; + createFunctionDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; + updateFunctionDeclaration(node: FunctionDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; + createClassDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; + updateClassDeclaration(node: ClassDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; + createInterfaceDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; + updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; + createTypeAliasDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; + updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; + createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]): EnumDeclaration; + updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]): EnumDeclaration; + createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags): ModuleDeclaration; + updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined): ModuleDeclaration; + createModuleBlock(statements: readonly Statement[]): ModuleBlock; + updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]): ModuleBlock; + createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock; + updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]): CaseBlock; + createNamespaceExportDeclaration(name: string | Identifier): NamespaceExportDeclaration; + updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration; + createImportEqualsDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; + updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; + createImportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; + updateImportDeclaration(node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; + createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createNamespaceImport(name: Identifier): NamespaceImport; + updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport; + createNamespaceExport(name: Identifier): NamespaceExport; + updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport; + createNamedImports(elements: readonly ImportSpecifier[]): NamedImports; + updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]): NamedImports; + createImportSpecifier(propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; + updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; + createExportAssignment(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression): ExportAssignment; + updateExportAssignment(node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression): ExportAssignment; + createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression): ExportDeclaration; + updateExportDeclaration(node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined): ExportDeclaration; + createNamedExports(elements: readonly ExportSpecifier[]): NamedExports; + updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]): NamedExports; + createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier): ExportSpecifier; + updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; + createExternalModuleReference(expression: Expression): ExternalModuleReference; + updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; + createJSDocAllType(): JSDocAllType; + createJSDocUnknownType(): JSDocUnknownType; + createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType; + updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType; + createJSDocNullableType(type: TypeNode): JSDocNullableType; + updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType; + createJSDocOptionalType(type: TypeNode): JSDocOptionalType; + updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType; + createJSDocFunctionType(parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType; + updateJSDocFunctionType(node: JSDocFunctionType, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): JSDocFunctionType; + createJSDocVariadicType(type: TypeNode): JSDocVariadicType; + updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType; + createJSDocNamepathType(type: TypeNode): JSDocNamepathType; + updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType; + createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression; + updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression; + createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral; + updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: readonly JSDocPropertyLikeTag[] | undefined, isArrayType: boolean | undefined): JSDocTypeLiteral; + createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature; + updateJSDocSignature(node: JSDocSignature, typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type: JSDocReturnTag | undefined): JSDocSignature; + createJSDocTemplateTag(tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string): JSDocTemplateTag; + updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | undefined): JSDocTemplateTag; + createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocTypedefTag; + updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocTypedefTag; + createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; + updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; + createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; + updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; + createJSDocTypeTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; + updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocTypeTag; + createJSDocReturnTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag; + updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment: string | undefined): JSDocReturnTag; + createJSDocThisTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocThisTag; + updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment: string | undefined): JSDocThisTag; + createJSDocEnumTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression, comment?: string): JSDocEnumTag; + updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocEnumTag; + createJSDocCallbackTag(tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocCallbackTag; + updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocCallbackTag; + createJSDocAugmentsTag(tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment?: string): JSDocAugmentsTag; + updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier | undefined, className: JSDocAugmentsTag["class"], comment: string | undefined): JSDocAugmentsTag; + createJSDocImplementsTag(tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag; + updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier | undefined, className: JSDocImplementsTag["class"], comment: string | undefined): JSDocImplementsTag; + createJSDocAuthorTag(tagName: Identifier | undefined, comment?: string): JSDocAuthorTag; + updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier | undefined, comment: string | undefined): JSDocAuthorTag; + createJSDocClassTag(tagName: Identifier | undefined, comment?: string): JSDocClassTag; + updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier | undefined, comment: string | undefined): JSDocClassTag; + createJSDocPublicTag(tagName: Identifier | undefined, comment?: string): JSDocPublicTag; + updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier | undefined, comment: string | undefined): JSDocPublicTag; + createJSDocPrivateTag(tagName: Identifier | undefined, comment?: string): JSDocPrivateTag; + updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier | undefined, comment: string | undefined): JSDocPrivateTag; + createJSDocProtectedTag(tagName: Identifier | undefined, comment?: string): JSDocProtectedTag; + updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier | undefined, comment: string | undefined): JSDocProtectedTag; + createJSDocReadonlyTag(tagName: Identifier | undefined, comment?: string): JSDocReadonlyTag; + updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | undefined): JSDocReadonlyTag; + createJSDocUnknownTag(tagName: Identifier, comment?: string): JSDocUnknownTag; + updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | undefined): JSDocUnknownTag; + createJSDocComment(comment?: string | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc; + updateJSDocComment(node: JSDoc, comment: string | undefined, tags: readonly JSDocTag[] | undefined): JSDoc; + createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; + updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; + createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; + updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; + createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement; + updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement; + createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; + createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; + updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; + createJsxOpeningFragment(): JsxOpeningFragment; + createJsxJsxClosingFragment(): JsxClosingFragment; + updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; + createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression | undefined): JsxAttribute; + updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression | undefined): JsxAttribute; + createJsxAttributes(properties: readonly JsxAttributeLike[]): JsxAttributes; + updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]): JsxAttributes; + createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute; + updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute; + createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined): JsxExpression; + updateJsxExpression(node: JsxExpression, expression: Expression | undefined): JsxExpression; + createCaseClause(expression: Expression, statements: readonly Statement[]): CaseClause; + updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]): CaseClause; + createDefaultClause(statements: readonly Statement[]): DefaultClause; + updateDefaultClause(node: DefaultClause, statements: readonly Statement[]): DefaultClause; + createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]): HeritageClause; + updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]): HeritageClause; + createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause; + updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause; + createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment; + updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment; + createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment; + updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined): ShorthandPropertyAssignment; + createSpreadAssignment(expression: Expression): SpreadAssignment; + updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; + createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; + updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; + createSourceFile(statements: readonly Statement[], endOfFileToken: EndOfFileToken, flags: NodeFlags): SourceFile; + updateSourceFile(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: readonly FileReference[], typeReferences?: readonly FileReference[], hasNoDefaultLib?: boolean, libReferences?: readonly FileReference[]): SourceFile; + createNotEmittedStatement(original: Node): NotEmittedStatement; + createPartiallyEmittedExpression(expression: Expression, original?: Node): PartiallyEmittedExpression; + updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression; + createCommaListExpression(elements: readonly Expression[]): CommaListExpression; + updateCommaListExpression(node: CommaListExpression, elements: readonly Expression[]): CommaListExpression; + createBundle(sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; + updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; + createComma(left: Expression, right: Expression): BinaryExpression; + createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; + createAssignment(left: Expression, right: Expression): AssignmentExpression; + createLogicalOr(left: Expression, right: Expression): BinaryExpression; + createLogicalAnd(left: Expression, right: Expression): BinaryExpression; + createBitwiseOr(left: Expression, right: Expression): BinaryExpression; + createBitwiseXor(left: Expression, right: Expression): BinaryExpression; + createBitwiseAnd(left: Expression, right: Expression): BinaryExpression; + createStrictEquality(left: Expression, right: Expression): BinaryExpression; + createStrictInequality(left: Expression, right: Expression): BinaryExpression; + createEquality(left: Expression, right: Expression): BinaryExpression; + createInequality(left: Expression, right: Expression): BinaryExpression; + createLessThan(left: Expression, right: Expression): BinaryExpression; + createLessThanEquals(left: Expression, right: Expression): BinaryExpression; + createGreaterThan(left: Expression, right: Expression): BinaryExpression; + createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression; + createLeftShift(left: Expression, right: Expression): BinaryExpression; + createRightShift(left: Expression, right: Expression): BinaryExpression; + createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression; + createAdd(left: Expression, right: Expression): BinaryExpression; + createSubtract(left: Expression, right: Expression): BinaryExpression; + createMultiply(left: Expression, right: Expression): BinaryExpression; + createDivide(left: Expression, right: Expression): BinaryExpression; + createModulo(left: Expression, right: Expression): BinaryExpression; + createExponent(left: Expression, right: Expression): BinaryExpression; + createPrefixPlus(operand: Expression): PrefixUnaryExpression; + createPrefixMinus(operand: Expression): PrefixUnaryExpression; + createPrefixIncrement(operand: Expression): PrefixUnaryExpression; + createPrefixDecrement(operand: Expression): PrefixUnaryExpression; + createBitwiseNot(operand: Expression): PrefixUnaryExpression; + createLogicalNot(operand: Expression): PrefixUnaryExpression; + createPostfixIncrement(operand: Expression): PostfixUnaryExpression; + createPostfixDecrement(operand: Expression): PostfixUnaryExpression; + createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; + createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; + createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + createVoidZero(): VoidExpression; + createExportDefault(expression: Expression): ExportAssignment; + createExternalModuleExport(exportName: Identifier): ExportDeclaration; + restoreOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds?: OuterExpressionKinds): Expression; + } + export interface CoreTransformationContext { + readonly factory: NodeFactory; /** Gets the compiler options supplied to the transformer. */ getCompilerOptions(): CompilerOptions; /** Starts a new lexical environment. */ @@ -3026,6 +3510,8 @@ declare namespace ts { hoistFunctionDeclaration(node: FunctionDeclaration): void; /** Hoists a variable declaration to the containing scope. */ hoistVariableDeclaration(node: Identifier): void; + } + export interface TransformationContext extends CoreTransformationContext { /** Records a request for a non-scoped emit helper in the current context. */ requestEmitHelper(helper: EmitHelper): void; /** Gets and resets the requested non-scoped emit helpers. */ @@ -3105,6 +3591,14 @@ declare namespace ts { * A function that accepts and possibly transforms a node. */ export type Visitor = (node: Node) => VisitResult; + export interface NodeVisitor { + (nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; + (nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T | undefined; + } + export interface NodesVisitor { + (nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; + (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + } export type VisitResult = T | T[] | undefined; export interface Printer { /** @@ -3201,6 +3695,7 @@ declare namespace ts { newLength: number; } export interface SyntaxList extends Node { + kind: SyntaxKind.SyntaxList; _children: Node[]; } export enum ListFormat { @@ -3476,7 +3971,7 @@ declare namespace ts { * @param node The original node. * @returns The original parse tree node if found; otherwise, undefined. */ - function getParseTreeNode(node: Node): Node; + function getParseTreeNode(node: Node | undefined): Node | undefined; /** * Gets the original parse tree node for a node. * @@ -3484,7 +3979,7 @@ declare namespace ts { * @param nodeTest A callback used to ensure the correct type of parse tree node is returned. * @returns The original parse tree node if found; otherwise, undefined. */ - function getParseTreeNode(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined; + function getParseTreeNode(node: T | undefined, nodeTest?: (node: Node) => node is T): T | undefined; /** Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' */ function escapeLeadingUnderscores(identifier: string): __String; /** @@ -3584,6 +4079,154 @@ declare namespace ts { */ function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): readonly TypeParameterDeclaration[]; function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined; + function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier; + function isPropertyAccessChain(node: Node): node is PropertyAccessChain; + function isElementAccessChain(node: Node): node is ElementAccessChain; + function isCallChain(node: Node): node is CallChain; + function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain | NonNullChain; + function isNullishCoalesce(node: Node): boolean; + function isConstTypeReference(node: Node): boolean; + function skipPartiallyEmittedExpressions(node: Expression): Expression; + function skipPartiallyEmittedExpressions(node: Node): Node; + function isNonNullChain(node: Node): node is NonNullChain; + function isBreakOrContinueStatement(node: Node): node is BreakOrContinueStatement; + function isNamedExportBindings(node: Node): node is NamedExportBindings; + function isUnparsedTextLike(node: Node): node is UnparsedTextLike; + function isUnparsedNode(node: Node): node is UnparsedNode; + function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag; + /** + * True if node is of some token syntax kind. + * For example, this is true for an IfKeyword but not for an IfStatement. + * Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail. + */ + function isToken(n: Node): boolean; + function isLiteralExpression(node: Node): node is LiteralExpression; + function isTemplateLiteralToken(node: Node): node is TemplateLiteralToken; + function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail; + function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | ExportSpecifier; + function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyCompatibleAliasDeclaration; + function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken; + function isModifier(node: Node): node is Modifier; + function isEntityName(node: Node): node is EntityName; + function isPropertyName(node: Node): node is PropertyName; + function isBindingName(node: Node): node is BindingName; + function isFunctionLike(node: Node): node is SignatureDeclaration; + function isClassElement(node: Node): node is ClassElement; + function isClassLike(node: Node): node is ClassLikeDeclaration; + function isAccessor(node: Node): node is AccessorDeclaration; + function isTypeElement(node: Node): node is TypeElement; + function isClassOrTypeElement(node: Node): node is ClassElement | TypeElement; + function isObjectLiteralElementLike(node: Node): node is ObjectLiteralElementLike; + /** + * Node test that determines whether a node is a valid type node. + * This differs from the `isPartOfTypeNode` function which determines whether a node is *part* + * of a TypeNode. + */ + function isTypeNode(node: Node): node is TypeNode; + function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; + function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; + function isCallLikeExpression(node: Node): node is CallLikeExpression; + function isCallOrNewExpression(node: Node): node is CallExpression | NewExpression; + function isTemplateLiteral(node: Node): node is TemplateLiteral; + function isAssertionExpression(node: Node): node is AssertionExpression; + function isIterationStatement(node: Node, lookInLabeledStatements: false): node is IterationStatement; + function isIterationStatement(node: Node, lookInLabeledStatements: boolean): node is IterationStatement | LabeledStatement; + function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement; + function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause; + /** True if node is of a kind that may contain comment text. */ + function isJSDocCommentContainingNode(node: Node): boolean; + function isSetAccessor(node: Node): node is SetAccessorDeclaration; + function isGetAccessor(node: Node): node is GetAccessorDeclaration; + /** True if has initializer node attached to it. */ + function hasOnlyExpressionInitializer(node: Node): node is HasExpressionInitializer; + function isObjectLiteralElement(node: Node): node is ObjectLiteralElement; + function isStringLiteralLike(node: Node): node is StringLiteralLike; +} +declare namespace ts { + const factory: NodeFactory; + function createUnparsedSourceFile(text: string): UnparsedSource; + function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; + function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; + function createInputFiles(javascriptText: string, declarationText: string): InputFiles; + function createInputFiles(readFileText: (path: string) => string | undefined, javascriptPath: string, javascriptMapPath: string | undefined, declarationPath: string, declarationMapPath: string | undefined, buildInfoPath: string | undefined): InputFiles; + function createInputFiles(javascriptText: string, declarationText: string, javascriptMapPath: string | undefined, javascriptMapText: string | undefined, declarationMapPath: string | undefined, declarationMapText: string | undefined): InputFiles; + /** + * Create an external source map source file reference + */ + function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource; + function setOriginalNode(node: T, original: Node | undefined): T; +} +declare namespace ts { + /** + * Clears any `EmitNode` entries from parse-tree nodes. + * @param sourceFile A source file. + */ + function disposeEmitNodes(sourceFile: SourceFile | undefined): void; + /** + * Sets flags that control emit behavior of a node. + */ + function setEmitFlags(node: T, emitFlags: EmitFlags): T; + /** + * Gets a custom text range to use when emitting source maps. + */ + function getSourceMapRange(node: Node): SourceMapRange; + /** + * Sets a custom text range to use when emitting source maps. + */ + function setSourceMapRange(node: T, range: SourceMapRange | undefined): T; + /** + * Gets the TextRange to use for source maps for a token of a node. + */ + function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined; + /** + * Sets the TextRange to use for source maps for a token of a node. + */ + function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined): T; + /** + * Gets a custom text range to use when emitting comments. + */ + function getCommentRange(node: Node): TextRange; + /** + * Sets a custom text range to use when emitting comments. + */ + function setCommentRange(node: T, range: TextRange): T; + function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined; + function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined): T; + function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T; + function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined; + function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined): T; + function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T; + function moveSyntheticComments(node: T, original: Node): T; + /** + * Gets the constant value to emit for an expression representing an enum. + */ + function getConstantValue(node: AccessExpression): string | number | undefined; + /** + * Sets the constant value to emit for an expression. + */ + function setConstantValue(node: AccessExpression, value: string | number): AccessExpression; + /** + * Adds an EmitHelper to a node. + */ + function addEmitHelper(node: T, helper: EmitHelper): T; + /** + * Add EmitHelpers to a node. + */ + function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T; + /** + * Removes an EmitHelper from a node. + */ + function removeEmitHelper(node: Node, helper: EmitHelper): boolean; + /** + * Gets the EmitHelpers of a node. + */ + function getEmitHelpers(node: Node): EmitHelper[] | undefined; + /** + * Moves matching emit helpers from a source node to a target node. + */ + function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean): void; +} +declare namespace ts { function isNumericLiteral(node: Node): node is NumericLiteral; function isBigIntLiteral(node: Node): node is BigIntLiteral; function isStringLiteral(node: Node): node is StringLiteral; @@ -3597,7 +4240,6 @@ declare namespace ts { function isQualifiedName(node: Node): node is QualifiedName; function isComputedPropertyName(node: Node): node is ComputedPropertyName; function isPrivateIdentifier(node: Node): node is PrivateIdentifier; - function isIdentifierOrPrivateIdentifier(node: Node): node is Identifier | PrivateIdentifier; function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration; function isParameter(node: Node): node is ParameterDeclaration; function isDecorator(node: Node): node is Decorator; @@ -3619,6 +4261,8 @@ declare namespace ts { function isTypeLiteralNode(node: Node): node is TypeLiteralNode; function isArrayTypeNode(node: Node): node is ArrayTypeNode; function isTupleTypeNode(node: Node): node is TupleTypeNode; + function isOptionalTypeNode(node: Node): node is OptionalTypeNode; + function isRestTypeNode(node: Node): node is RestTypeNode; function isUnionTypeNode(node: Node): node is UnionTypeNode; function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode; function isConditionalTypeNode(node: Node): node is ConditionalTypeNode; @@ -3636,20 +4280,12 @@ declare namespace ts { function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression; function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression; function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression; - function isPropertyAccessChain(node: Node): node is PropertyAccessChain; function isElementAccessExpression(node: Node): node is ElementAccessExpression; - function isElementAccessChain(node: Node): node is ElementAccessChain; function isCallExpression(node: Node): node is CallExpression; - function isCallChain(node: Node): node is CallChain; - function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain | NonNullChain; - function isNullishCoalesce(node: Node): boolean; function isNewExpression(node: Node): node is NewExpression; function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression; - function isTypeAssertion(node: Node): node is TypeAssertion; - function isConstTypeReference(node: Node): boolean; + function isTypeAssertionExpression(node: Node): node is TypeAssertion; function isParenthesizedExpression(node: Node): node is ParenthesizedExpression; - function skipPartiallyEmittedExpressions(node: Expression): Expression; - function skipPartiallyEmittedExpressions(node: Node): Node; function isFunctionExpression(node: Node): node is FunctionExpression; function isArrowFunction(node: Node): node is ArrowFunction; function isDeleteExpression(node: Node): node is DeleteExpression; @@ -3668,8 +4304,10 @@ declare namespace ts { function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments; function isAsExpression(node: Node): node is AsExpression; function isNonNullExpression(node: Node): node is NonNullExpression; - function isNonNullChain(node: Node): node is NonNullChain; function isMetaProperty(node: Node): node is MetaProperty; + function isSyntheticExpression(node: Node): node is SyntheticExpression; + function isPartiallyEmittedExpression(node: Node): node is PartiallyEmittedExpression; + function isCommaListExpression(node: Node): node is CommaListExpression; function isTemplateSpan(node: Node): node is TemplateSpan; function isSemicolonClassElement(node: Node): node is SemicolonClassElement; function isBlock(node: Node): node is Block; @@ -3684,7 +4322,6 @@ declare namespace ts { function isForOfStatement(node: Node): node is ForOfStatement; function isContinueStatement(node: Node): node is ContinueStatement; function isBreakStatement(node: Node): node is BreakStatement; - function isBreakOrContinueStatement(node: Node): node is BreakOrContinueStatement; function isReturnStatement(node: Node): node is ReturnStatement; function isWithStatement(node: Node): node is WithStatement; function isSwitchStatement(node: Node): node is SwitchStatement; @@ -3708,7 +4345,6 @@ declare namespace ts { function isImportClause(node: Node): node is ImportClause; function isNamespaceImport(node: Node): node is NamespaceImport; function isNamespaceExport(node: Node): node is NamespaceExport; - function isNamedExportBindings(node: Node): node is NamedExportBindings; function isNamedImports(node: Node): node is NamedImports; function isImportSpecifier(node: Node): node is ImportSpecifier; function isExportAssignment(node: Node): node is ExportAssignment; @@ -3716,6 +4352,7 @@ declare namespace ts { function isNamedExports(node: Node): node is NamedExports; function isExportSpecifier(node: Node): node is ExportSpecifier; function isMissingDeclaration(node: Node): node is MissingDeclaration; + function isNotEmittedStatement(node: Node): node is NotEmittedStatement; function isExternalModuleReference(node: Node): node is ExternalModuleReference; function isJsxElement(node: Node): node is JsxElement; function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement; @@ -3736,12 +4373,10 @@ declare namespace ts { function isShorthandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment; function isSpreadAssignment(node: Node): node is SpreadAssignment; function isEnumMember(node: Node): node is EnumMember; + function isUnparsedPrepend(node: Node): node is UnparsedPrepend; function isSourceFile(node: Node): node is SourceFile; function isBundle(node: Node): node is Bundle; function isUnparsedSource(node: Node): node is UnparsedSource; - function isUnparsedPrepend(node: Node): node is UnparsedPrepend; - function isUnparsedTextLike(node: Node): node is UnparsedTextLike; - function isUnparsedNode(node: Node): node is UnparsedNode; function isJSDocTypeExpression(node: Node): node is JSDocTypeExpression; function isJSDocAllType(node: Node): node is JSDocAllType; function isJSDocUnknownType(node: Node): node is JSDocUnknownType; @@ -3750,78 +4385,33 @@ declare namespace ts { function isJSDocOptionalType(node: Node): node is JSDocOptionalType; function isJSDocFunctionType(node: Node): node is JSDocFunctionType; function isJSDocVariadicType(node: Node): node is JSDocVariadicType; + function isJSDocNamepathType(node: Node): node is JSDocNamepathType; function isJSDoc(node: Node): node is JSDoc; - function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag; + function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral; + function isJSDocSignature(node: Node): node is JSDocSignature; function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag; - function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag; + function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag; function isJSDocClassTag(node: Node): node is JSDocClassTag; + function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag; function isJSDocPublicTag(node: Node): node is JSDocPublicTag; function isJSDocPrivateTag(node: Node): node is JSDocPrivateTag; function isJSDocProtectedTag(node: Node): node is JSDocProtectedTag; function isJSDocReadonlyTag(node: Node): node is JSDocReadonlyTag; function isJSDocEnumTag(node: Node): node is JSDocEnumTag; - function isJSDocThisTag(node: Node): node is JSDocThisTag; function isJSDocParameterTag(node: Node): node is JSDocParameterTag; function isJSDocReturnTag(node: Node): node is JSDocReturnTag; + function isJSDocThisTag(node: Node): node is JSDocThisTag; function isJSDocTypeTag(node: Node): node is JSDocTypeTag; function isJSDocTemplateTag(node: Node): node is JSDocTemplateTag; function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag; + function isJSDocUnknownTag(node: Node): node is JSDocUnknownTag; function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag; - function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag; - function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral; - function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag; - function isJSDocSignature(node: Node): node is JSDocSignature; - /** - * True if node is of some token syntax kind. - * For example, this is true for an IfKeyword but not for an IfStatement. - * Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail. - */ - function isToken(n: Node): boolean; - function isLiteralExpression(node: Node): node is LiteralExpression; - type TemplateLiteralToken = NoSubstitutionTemplateLiteral | TemplateHead | TemplateMiddle | TemplateTail; - function isTemplateLiteralToken(node: Node): node is TemplateLiteralToken; - function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail; - function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | ExportSpecifier; - function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyCompatibleAliasDeclaration; - function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken; - function isModifier(node: Node): node is Modifier; - function isEntityName(node: Node): node is EntityName; - function isPropertyName(node: Node): node is PropertyName; - function isBindingName(node: Node): node is BindingName; - function isFunctionLike(node: Node): node is SignatureDeclaration; - function isClassElement(node: Node): node is ClassElement; - function isClassLike(node: Node): node is ClassLikeDeclaration; - function isAccessor(node: Node): node is AccessorDeclaration; - function isTypeElement(node: Node): node is TypeElement; - function isClassOrTypeElement(node: Node): node is ClassElement | TypeElement; - function isObjectLiteralElementLike(node: Node): node is ObjectLiteralElementLike; - /** - * Node test that determines whether a node is a valid type node. - * This differs from the `isPartOfTypeNode` function which determines whether a node is *part* - * of a TypeNode. - */ - function isTypeNode(node: Node): node is TypeNode; - function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; - function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; - function isCallLikeExpression(node: Node): node is CallLikeExpression; - function isCallOrNewExpression(node: Node): node is CallExpression | NewExpression; - function isTemplateLiteral(node: Node): node is TemplateLiteral; - function isAssertionExpression(node: Node): node is AssertionExpression; - function isIterationStatement(node: Node, lookInLabeledStatements: false): node is IterationStatement; - function isIterationStatement(node: Node, lookInLabeledStatements: boolean): node is IterationStatement | LabeledStatement; - function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement; - function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause; - /** True if node is of a kind that may contain comment text. */ - function isJSDocCommentContainingNode(node: Node): boolean; - function isSetAccessor(node: Node): node is SetAccessorDeclaration; - function isGetAccessor(node: Node): node is GetAccessorDeclaration; - /** True if has initializer node attached to it. */ - function hasOnlyExpressionInitializer(node: Node): node is HasExpressionInitializer; - function isObjectLiteralElement(node: Node): node is ObjectLiteralElement; - function isStringLiteralLike(node: Node): node is StringLiteralLike; + function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag; +} +declare namespace ts { + function setTextRange(range: T, location: TextRange | undefined): T; } declare namespace ts { - export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node; /** * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, @@ -3977,476 +4567,6 @@ declare namespace ts { function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; } -declare namespace ts { - function createNodeArray(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray; - /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; - function createLiteral(value: number | PseudoBigInt): NumericLiteral; - function createLiteral(value: boolean): BooleanLiteral; - function createLiteral(value: string | number | PseudoBigInt | boolean): PrimaryExpression; - function createNumericLiteral(value: string, numericLiteralFlags?: TokenFlags): NumericLiteral; - function createBigIntLiteral(value: string): BigIntLiteral; - function createStringLiteral(text: string): StringLiteral; - function createRegularExpressionLiteral(text: string): RegularExpressionLiteral; - function createIdentifier(text: string): Identifier; - function updateIdentifier(node: Identifier): Identifier; - /** Create a unique temporary variable. */ - function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; - /** Create a unique temporary variable for use in a loop. */ - function createLoopVariable(): Identifier; - /** Create a unique name based on the supplied text. */ - function createUniqueName(text: string): Identifier; - /** Create a unique name based on the supplied text. */ - function createOptimisticUniqueName(text: string): Identifier; - /** Create a unique name based on the supplied text. This does not consider names injected by the transformer. */ - function createFileLevelUniqueName(text: string): Identifier; - /** Create a unique name generated for a node. */ - function getGeneratedNameForNode(node: Node | undefined): Identifier; - function createPrivateIdentifier(text: string): PrivateIdentifier; - function createToken(token: TKind): Token; - function createSuper(): SuperExpression; - function createThis(): ThisExpression & Token; - function createNull(): NullLiteral & Token; - function createTrue(): BooleanLiteral & Token; - function createFalse(): BooleanLiteral & Token; - function createModifier(kind: T): Token; - function createModifiersFromModifierFlags(flags: ModifierFlags): Modifier[]; - function createQualifiedName(left: EntityName, right: string | Identifier): QualifiedName; - function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName; - function createComputedPropertyName(expression: Expression): ComputedPropertyName; - function updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName; - function createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; - function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined): TypeParameterDeclaration; - function createParameter(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): ParameterDeclaration; - function updateParameter(node: ParameterDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): ParameterDeclaration; - function createDecorator(expression: Expression): Decorator; - function updateDecorator(node: Decorator, expression: Expression): Decorator; - function createPropertySignature(modifiers: readonly Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature; - function updatePropertySignature(node: PropertySignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature; - function createProperty(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; - function updateProperty(node: PropertyDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertyDeclaration; - function createMethodSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): MethodSignature; - function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined): MethodSignature; - function createMethod(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; - function updateMethod(node: MethodDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): MethodDeclaration; - function createConstructor(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; - function updateConstructor(node: ConstructorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined): ConstructorDeclaration; - function createGetAccessor(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; - function updateGetAccessor(node: GetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): GetAccessorDeclaration; - function createSetAccessor(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; - function updateSetAccessor(node: SetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined): SetAccessorDeclaration; - function createCallSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration; - function updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration; - function createConstructSignature(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration; - function updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration; - function createIndexSignature(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; - function updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration; - function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode; - function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode; - function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; - function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode; - function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; - function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined): TypeReferenceNode; - function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; - function createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode; - function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode; - function createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode; - function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructorTypeNode; - function createTypeQueryNode(exprName: EntityName): TypeQueryNode; - function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; - function createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; - function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode; - function createArrayTypeNode(elementType: TypeNode): ArrayTypeNode; - function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode; - function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; - function updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]): TupleTypeNode; - function createOptionalTypeNode(type: TypeNode): OptionalTypeNode; - function updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode; - function createRestTypeNode(type: TypeNode): RestTypeNode; - function updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode; - function createUnionTypeNode(types: readonly TypeNode[]): UnionTypeNode; - function updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode; - function createIntersectionTypeNode(types: readonly TypeNode[]): IntersectionTypeNode; - function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode; - function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: readonly TypeNode[]): UnionOrIntersectionTypeNode; - function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; - function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; - function createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; - function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; - function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; - function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; - function createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; - function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; - function createNamedTupleMember(dotDotDotToken: Token | undefined, name: Identifier, questionToken: Token | undefined, type: TypeNode): NamedTupleMember; - function updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: Token | undefined, name: Identifier, questionToken: Token | undefined, type: TypeNode): NamedTupleMember; - function createThisTypeNode(): ThisTypeNode; - function createTypeOperatorNode(type: TypeNode): TypeOperatorNode; - function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; - function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; - function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - function createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; - function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; - function createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; - function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; - function createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern; - function updateObjectBindingPattern(node: ObjectBindingPattern, elements: readonly BindingElement[]): ObjectBindingPattern; - function createArrayBindingPattern(elements: readonly ArrayBindingElement[]): ArrayBindingPattern; - function updateArrayBindingPattern(node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]): ArrayBindingPattern; - function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression): BindingElement; - function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined): BindingElement; - function createArrayLiteral(elements?: readonly Expression[], multiLine?: boolean): ArrayLiteralExpression; - function updateArrayLiteral(node: ArrayLiteralExpression, elements: readonly Expression[]): ArrayLiteralExpression; - function createObjectLiteral(properties?: readonly ObjectLiteralElementLike[], multiLine?: boolean): ObjectLiteralExpression; - function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression; - function createPropertyAccess(expression: Expression, name: string | Identifier | PrivateIdentifier): PropertyAccessExpression; - function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier): PropertyAccessExpression; - function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier): PropertyAccessChain; - function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier): PropertyAccessChain; - function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression; - function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression; - function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain; - function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression): ElementAccessChain; - function createCall(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallExpression; - function updateCall(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallExpression; - function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallChain; - function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallChain; - function createNew(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; - function updateNew(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression; - /** @deprecated */ function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function createTaggedTemplate(tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; - /** @deprecated */ function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; - function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; - function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; - function createParen(expression: Expression): ParenthesizedExpression; - function updateParen(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression; - function createFunctionExpression(modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[] | undefined, type: TypeNode | undefined, body: Block): FunctionExpression; - function updateFunctionExpression(node: FunctionExpression, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block): FunctionExpression; - function createArrowFunction(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; - function updateArrowFunction(node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: Token, body: ConciseBody): ArrowFunction; - function createDelete(expression: Expression): DeleteExpression; - function updateDelete(node: DeleteExpression, expression: Expression): DeleteExpression; - function createTypeOf(expression: Expression): TypeOfExpression; - function updateTypeOf(node: TypeOfExpression, expression: Expression): TypeOfExpression; - function createVoid(expression: Expression): VoidExpression; - function updateVoid(node: VoidExpression, expression: Expression): VoidExpression; - function createAwait(expression: Expression): AwaitExpression; - function updateAwait(node: AwaitExpression, expression: Expression): AwaitExpression; - function createPrefix(operator: PrefixUnaryOperator, operand: Expression): PrefixUnaryExpression; - function updatePrefix(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression; - function createPostfix(operand: Expression, operator: PostfixUnaryOperator): PostfixUnaryExpression; - function updatePostfix(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression; - function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression; - function updateBinary(node: BinaryExpression, left: Expression, right: Expression, operator?: BinaryOperator | BinaryOperatorToken): BinaryExpression; - /** @deprecated */ function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; - function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; - function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; - function createTemplateExpression(head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; - function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]): TemplateExpression; - function createTemplateHead(text: string, rawText?: string): TemplateHead; - function createTemplateMiddle(text: string, rawText?: string): TemplateMiddle; - function createTemplateTail(text: string, rawText?: string): TemplateTail; - function createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; - function createYield(expression?: Expression): YieldExpression; - function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; - function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; - function createSpread(expression: Expression): SpreadElement; - function updateSpread(node: SpreadElement, expression: Expression): SpreadElement; - function createClassExpression(modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; - function updateClassExpression(node: ClassExpression, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassExpression; - function createOmittedExpression(): OmittedExpression; - function createExpressionWithTypeArguments(typeArguments: readonly TypeNode[] | undefined, expression: Expression): ExpressionWithTypeArguments; - function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: readonly TypeNode[] | undefined, expression: Expression): ExpressionWithTypeArguments; - function createAsExpression(expression: Expression, type: TypeNode): AsExpression; - function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression; - function createNonNullExpression(expression: Expression): NonNullExpression; - function updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression; - function createNonNullChain(expression: Expression): NonNullChain; - function updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain; - function createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier): MetaProperty; - function updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty; - function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; - function updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail): TemplateSpan; - function createSemicolonClassElement(): SemicolonClassElement; - function createBlock(statements: readonly Statement[], multiLine?: boolean): Block; - function updateBlock(node: Block, statements: readonly Statement[]): Block; - function createVariableStatement(modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]): VariableStatement; - function updateVariableStatement(node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList): VariableStatement; - function createEmptyStatement(): EmptyStatement; - function createExpressionStatement(expression: Expression): ExpressionStatement; - function updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement; - /** @deprecated Use `createExpressionStatement` instead. */ - const createStatement: typeof createExpressionStatement; - /** @deprecated Use `updateExpressionStatement` instead. */ - const updateStatement: typeof updateExpressionStatement; - function createIf(expression: Expression, thenStatement: Statement, elseStatement?: Statement): IfStatement; - function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined): IfStatement; - function createDo(statement: Statement, expression: Expression): DoStatement; - function updateDo(node: DoStatement, statement: Statement, expression: Expression): DoStatement; - function createWhile(expression: Expression, statement: Statement): WhileStatement; - function updateWhile(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement; - function createFor(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; - function updateFor(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement; - function createForIn(initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; - function updateForIn(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement; - function createForOf(awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; - function updateForOf(node: ForOfStatement, awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement; - function createContinue(label?: string | Identifier): ContinueStatement; - function updateContinue(node: ContinueStatement, label: Identifier | undefined): ContinueStatement; - function createBreak(label?: string | Identifier): BreakStatement; - function updateBreak(node: BreakStatement, label: Identifier | undefined): BreakStatement; - function createReturn(expression?: Expression): ReturnStatement; - function updateReturn(node: ReturnStatement, expression: Expression | undefined): ReturnStatement; - function createWith(expression: Expression, statement: Statement): WithStatement; - function updateWith(node: WithStatement, expression: Expression, statement: Statement): WithStatement; - function createSwitch(expression: Expression, caseBlock: CaseBlock): SwitchStatement; - function updateSwitch(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement; - function createLabel(label: string | Identifier, statement: Statement): LabeledStatement; - function updateLabel(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement; - function createThrow(expression: Expression): ThrowStatement; - function updateThrow(node: ThrowStatement, expression: Expression): ThrowStatement; - function createTry(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; - function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined): TryStatement; - function createDebuggerStatement(): DebuggerStatement; - function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression): VariableDeclaration; - function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; - function createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList; - function updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]): VariableDeclarationList; - function createFunctionDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; - function updateFunctionDeclaration(node: FunctionDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration; - function createClassDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; - function updateClassDeclaration(node: ClassDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]): ClassDeclaration; - function createInterfaceDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; - function updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]): InterfaceDeclaration; - function createTypeAliasDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; - function updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode): TypeAliasDeclaration; - function createEnumDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]): EnumDeclaration; - function updateEnumDeclaration(node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]): EnumDeclaration; - function createModuleDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags): ModuleDeclaration; - function updateModuleDeclaration(node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined): ModuleDeclaration; - function createModuleBlock(statements: readonly Statement[]): ModuleBlock; - function updateModuleBlock(node: ModuleBlock, statements: readonly Statement[]): ModuleBlock; - function createCaseBlock(clauses: readonly CaseOrDefaultClause[]): CaseBlock; - function updateCaseBlock(node: CaseBlock, clauses: readonly CaseOrDefaultClause[]): CaseBlock; - function createNamespaceExportDeclaration(name: string | Identifier): NamespaceExportDeclaration; - function updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration; - function createImportEqualsDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; - function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; - function createImportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; - function updateImportDeclaration(node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; - function createImportClause(name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly?: boolean): ImportClause; - function updateImportClause(node: ImportClause, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly: boolean): ImportClause; - function createNamespaceImport(name: Identifier): NamespaceImport; - function createNamespaceExport(name: Identifier): NamespaceExport; - function updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport; - function updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport; - function createNamedImports(elements: readonly ImportSpecifier[]): NamedImports; - function updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]): NamedImports; - function createImportSpecifier(propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; - function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; - function createExportAssignment(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression): ExportAssignment; - function updateExportAssignment(node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression): ExportAssignment; - function createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression, isTypeOnly?: boolean): ExportDeclaration; - function updateExportDeclaration(node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined, isTypeOnly: boolean): ExportDeclaration; - function createNamedExports(elements: readonly ExportSpecifier[]): NamedExports; - function updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]): NamedExports; - function createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier): ExportSpecifier; - function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; - function createExternalModuleReference(expression: Expression): ExternalModuleReference; - function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; - function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression; - function createJSDocTypeTag(typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; - function createJSDocReturnTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag; - function createJSDocThisTag(typeExpression?: JSDocTypeExpression): JSDocThisTag; - /** - * @deprecated Use `createJSDocParameterTag` to create jsDoc param tag. - */ - function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag; - function createJSDocClassTag(comment?: string): JSDocClassTag; - function createJSDocComment(comment?: string | undefined, tags?: NodeArray | undefined): JSDoc; - function createJSDocTag(kind: T["kind"], tagName: string, comment?: string): T; - function createJSDocAugmentsTag(classExpression: JSDocAugmentsTag["class"], comment?: string): JSDocAugmentsTag; - function createJSDocEnumTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocEnumTag; - function createJSDocTemplateTag(constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string): JSDocTemplateTag; - function createJSDocTypedefTag(fullName?: JSDocNamespaceDeclaration | Identifier, name?: Identifier, comment?: string, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral): JSDocTypedefTag; - function createJSDocCallbackTag(fullName: JSDocNamespaceDeclaration | Identifier | undefined, name: Identifier | undefined, comment: string | undefined, typeExpression: JSDocSignature): JSDocCallbackTag; - function createJSDocSignature(typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag): JSDocSignature; - function createJSDocPropertyTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string): JSDocPropertyTag; - function createJSDocParameterTag(typeExpression: JSDocTypeExpression | undefined, name: EntityName, isNameFirst: boolean, isBracketed: boolean, comment?: string): JSDocParameterTag; - function createJSDocTypeLiteral(jsDocPropertyTags?: readonly JSDocPropertyLikeTag[], isArrayType?: boolean): JSDocTypeLiteral; - function createJSDocImplementsTag(classExpression: JSDocImplementsTag["class"], comment?: string): JSDocImplementsTag; - function createJSDocAuthorTag(comment?: string): JSDocAuthorTag; - function createJSDocPublicTag(): JSDocPublicTag; - function createJSDocPrivateTag(): JSDocPrivateTag; - function createJSDocProtectedTag(): JSDocProtectedTag; - function createJSDocReadonlyTag(): JSDocReadonlyTag; - function appendJSDocToContainer(node: JSDocContainer, jsdoc: JSDoc): JSDocContainer; - function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; - function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement): JsxElement; - function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; - function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxSelfClosingElement; - function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; - function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes): JsxOpeningElement; - function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement; - function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement; - function createJsxFragment(openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; - function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; - function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText; - function createJsxOpeningFragment(): JsxOpeningFragment; - function createJsxJsxClosingFragment(): JsxClosingFragment; - function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment): JsxFragment; - function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute; - function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute; - function createJsxAttributes(properties: readonly JsxAttributeLike[]): JsxAttributes; - function updateJsxAttributes(node: JsxAttributes, properties: readonly JsxAttributeLike[]): JsxAttributes; - function createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute; - function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute; - function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined): JsxExpression; - function updateJsxExpression(node: JsxExpression, expression: Expression | undefined): JsxExpression; - function createCaseClause(expression: Expression, statements: readonly Statement[]): CaseClause; - function updateCaseClause(node: CaseClause, expression: Expression, statements: readonly Statement[]): CaseClause; - function createDefaultClause(statements: readonly Statement[]): DefaultClause; - function updateDefaultClause(node: DefaultClause, statements: readonly Statement[]): DefaultClause; - function createHeritageClause(token: HeritageClause["token"], types: readonly ExpressionWithTypeArguments[]): HeritageClause; - function updateHeritageClause(node: HeritageClause, types: readonly ExpressionWithTypeArguments[]): HeritageClause; - function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause; - function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause; - function createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment; - function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment; - function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment; - function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined): ShorthandPropertyAssignment; - function createSpreadAssignment(expression: Expression): SpreadAssignment; - function updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; - function createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; - function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; - function updateSourceFileNode(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean, libReferences?: SourceFile["libReferenceDirectives"]): SourceFile; - /** - * Creates a shallow, memberwise clone of a node for mutation. - */ - function getMutableClone(node: T): T; - /** - * Creates a synthetic statement to act as a placeholder for a not-emitted statement in - * order to preserve comments. - * - * @param original The original statement. - */ - function createNotEmittedStatement(original: Node): NotEmittedStatement; - /** - * Creates a synthetic expression to act as a placeholder for a not-emitted expression in - * order to preserve comments or sourcemap positions. - * - * @param expression The inner expression to emit. - * @param original The original outer expression. - * @param location The location for the expression. Defaults to the positions from "original" if provided. - */ - function createPartiallyEmittedExpression(expression: Expression, original?: Node): PartiallyEmittedExpression; - function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression; - function createCommaList(elements: readonly Expression[]): CommaListExpression; - function updateCommaList(node: CommaListExpression, elements: readonly Expression[]): CommaListExpression; - function createBundle(sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; - function createUnparsedSourceFile(text: string): UnparsedSource; - function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; - function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; - function createInputFiles(javascriptText: string, declarationText: string): InputFiles; - function createInputFiles(readFileText: (path: string) => string | undefined, javascriptPath: string, javascriptMapPath: string | undefined, declarationPath: string, declarationMapPath: string | undefined, buildInfoPath: string | undefined): InputFiles; - function createInputFiles(javascriptText: string, declarationText: string, javascriptMapPath: string | undefined, javascriptMapText: string | undefined, declarationMapPath: string | undefined, declarationMapText: string | undefined): InputFiles; - function updateBundle(node: Bundle, sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[]): Bundle; - function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[]): CallExpression; - function createImmediatelyInvokedFunctionExpression(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; - function createImmediatelyInvokedArrowFunction(statements: readonly Statement[]): CallExpression; - function createImmediatelyInvokedArrowFunction(statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; - function createComma(left: Expression, right: Expression): Expression; - function createLessThan(left: Expression, right: Expression): Expression; - function createAssignment(left: ObjectLiteralExpression | ArrayLiteralExpression, right: Expression): DestructuringAssignment; - function createAssignment(left: Expression, right: Expression): BinaryExpression; - function createStrictEquality(left: Expression, right: Expression): BinaryExpression; - function createStrictInequality(left: Expression, right: Expression): BinaryExpression; - function createAdd(left: Expression, right: Expression): BinaryExpression; - function createSubtract(left: Expression, right: Expression): BinaryExpression; - function createPostfixIncrement(operand: Expression): PostfixUnaryExpression; - function createLogicalAnd(left: Expression, right: Expression): BinaryExpression; - function createLogicalOr(left: Expression, right: Expression): BinaryExpression; - function createNullishCoalesce(left: Expression, right: Expression): BinaryExpression; - function createLogicalNot(operand: Expression): PrefixUnaryExpression; - function createVoidZero(): VoidExpression; - function createExportDefault(expression: Expression): ExportAssignment; - function createExternalModuleExport(exportName: Identifier): ExportDeclaration; - /** - * Clears any EmitNode entries from parse-tree nodes. - * @param sourceFile A source file. - */ - function disposeEmitNodes(sourceFile: SourceFile): void; - function setTextRange(range: T, location: TextRange | undefined): T; - /** - * Sets flags that control emit behavior of a node. - */ - function setEmitFlags(node: T, emitFlags: EmitFlags): T; - /** - * Gets a custom text range to use when emitting source maps. - */ - function getSourceMapRange(node: Node): SourceMapRange; - /** - * Sets a custom text range to use when emitting source maps. - */ - function setSourceMapRange(node: T, range: SourceMapRange | undefined): T; - /** - * Create an external source map source file reference - */ - function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource; - /** - * Gets the TextRange to use for source maps for a token of a node. - */ - function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined; - /** - * Sets the TextRange to use for source maps for a token of a node. - */ - function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined): T; - /** - * Gets a custom text range to use when emitting comments. - */ - function getCommentRange(node: Node): TextRange; - /** - * Sets a custom text range to use when emitting comments. - */ - function setCommentRange(node: T, range: TextRange): T; - function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined; - function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined): T; - function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T; - function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined; - function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined): T; - function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T; - function moveSyntheticComments(node: T, original: Node): T; - /** - * Gets the constant value to emit for an expression. - */ - function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression): string | number | undefined; - /** - * Sets the constant value to emit for an expression. - */ - function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: string | number): PropertyAccessExpression | ElementAccessExpression; - /** - * Adds an EmitHelper to a node. - */ - function addEmitHelper(node: T, helper: EmitHelper): T; - /** - * Add EmitHelpers to a node. - */ - function addEmitHelpers(node: T, helpers: EmitHelper[] | undefined): T; - /** - * Removes an EmitHelper from a node. - */ - function removeEmitHelper(node: Node, helper: EmitHelper): boolean; - /** - * Gets the EmitHelpers of a node. - */ - function getEmitHelpers(node: Node): EmitHelper[] | undefined; - /** - * Moves matching emit helpers from a source node to a target node. - */ - function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean): void; - function setOriginalNode(node: T, original: Node | undefined): T; -} declare namespace ts { /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. @@ -4456,7 +4576,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; + function visitNode(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray) => T): T; /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -4475,7 +4595,7 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes(nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; + function visitNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -4485,18 +4605,18 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes(nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean): NodeArray; + function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray): NodeArray; - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: (nodes: NodeArray | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) => NodeArray | undefined): NodeArray | undefined; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. @@ -6160,5 +6280,761 @@ declare namespace ts { */ function transform(source: T | T[], transformers: TransformerFactory[], compilerOptions?: CompilerOptions): TransformationResult; } +declare namespace ts { + /** @deprecated Use `factory.createNodeArray` or the factory supplied by your transformation context instead. */ + const createNodeArray: (elements?: readonly T[] | undefined, hasTrailingComma?: boolean | undefined) => NodeArray; + /** @deprecated Use `factory.createNumericLiteral` or the factory supplied by your transformation context instead. */ + const createNumericLiteral: (value: string | number, numericLiteralFlags?: TokenFlags | undefined) => NumericLiteral; + /** @deprecated Use `factory.createBigIntLiteral` or the factory supplied by your transformation context instead. */ + const createBigIntLiteral: (value: string | PseudoBigInt) => BigIntLiteral; + /** @deprecated Use `factory.createStringLiteral` or the factory supplied by your transformation context instead. */ + const createStringLiteral: { + (text: string, isSingleQuote?: boolean | undefined): StringLiteral; + (text: string, isSingleQuote?: boolean | undefined, hasExtendedUnicodeEscape?: boolean | undefined): StringLiteral; + }; + /** @deprecated Use `factory.createStringLiteralFromNode` or the factory supplied by your transformation context instead. */ + const createStringLiteralFromNode: (sourceNode: Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral, isSingleQuote?: boolean | undefined) => StringLiteral; + /** @deprecated Use `factory.createRegularExpressionLiteral` or the factory supplied by your transformation context instead. */ + const createRegularExpressionLiteral: (text: string) => RegularExpressionLiteral; + /** @deprecated Use `factory.createLoopVariable` or the factory supplied by your transformation context instead. */ + const createLoopVariable: () => Identifier; + /** @deprecated Use `factory.createUniqueName` or the factory supplied by your transformation context instead. */ + const createUniqueName: (text: string, flags?: GeneratedIdentifierFlags | undefined) => Identifier; + /** @deprecated Use `factory.createPrivateIdentifier` or the factory supplied by your transformation context instead. */ + const createPrivateIdentifier: (text: string) => PrivateIdentifier; + /** @deprecated Use `factory.createSuper` or the factory supplied by your transformation context instead. */ + const createSuper: () => SuperExpression; + /** @deprecated Use `factory.createThis` or the factory supplied by your transformation context instead. */ + const createThis: () => ThisExpression; + /** @deprecated Use `factory.createNull` or the factory supplied by your transformation context instead. */ + const createNull: () => NullLiteral; + /** @deprecated Use `factory.createTrue` or the factory supplied by your transformation context instead. */ + const createTrue: () => TrueLiteral; + /** @deprecated Use `factory.createFalse` or the factory supplied by your transformation context instead. */ + const createFalse: () => FalseLiteral; + /** @deprecated Use `factory.createModifier` or the factory supplied by your transformation context instead. */ + const createModifier: (kind: T) => ModifierToken; + /** @deprecated Use `factory.createModifiersFromModifierFlags` or the factory supplied by your transformation context instead. */ + const createModifiersFromModifierFlags: (flags: ModifierFlags) => Modifier[]; + /** @deprecated Use `factory.createQualifiedName` or the factory supplied by your transformation context instead. */ + const createQualifiedName: (left: EntityName, right: string | Identifier) => QualifiedName; + /** @deprecated Use `factory.updateQualifiedName` or the factory supplied by your transformation context instead. */ + const updateQualifiedName: (node: QualifiedName, left: EntityName, right: Identifier) => QualifiedName; + /** @deprecated Use `factory.createComputedPropertyName` or the factory supplied by your transformation context instead. */ + const createComputedPropertyName: (expression: Expression) => ComputedPropertyName; + /** @deprecated Use `factory.updateComputedPropertyName` or the factory supplied by your transformation context instead. */ + const updateComputedPropertyName: (node: ComputedPropertyName, expression: Expression) => ComputedPropertyName; + /** @deprecated Use `factory.createTypeParameterDeclaration` or the factory supplied by your transformation context instead. */ + const createTypeParameterDeclaration: (name: string | Identifier, constraint?: TypeNode | undefined, defaultType?: TypeNode | undefined) => TypeParameterDeclaration; + /** @deprecated Use `factory.updateTypeParameterDeclaration` or the factory supplied by your transformation context instead. */ + const updateTypeParameterDeclaration: (node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) => TypeParameterDeclaration; + /** @deprecated Use `factory.createParameterDeclaration` or the factory supplied by your transformation context instead. */ + const createParameter: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | Identifier | ObjectBindingPattern | ArrayBindingPattern, questionToken?: QuestionToken | undefined, type?: TypeNode | undefined, initializer?: Expression | undefined) => ParameterDeclaration; + /** @deprecated Use `factory.updateParameterDeclaration` or the factory supplied by your transformation context instead. */ + const updateParameter: (node: ParameterDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | Identifier | ObjectBindingPattern | ArrayBindingPattern, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) => ParameterDeclaration; + /** @deprecated Use `factory.createDecorator` or the factory supplied by your transformation context instead. */ + const createDecorator: (expression: Expression) => Decorator; + /** @deprecated Use `factory.updateDecorator` or the factory supplied by your transformation context instead. */ + const updateDecorator: (node: Decorator, expression: Expression) => Decorator; + /** @deprecated Use `factory.createPropertyDeclaration` or the factory supplied by your transformation context instead. */ + const createProperty: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) => PropertyDeclaration; + /** @deprecated Use `factory.updatePropertyDeclaration` or the factory supplied by your transformation context instead. */ + const updateProperty: (node: PropertyDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, questionOrExclamationToken: QuestionToken | ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) => PropertyDeclaration; + /** @deprecated Use `factory.createMethodDeclaration` or the factory supplied by your transformation context instead. */ + const createMethod: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => MethodDeclaration; + /** @deprecated Use `factory.updateMethodDeclaration` or the factory supplied by your transformation context instead. */ + const updateMethod: (node: MethodDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => MethodDeclaration; + /** @deprecated Use `factory.createConstructorDeclaration` or the factory supplied by your transformation context instead. */ + const createConstructor: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined) => ConstructorDeclaration; + /** @deprecated Use `factory.updateConstructorDeclaration` or the factory supplied by your transformation context instead. */ + const updateConstructor: (node: ConstructorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], body: Block | undefined) => ConstructorDeclaration; + /** @deprecated Use `factory.createGetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + const createGetAccessor: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => GetAccessorDeclaration; + /** @deprecated Use `factory.updateGetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + const updateGetAccessor: (node: GetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => GetAccessorDeclaration; + /** @deprecated Use `factory.createSetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + const createSetAccessor: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, parameters: readonly ParameterDeclaration[], body: Block | undefined) => SetAccessorDeclaration; + /** @deprecated Use `factory.updateSetAccessorDeclaration` or the factory supplied by your transformation context instead. */ + const updateSetAccessor: (node: SetAccessorDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: PropertyName, parameters: readonly ParameterDeclaration[], body: Block | undefined) => SetAccessorDeclaration; + /** @deprecated Use `factory.createCallSignature` or the factory supplied by your transformation context instead. */ + const createCallSignature: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) => CallSignatureDeclaration; + /** @deprecated Use `factory.updateCallSignature` or the factory supplied by your transformation context instead. */ + const updateCallSignature: (node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) => CallSignatureDeclaration; + /** @deprecated Use `factory.createConstructSignature` or the factory supplied by your transformation context instead. */ + const createConstructSignature: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) => ConstructSignatureDeclaration; + /** @deprecated Use `factory.updateConstructSignature` or the factory supplied by your transformation context instead. */ + const updateConstructSignature: (node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) => ConstructSignatureDeclaration; + /** @deprecated Use `factory.updateIndexSignature` or the factory supplied by your transformation context instead. */ + const updateIndexSignature: (node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => IndexSignatureDeclaration; + /** @deprecated Use `factory.createKeywordTypeNode` or the factory supplied by your transformation context instead. */ + const createKeywordTypeNode: (kind: TKind) => KeywordTypeNode; + /** @deprecated Use `factory.createTypePredicateNode` or the factory supplied by your transformation context instead. */ + const createTypePredicateNodeWithModifier: (assertsModifier: AssertsKeyword | undefined, parameterName: string | Identifier | ThisTypeNode, type: TypeNode | undefined) => TypePredicateNode; + /** @deprecated Use `factory.updateTypePredicateNode` or the factory supplied by your transformation context instead. */ + const updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) => TypePredicateNode; + /** @deprecated Use `factory.createTypeReferenceNode` or the factory supplied by your transformation context instead. */ + const createTypeReferenceNode: (typeName: string | Identifier | QualifiedName, typeArguments?: readonly TypeNode[] | undefined) => TypeReferenceNode; + /** @deprecated Use `factory.updateTypeReferenceNode` or the factory supplied by your transformation context instead. */ + const updateTypeReferenceNode: (node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) => TypeReferenceNode; + /** @deprecated Use `factory.createFunctionTypeNode` or the factory supplied by your transformation context instead. */ + const createFunctionTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => FunctionTypeNode; + /** @deprecated Use `factory.updateFunctionTypeNode` or the factory supplied by your transformation context instead. */ + const updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => FunctionTypeNode; + /** @deprecated Use `factory.createConstructorTypeNode` or the factory supplied by your transformation context instead. */ + const createConstructorTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => ConstructorTypeNode; + /** @deprecated Use `factory.updateConstructorTypeNode` or the factory supplied by your transformation context instead. */ + const updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => ConstructorTypeNode; + /** @deprecated Use `factory.createTypeQueryNode` or the factory supplied by your transformation context instead. */ + const createTypeQueryNode: (exprName: EntityName) => TypeQueryNode; + /** @deprecated Use `factory.updateTypeQueryNode` or the factory supplied by your transformation context instead. */ + const updateTypeQueryNode: (node: TypeQueryNode, exprName: EntityName) => TypeQueryNode; + /** @deprecated Use `factory.createTypeLiteralNode` or the factory supplied by your transformation context instead. */ + const createTypeLiteralNode: (members: readonly TypeElement[] | undefined) => TypeLiteralNode; + /** @deprecated Use `factory.updateTypeLiteralNode` or the factory supplied by your transformation context instead. */ + const updateTypeLiteralNode: (node: TypeLiteralNode, members: NodeArray) => TypeLiteralNode; + /** @deprecated Use `factory.createArrayTypeNode` or the factory supplied by your transformation context instead. */ + const createArrayTypeNode: (elementType: TypeNode) => ArrayTypeNode; + /** @deprecated Use `factory.updateArrayTypeNode` or the factory supplied by your transformation context instead. */ + const updateArrayTypeNode: (node: ArrayTypeNode, elementType: TypeNode) => ArrayTypeNode; + /** @deprecated Use `factory.createTupleTypeNode` or the factory supplied by your transformation context instead. */ + const createTupleTypeNode: (elements: readonly (TypeNode | NamedTupleMember)[]) => TupleTypeNode; + /** @deprecated Use `factory.updateTupleTypeNode` or the factory supplied by your transformation context instead. */ + const updateTupleTypeNode: (node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]) => TupleTypeNode; + /** @deprecated Use `factory.createOptionalTypeNode` or the factory supplied by your transformation context instead. */ + const createOptionalTypeNode: (type: TypeNode) => OptionalTypeNode; + /** @deprecated Use `factory.updateOptionalTypeNode` or the factory supplied by your transformation context instead. */ + const updateOptionalTypeNode: (node: OptionalTypeNode, type: TypeNode) => OptionalTypeNode; + /** @deprecated Use `factory.createRestTypeNode` or the factory supplied by your transformation context instead. */ + const createRestTypeNode: (type: TypeNode) => RestTypeNode; + /** @deprecated Use `factory.updateRestTypeNode` or the factory supplied by your transformation context instead. */ + const updateRestTypeNode: (node: RestTypeNode, type: TypeNode) => RestTypeNode; + /** @deprecated Use `factory.createUnionTypeNode` or the factory supplied by your transformation context instead. */ + const createUnionTypeNode: (types: readonly TypeNode[]) => UnionTypeNode; + /** @deprecated Use `factory.updateUnionTypeNode` or the factory supplied by your transformation context instead. */ + const updateUnionTypeNode: (node: UnionTypeNode, types: NodeArray) => UnionTypeNode; + /** @deprecated Use `factory.createIntersectionTypeNode` or the factory supplied by your transformation context instead. */ + const createIntersectionTypeNode: (types: readonly TypeNode[]) => IntersectionTypeNode; + /** @deprecated Use `factory.updateIntersectionTypeNode` or the factory supplied by your transformation context instead. */ + const updateIntersectionTypeNode: (node: IntersectionTypeNode, types: NodeArray) => IntersectionTypeNode; + /** @deprecated Use `factory.createConditionalTypeNode` or the factory supplied by your transformation context instead. */ + const createConditionalTypeNode: (checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) => ConditionalTypeNode; + /** @deprecated Use `factory.updateConditionalTypeNode` or the factory supplied by your transformation context instead. */ + const updateConditionalTypeNode: (node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) => ConditionalTypeNode; + /** @deprecated Use `factory.createInferTypeNode` or the factory supplied by your transformation context instead. */ + const createInferTypeNode: (typeParameter: TypeParameterDeclaration) => InferTypeNode; + /** @deprecated Use `factory.updateInferTypeNode` or the factory supplied by your transformation context instead. */ + const updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) => InferTypeNode; + /** @deprecated Use `factory.createImportTypeNode` or the factory supplied by your transformation context instead. */ + const createImportTypeNode: (argument: TypeNode, qualifier?: Identifier | QualifiedName | undefined, typeArguments?: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; + /** @deprecated Use `factory.updateImportTypeNode` or the factory supplied by your transformation context instead. */ + const updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: Identifier | QualifiedName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; + /** @deprecated Use `factory.createParenthesizedType` or the factory supplied by your transformation context instead. */ + const createParenthesizedType: (type: TypeNode) => ParenthesizedTypeNode; + /** @deprecated Use `factory.updateParenthesizedType` or the factory supplied by your transformation context instead. */ + const updateParenthesizedType: (node: ParenthesizedTypeNode, type: TypeNode) => ParenthesizedTypeNode; + /** @deprecated Use `factory.createThisTypeNode` or the factory supplied by your transformation context instead. */ + const createThisTypeNode: () => ThisTypeNode; + /** @deprecated Use `factory.updateTypeOperatorNode` or the factory supplied by your transformation context instead. */ + const updateTypeOperatorNode: (node: TypeOperatorNode, type: TypeNode) => TypeOperatorNode; + /** @deprecated Use `factory.createIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */ + const createIndexedAccessTypeNode: (objectType: TypeNode, indexType: TypeNode) => IndexedAccessTypeNode; + /** @deprecated Use `factory.updateIndexedAccessTypeNode` or the factory supplied by your transformation context instead. */ + const updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) => IndexedAccessTypeNode; + /** @deprecated Use `factory.createMappedTypeNode` or the factory supplied by your transformation context instead. */ + const createMappedTypeNode: (readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode; + /** @deprecated Use `factory.updateMappedTypeNode` or the factory supplied by your transformation context instead. */ + const updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined) => MappedTypeNode; + /** @deprecated Use `factory.createLiteralTypeNode` or the factory supplied by your transformation context instead. */ + const createLiteralTypeNode: (literal: LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral) => LiteralTypeNode; + /** @deprecated Use `factory.updateLiteralTypeNode` or the factory supplied by your transformation context instead. */ + const updateLiteralTypeNode: (node: LiteralTypeNode, literal: LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral) => LiteralTypeNode; + /** @deprecated Use `factory.createObjectBindingPattern` or the factory supplied by your transformation context instead. */ + const createObjectBindingPattern: (elements: readonly BindingElement[]) => ObjectBindingPattern; + /** @deprecated Use `factory.updateObjectBindingPattern` or the factory supplied by your transformation context instead. */ + const updateObjectBindingPattern: (node: ObjectBindingPattern, elements: readonly BindingElement[]) => ObjectBindingPattern; + /** @deprecated Use `factory.createArrayBindingPattern` or the factory supplied by your transformation context instead. */ + const createArrayBindingPattern: (elements: readonly ArrayBindingElement[]) => ArrayBindingPattern; + /** @deprecated Use `factory.updateArrayBindingPattern` or the factory supplied by your transformation context instead. */ + const updateArrayBindingPattern: (node: ArrayBindingPattern, elements: readonly ArrayBindingElement[]) => ArrayBindingPattern; + /** @deprecated Use `factory.createBindingElement` or the factory supplied by your transformation context instead. */ + const createBindingElement: (dotDotDotToken: DotDotDotToken | undefined, propertyName: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | undefined, name: string | Identifier | ObjectBindingPattern | ArrayBindingPattern, initializer?: Expression | undefined) => BindingElement; + /** @deprecated Use `factory.updateBindingElement` or the factory supplied by your transformation context instead. */ + const updateBindingElement: (node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | undefined, name: BindingName, initializer: Expression | undefined) => BindingElement; + /** @deprecated Use `factory.createArrayLiteral` or the factory supplied by your transformation context instead. */ + const createArrayLiteral: (elements?: readonly Expression[] | undefined, multiLine?: boolean | undefined) => ArrayLiteralExpression; + /** @deprecated Use `factory.updateArrayLiteral` or the factory supplied by your transformation context instead. */ + const updateArrayLiteral: (node: ArrayLiteralExpression, elements: readonly Expression[]) => ArrayLiteralExpression; + /** @deprecated Use `factory.createObjectLiteral` or the factory supplied by your transformation context instead. */ + const createObjectLiteral: (properties?: readonly ObjectLiteralElementLike[] | undefined, multiLine?: boolean | undefined) => ObjectLiteralExpression; + /** @deprecated Use `factory.updateObjectLiteral` or the factory supplied by your transformation context instead. */ + const updateObjectLiteral: (node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]) => ObjectLiteralExpression; + /** @deprecated Use `factory.createPropertyAccess` or the factory supplied by your transformation context instead. */ + const createPropertyAccess: (expression: Expression, name: string | Identifier | PrivateIdentifier) => PropertyAccessExpression; + /** @deprecated Use `factory.updatePropertyAccess` or the factory supplied by your transformation context instead. */ + const updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: Identifier | PrivateIdentifier) => PropertyAccessExpression; + /** @deprecated Use `factory.createPropertyAccessChain` or the factory supplied by your transformation context instead. */ + const createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier | PrivateIdentifier) => PropertyAccessChain; + /** @deprecated Use `factory.updatePropertyAccessChain` or the factory supplied by your transformation context instead. */ + const updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier | PrivateIdentifier) => PropertyAccessChain; + /** @deprecated Use `factory.createElementAccess` or the factory supplied by your transformation context instead. */ + const createElementAccess: (expression: Expression, index: number | Expression) => ElementAccessExpression; + /** @deprecated Use `factory.updateElementAccess` or the factory supplied by your transformation context instead. */ + const updateElementAccess: (node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) => ElementAccessExpression; + /** @deprecated Use `factory.createElementAccessChain` or the factory supplied by your transformation context instead. */ + const createElementAccessChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression) => ElementAccessChain; + /** @deprecated Use `factory.updateElementAccessChain` or the factory supplied by your transformation context instead. */ + const updateElementAccessChain: (node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression) => ElementAccessChain; + /** @deprecated Use `factory.createCall` or the factory supplied by your transformation context instead. */ + const createCall: (expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) => CallExpression; + /** @deprecated Use `factory.updateCall` or the factory supplied by your transformation context instead. */ + const updateCall: (node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) => CallExpression; + /** @deprecated Use `factory.createCallChain` or the factory supplied by your transformation context instead. */ + const createCallChain: (expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) => CallChain; + /** @deprecated Use `factory.updateCallChain` or the factory supplied by your transformation context instead. */ + const updateCallChain: (node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) => CallChain; + /** @deprecated Use `factory.createNew` or the factory supplied by your transformation context instead. */ + const createNew: (expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) => NewExpression; + /** @deprecated Use `factory.updateNew` or the factory supplied by your transformation context instead. */ + const updateNew: (node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) => NewExpression; + /** @deprecated Use `factory.createTypeAssertion` or the factory supplied by your transformation context instead. */ + const createTypeAssertion: (type: TypeNode, expression: Expression) => TypeAssertion; + /** @deprecated Use `factory.updateTypeAssertion` or the factory supplied by your transformation context instead. */ + const updateTypeAssertion: (node: TypeAssertion, type: TypeNode, expression: Expression) => TypeAssertion; + /** @deprecated Use `factory.createParen` or the factory supplied by your transformation context instead. */ + const createParen: (expression: Expression) => ParenthesizedExpression; + /** @deprecated Use `factory.updateParen` or the factory supplied by your transformation context instead. */ + const updateParen: (node: ParenthesizedExpression, expression: Expression) => ParenthesizedExpression; + /** @deprecated Use `factory.createFunctionExpression` or the factory supplied by your transformation context instead. */ + const createFunctionExpression: (modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[] | undefined, type: TypeNode | undefined, body: Block) => FunctionExpression; + /** @deprecated Use `factory.updateFunctionExpression` or the factory supplied by your transformation context instead. */ + const updateFunctionExpression: (node: FunctionExpression, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block) => FunctionExpression; + /** @deprecated Use `factory.createDelete` or the factory supplied by your transformation context instead. */ + const createDelete: (expression: Expression) => DeleteExpression; + /** @deprecated Use `factory.updateDelete` or the factory supplied by your transformation context instead. */ + const updateDelete: (node: DeleteExpression, expression: Expression) => DeleteExpression; + /** @deprecated Use `factory.createTypeOf` or the factory supplied by your transformation context instead. */ + const createTypeOf: (expression: Expression) => TypeOfExpression; + /** @deprecated Use `factory.updateTypeOf` or the factory supplied by your transformation context instead. */ + const updateTypeOf: (node: TypeOfExpression, expression: Expression) => TypeOfExpression; + /** @deprecated Use `factory.createVoid` or the factory supplied by your transformation context instead. */ + const createVoid: (expression: Expression) => VoidExpression; + /** @deprecated Use `factory.updateVoid` or the factory supplied by your transformation context instead. */ + const updateVoid: (node: VoidExpression, expression: Expression) => VoidExpression; + /** @deprecated Use `factory.createAwait` or the factory supplied by your transformation context instead. */ + const createAwait: (expression: Expression) => AwaitExpression; + /** @deprecated Use `factory.updateAwait` or the factory supplied by your transformation context instead. */ + const updateAwait: (node: AwaitExpression, expression: Expression) => AwaitExpression; + /** @deprecated Use `factory.createPrefix` or the factory supplied by your transformation context instead. */ + const createPrefix: (operator: PrefixUnaryOperator, operand: Expression) => PrefixUnaryExpression; + /** @deprecated Use `factory.updatePrefix` or the factory supplied by your transformation context instead. */ + const updatePrefix: (node: PrefixUnaryExpression, operand: Expression) => PrefixUnaryExpression; + /** @deprecated Use `factory.createPostfix` or the factory supplied by your transformation context instead. */ + const createPostfix: (operand: Expression, operator: PostfixUnaryOperator) => PostfixUnaryExpression; + /** @deprecated Use `factory.updatePostfix` or the factory supplied by your transformation context instead. */ + const updatePostfix: (node: PostfixUnaryExpression, operand: Expression) => PostfixUnaryExpression; + /** @deprecated Use `factory.createBinary` or the factory supplied by your transformation context instead. */ + const createBinary: (left: Expression, operator: SyntaxKind.CommaToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.EqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.AsteriskToken | SyntaxKind.AsteriskAsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.QuestionQuestionToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | BinaryOperatorToken, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.updateConditional` or the factory supplied by your transformation context instead. */ + const updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) => ConditionalExpression; + /** @deprecated Use `factory.createTemplateExpression` or the factory supplied by your transformation context instead. */ + const createTemplateExpression: (head: TemplateHead, templateSpans: readonly TemplateSpan[]) => TemplateExpression; + /** @deprecated Use `factory.updateTemplateExpression` or the factory supplied by your transformation context instead. */ + const updateTemplateExpression: (node: TemplateExpression, head: TemplateHead, templateSpans: readonly TemplateSpan[]) => TemplateExpression; + /** @deprecated Use `factory.createTemplateHead` or the factory supplied by your transformation context instead. */ + const createTemplateHead: { + (text: string, rawText?: string | undefined, templateFlags?: TokenFlags | undefined): TemplateHead; + (text: string | undefined, rawText: string, templateFlags?: TokenFlags | undefined): TemplateHead; + }; + /** @deprecated Use `factory.createTemplateMiddle` or the factory supplied by your transformation context instead. */ + const createTemplateMiddle: { + (text: string, rawText?: string | undefined, templateFlags?: TokenFlags | undefined): TemplateMiddle; + (text: string | undefined, rawText: string, templateFlags?: TokenFlags | undefined): TemplateMiddle; + }; + /** @deprecated Use `factory.createTemplateTail` or the factory supplied by your transformation context instead. */ + const createTemplateTail: { + (text: string, rawText?: string | undefined, templateFlags?: TokenFlags | undefined): TemplateTail; + (text: string | undefined, rawText: string, templateFlags?: TokenFlags | undefined): TemplateTail; + }; + /** @deprecated Use `factory.createNoSubstitutionTemplateLiteral` or the factory supplied by your transformation context instead. */ + const createNoSubstitutionTemplateLiteral: { + (text: string, rawText?: string | undefined): NoSubstitutionTemplateLiteral; + (text: string | undefined, rawText: string): NoSubstitutionTemplateLiteral; + }; + /** @deprecated Use `factory.updateYield` or the factory supplied by your transformation context instead. */ + const updateYield: (node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression | undefined) => YieldExpression; + /** @deprecated Use `factory.createSpread` or the factory supplied by your transformation context instead. */ + const createSpread: (expression: Expression) => SpreadElement; + /** @deprecated Use `factory.updateSpread` or the factory supplied by your transformation context instead. */ + const updateSpread: (node: SpreadElement, expression: Expression) => SpreadElement; + /** @deprecated Use `factory.createOmittedExpression` or the factory supplied by your transformation context instead. */ + const createOmittedExpression: () => OmittedExpression; + /** @deprecated Use `factory.createAsExpression` or the factory supplied by your transformation context instead. */ + const createAsExpression: (expression: Expression, type: TypeNode) => AsExpression; + /** @deprecated Use `factory.updateAsExpression` or the factory supplied by your transformation context instead. */ + const updateAsExpression: (node: AsExpression, expression: Expression, type: TypeNode) => AsExpression; + /** @deprecated Use `factory.createNonNullExpression` or the factory supplied by your transformation context instead. */ + const createNonNullExpression: (expression: Expression) => NonNullExpression; + /** @deprecated Use `factory.updateNonNullExpression` or the factory supplied by your transformation context instead. */ + const updateNonNullExpression: (node: NonNullExpression, expression: Expression) => NonNullExpression; + /** @deprecated Use `factory.createNonNullChain` or the factory supplied by your transformation context instead. */ + const createNonNullChain: (expression: Expression) => NonNullChain; + /** @deprecated Use `factory.updateNonNullChain` or the factory supplied by your transformation context instead. */ + const updateNonNullChain: (node: NonNullChain, expression: Expression) => NonNullChain; + /** @deprecated Use `factory.createMetaProperty` or the factory supplied by your transformation context instead. */ + const createMetaProperty: (keywordToken: SyntaxKind.ImportKeyword | SyntaxKind.NewKeyword, name: Identifier) => MetaProperty; + /** @deprecated Use `factory.updateMetaProperty` or the factory supplied by your transformation context instead. */ + const updateMetaProperty: (node: MetaProperty, name: Identifier) => MetaProperty; + /** @deprecated Use `factory.createTemplateSpan` or the factory supplied by your transformation context instead. */ + const createTemplateSpan: (expression: Expression, literal: TemplateMiddle | TemplateTail) => TemplateSpan; + /** @deprecated Use `factory.updateTemplateSpan` or the factory supplied by your transformation context instead. */ + const updateTemplateSpan: (node: TemplateSpan, expression: Expression, literal: TemplateMiddle | TemplateTail) => TemplateSpan; + /** @deprecated Use `factory.createSemicolonClassElement` or the factory supplied by your transformation context instead. */ + const createSemicolonClassElement: () => SemicolonClassElement; + /** @deprecated Use `factory.createBlock` or the factory supplied by your transformation context instead. */ + const createBlock: (statements: readonly Statement[], multiLine?: boolean | undefined) => Block; + /** @deprecated Use `factory.updateBlock` or the factory supplied by your transformation context instead. */ + const updateBlock: (node: Block, statements: readonly Statement[]) => Block; + /** @deprecated Use `factory.createVariableStatement` or the factory supplied by your transformation context instead. */ + const createVariableStatement: (modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList | readonly VariableDeclaration[]) => VariableStatement; + /** @deprecated Use `factory.updateVariableStatement` or the factory supplied by your transformation context instead. */ + const updateVariableStatement: (node: VariableStatement, modifiers: readonly Modifier[] | undefined, declarationList: VariableDeclarationList) => VariableStatement; + /** @deprecated Use `factory.createEmptyStatement` or the factory supplied by your transformation context instead. */ + const createEmptyStatement: () => EmptyStatement; + /** @deprecated Use `factory.createExpressionStatement` or the factory supplied by your transformation context instead. */ + const createExpressionStatement: (expression: Expression) => ExpressionStatement; + /** @deprecated Use `factory.updateExpressionStatement` or the factory supplied by your transformation context instead. */ + const updateExpressionStatement: (node: ExpressionStatement, expression: Expression) => ExpressionStatement; + /** @deprecated Use `factory.createExpressionStatement` or the factory supplied by your transformation context instead. */ + const createStatement: (expression: Expression) => ExpressionStatement; + /** @deprecated Use `factory.updateExpressionStatement` or the factory supplied by your transformation context instead. */ + const updateStatement: (node: ExpressionStatement, expression: Expression) => ExpressionStatement; + /** @deprecated Use `factory.createIf` or the factory supplied by your transformation context instead. */ + const createIf: (expression: Expression, thenStatement: Statement, elseStatement?: Statement | undefined) => IfStatement; + /** @deprecated Use `factory.updateIf` or the factory supplied by your transformation context instead. */ + const updateIf: (node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined) => IfStatement; + /** @deprecated Use `factory.createDo` or the factory supplied by your transformation context instead. */ + const createDo: (statement: Statement, expression: Expression) => DoStatement; + /** @deprecated Use `factory.updateDo` or the factory supplied by your transformation context instead. */ + const updateDo: (node: DoStatement, statement: Statement, expression: Expression) => DoStatement; + /** @deprecated Use `factory.createWhile` or the factory supplied by your transformation context instead. */ + const createWhile: (expression: Expression, statement: Statement) => WhileStatement; + /** @deprecated Use `factory.updateWhile` or the factory supplied by your transformation context instead. */ + const updateWhile: (node: WhileStatement, expression: Expression, statement: Statement) => WhileStatement; + /** @deprecated Use `factory.createFor` or the factory supplied by your transformation context instead. */ + const createFor: (initializer: Expression | VariableDeclarationList | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) => ForStatement; + /** @deprecated Use `factory.updateFor` or the factory supplied by your transformation context instead. */ + const updateFor: (node: ForStatement, initializer: Expression | VariableDeclarationList | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) => ForStatement; + /** @deprecated Use `factory.createForIn` or the factory supplied by your transformation context instead. */ + const createForIn: (initializer: ForInitializer, expression: Expression, statement: Statement) => ForInStatement; + /** @deprecated Use `factory.updateForIn` or the factory supplied by your transformation context instead. */ + const updateForIn: (node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement) => ForInStatement; + /** @deprecated Use `factory.createForOf` or the factory supplied by your transformation context instead. */ + const createForOf: (awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) => ForOfStatement; + /** @deprecated Use `factory.updateForOf` or the factory supplied by your transformation context instead. */ + const updateForOf: (node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) => ForOfStatement; + /** @deprecated Use `factory.createContinue` or the factory supplied by your transformation context instead. */ + const createContinue: (label?: string | Identifier | undefined) => ContinueStatement; + /** @deprecated Use `factory.updateContinue` or the factory supplied by your transformation context instead. */ + const updateContinue: (node: ContinueStatement, label: Identifier | undefined) => ContinueStatement; + /** @deprecated Use `factory.createBreak` or the factory supplied by your transformation context instead. */ + const createBreak: (label?: string | Identifier | undefined) => BreakStatement; + /** @deprecated Use `factory.updateBreak` or the factory supplied by your transformation context instead. */ + const updateBreak: (node: BreakStatement, label: Identifier | undefined) => BreakStatement; + /** @deprecated Use `factory.createReturn` or the factory supplied by your transformation context instead. */ + const createReturn: (expression?: Expression | undefined) => ReturnStatement; + /** @deprecated Use `factory.updateReturn` or the factory supplied by your transformation context instead. */ + const updateReturn: (node: ReturnStatement, expression: Expression | undefined) => ReturnStatement; + /** @deprecated Use `factory.createWith` or the factory supplied by your transformation context instead. */ + const createWith: (expression: Expression, statement: Statement) => WithStatement; + /** @deprecated Use `factory.updateWith` or the factory supplied by your transformation context instead. */ + const updateWith: (node: WithStatement, expression: Expression, statement: Statement) => WithStatement; + /** @deprecated Use `factory.createSwitch` or the factory supplied by your transformation context instead. */ + const createSwitch: (expression: Expression, caseBlock: CaseBlock) => SwitchStatement; + /** @deprecated Use `factory.updateSwitch` or the factory supplied by your transformation context instead. */ + const updateSwitch: (node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) => SwitchStatement; + /** @deprecated Use `factory.createLabel` or the factory supplied by your transformation context instead. */ + const createLabel: (label: string | Identifier, statement: Statement) => LabeledStatement; + /** @deprecated Use `factory.updateLabel` or the factory supplied by your transformation context instead. */ + const updateLabel: (node: LabeledStatement, label: Identifier, statement: Statement) => LabeledStatement; + /** @deprecated Use `factory.createThrow` or the factory supplied by your transformation context instead. */ + const createThrow: (expression: Expression) => ThrowStatement; + /** @deprecated Use `factory.updateThrow` or the factory supplied by your transformation context instead. */ + const updateThrow: (node: ThrowStatement, expression: Expression) => ThrowStatement; + /** @deprecated Use `factory.createTry` or the factory supplied by your transformation context instead. */ + const createTry: (tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) => TryStatement; + /** @deprecated Use `factory.updateTry` or the factory supplied by your transformation context instead. */ + const updateTry: (node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) => TryStatement; + /** @deprecated Use `factory.createDebuggerStatement` or the factory supplied by your transformation context instead. */ + const createDebuggerStatement: () => DebuggerStatement; + /** @deprecated Use `factory.createVariableDeclarationList` or the factory supplied by your transformation context instead. */ + const createVariableDeclarationList: (declarations: readonly VariableDeclaration[], flags?: NodeFlags | undefined) => VariableDeclarationList; + /** @deprecated Use `factory.updateVariableDeclarationList` or the factory supplied by your transformation context instead. */ + const updateVariableDeclarationList: (node: VariableDeclarationList, declarations: readonly VariableDeclaration[]) => VariableDeclarationList; + /** @deprecated Use `factory.createFunctionDeclaration` or the factory supplied by your transformation context instead. */ + const createFunctionDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => FunctionDeclaration; + /** @deprecated Use `factory.updateFunctionDeclaration` or the factory supplied by your transformation context instead. */ + const updateFunctionDeclaration: (node: FunctionDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) => FunctionDeclaration; + /** @deprecated Use `factory.createClassDeclaration` or the factory supplied by your transformation context instead. */ + const createClassDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]) => ClassDeclaration; + /** @deprecated Use `factory.updateClassDeclaration` or the factory supplied by your transformation context instead. */ + const updateClassDeclaration: (node: ClassDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]) => ClassDeclaration; + /** @deprecated Use `factory.createInterfaceDeclaration` or the factory supplied by your transformation context instead. */ + const createInterfaceDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]) => InterfaceDeclaration; + /** @deprecated Use `factory.updateInterfaceDeclaration` or the factory supplied by your transformation context instead. */ + const updateInterfaceDeclaration: (node: InterfaceDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly TypeElement[]) => InterfaceDeclaration; + /** @deprecated Use `factory.createTypeAliasDeclaration` or the factory supplied by your transformation context instead. */ + const createTypeAliasDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode) => TypeAliasDeclaration; + /** @deprecated Use `factory.updateTypeAliasDeclaration` or the factory supplied by your transformation context instead. */ + const updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, typeParameters: readonly TypeParameterDeclaration[] | undefined, type: TypeNode) => TypeAliasDeclaration; + /** @deprecated Use `factory.createEnumDeclaration` or the factory supplied by your transformation context instead. */ + const createEnumDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, members: readonly EnumMember[]) => EnumDeclaration; + /** @deprecated Use `factory.updateEnumDeclaration` or the factory supplied by your transformation context instead. */ + const updateEnumDeclaration: (node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]) => EnumDeclaration; + /** @deprecated Use `factory.createModuleDeclaration` or the factory supplied by your transformation context instead. */ + const createModuleDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined, flags?: NodeFlags | undefined) => ModuleDeclaration; + /** @deprecated Use `factory.updateModuleDeclaration` or the factory supplied by your transformation context instead. */ + const updateModuleDeclaration: (node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined) => ModuleDeclaration; + /** @deprecated Use `factory.createModuleBlock` or the factory supplied by your transformation context instead. */ + const createModuleBlock: (statements: readonly Statement[]) => ModuleBlock; + /** @deprecated Use `factory.updateModuleBlock` or the factory supplied by your transformation context instead. */ + const updateModuleBlock: (node: ModuleBlock, statements: readonly Statement[]) => ModuleBlock; + /** @deprecated Use `factory.createCaseBlock` or the factory supplied by your transformation context instead. */ + const createCaseBlock: (clauses: readonly CaseOrDefaultClause[]) => CaseBlock; + /** @deprecated Use `factory.updateCaseBlock` or the factory supplied by your transformation context instead. */ + const updateCaseBlock: (node: CaseBlock, clauses: readonly CaseOrDefaultClause[]) => CaseBlock; + /** @deprecated Use `factory.createNamespaceExportDeclaration` or the factory supplied by your transformation context instead. */ + const createNamespaceExportDeclaration: (name: string | Identifier) => NamespaceExportDeclaration; + /** @deprecated Use `factory.updateNamespaceExportDeclaration` or the factory supplied by your transformation context instead. */ + const updateNamespaceExportDeclaration: (node: NamespaceExportDeclaration, name: Identifier) => NamespaceExportDeclaration; + /** @deprecated Use `factory.createImportEqualsDeclaration` or the factory supplied by your transformation context instead. */ + const createImportEqualsDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference) => ImportEqualsDeclaration; + /** @deprecated Use `factory.updateImportEqualsDeclaration` or the factory supplied by your transformation context instead. */ + const updateImportEqualsDeclaration: (node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference) => ImportEqualsDeclaration; + /** @deprecated Use `factory.createImportDeclaration` or the factory supplied by your transformation context instead. */ + const createImportDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression) => ImportDeclaration; + /** @deprecated Use `factory.updateImportDeclaration` or the factory supplied by your transformation context instead. */ + const updateImportDeclaration: (node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression) => ImportDeclaration; + /** @deprecated Use `factory.createNamespaceImport` or the factory supplied by your transformation context instead. */ + const createNamespaceImport: (name: Identifier) => NamespaceImport; + /** @deprecated Use `factory.updateNamespaceImport` or the factory supplied by your transformation context instead. */ + const updateNamespaceImport: (node: NamespaceImport, name: Identifier) => NamespaceImport; + /** @deprecated Use `factory.createNamedImports` or the factory supplied by your transformation context instead. */ + const createNamedImports: (elements: readonly ImportSpecifier[]) => NamedImports; + /** @deprecated Use `factory.updateNamedImports` or the factory supplied by your transformation context instead. */ + const updateNamedImports: (node: NamedImports, elements: readonly ImportSpecifier[]) => NamedImports; + /** @deprecated Use `factory.createImportSpecifier` or the factory supplied by your transformation context instead. */ + const createImportSpecifier: (propertyName: Identifier | undefined, name: Identifier) => ImportSpecifier; + /** @deprecated Use `factory.updateImportSpecifier` or the factory supplied by your transformation context instead. */ + const updateImportSpecifier: (node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier) => ImportSpecifier; + /** @deprecated Use `factory.createExportAssignment` or the factory supplied by your transformation context instead. */ + const createExportAssignment: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression) => ExportAssignment; + /** @deprecated Use `factory.updateExportAssignment` or the factory supplied by your transformation context instead. */ + const updateExportAssignment: (node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression) => ExportAssignment; + /** @deprecated Use `factory.createNamedExports` or the factory supplied by your transformation context instead. */ + const createNamedExports: (elements: readonly ExportSpecifier[]) => NamedExports; + /** @deprecated Use `factory.updateNamedExports` or the factory supplied by your transformation context instead. */ + const updateNamedExports: (node: NamedExports, elements: readonly ExportSpecifier[]) => NamedExports; + /** @deprecated Use `factory.createExportSpecifier` or the factory supplied by your transformation context instead. */ + const createExportSpecifier: (propertyName: string | Identifier | undefined, name: string | Identifier) => ExportSpecifier; + /** @deprecated Use `factory.updateExportSpecifier` or the factory supplied by your transformation context instead. */ + const updateExportSpecifier: (node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier) => ExportSpecifier; + /** @deprecated Use `factory.createExternalModuleReference` or the factory supplied by your transformation context instead. */ + const createExternalModuleReference: (expression: Expression) => ExternalModuleReference; + /** @deprecated Use `factory.updateExternalModuleReference` or the factory supplied by your transformation context instead. */ + const updateExternalModuleReference: (node: ExternalModuleReference, expression: Expression) => ExternalModuleReference; + /** @deprecated Use `factory.createJSDocTypeExpression` or the factory supplied by your transformation context instead. */ + const createJSDocTypeExpression: (type: TypeNode) => JSDocTypeExpression; + /** @deprecated Use `factory.createJSDocTypeTag` or the factory supplied by your transformation context instead. */ + const createJSDocTypeTag: (tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string | undefined) => JSDocTypeTag; + /** @deprecated Use `factory.createJSDocReturnTag` or the factory supplied by your transformation context instead. */ + const createJSDocReturnTag: (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocReturnTag; + /** @deprecated Use `factory.createJSDocThisTag` or the factory supplied by your transformation context instead. */ + const createJSDocThisTag: (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocThisTag; + /** @deprecated Use `factory.createJSDocComment` or the factory supplied by your transformation context instead. */ + const createJSDocComment: (comment?: string | undefined, tags?: readonly JSDocTag[] | undefined) => JSDoc; + /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ + const createJSDocParameterTag: (tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocParameterTag; + /** @deprecated Use `factory.createJSDocClassTag` or the factory supplied by your transformation context instead. */ + const createJSDocClassTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocClassTag; + /** @deprecated Use `factory.createJSDocAugmentsTag` or the factory supplied by your transformation context instead. */ + const createJSDocAugmentsTag: (tagName: Identifier | undefined, className: ExpressionWithTypeArguments & { + readonly expression: Identifier | PropertyAccessEntityNameExpression; + }, comment?: string | undefined) => JSDocAugmentsTag; + /** @deprecated Use `factory.createJSDocEnumTag` or the factory supplied by your transformation context instead. */ + const createJSDocEnumTag: (tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocEnumTag; + /** @deprecated Use `factory.createJSDocTemplateTag` or the factory supplied by your transformation context instead. */ + const createJSDocTemplateTag: (tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment?: string | undefined) => JSDocTemplateTag; + /** @deprecated Use `factory.createJSDocTypedefTag` or the factory supplied by your transformation context instead. */ + const createJSDocTypedefTag: (tagName: Identifier | undefined, typeExpression?: JSDocTypeLiteral | JSDocTypeExpression | undefined, fullName?: Identifier | JSDocNamespaceDeclaration | undefined, comment?: string | undefined) => JSDocTypedefTag; + /** @deprecated Use `factory.createJSDocCallbackTag` or the factory supplied by your transformation context instead. */ + const createJSDocCallbackTag: (tagName: Identifier | undefined, typeExpression: JSDocSignature, fullName?: Identifier | JSDocNamespaceDeclaration | undefined, comment?: string | undefined) => JSDocCallbackTag; + /** @deprecated Use `factory.createJSDocSignature` or the factory supplied by your transformation context instead. */ + const createJSDocSignature: (typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag | undefined) => JSDocSignature; + /** @deprecated Use `factory.createJSDocPropertyTag` or the factory supplied by your transformation context instead. */ + const createJSDocPropertyTag: (tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocPropertyTag; + /** @deprecated Use `factory.createJSDocTypeLiteral` or the factory supplied by your transformation context instead. */ + const createJSDocTypeLiteral: (jsDocPropertyTags?: readonly JSDocPropertyLikeTag[] | undefined, isArrayType?: boolean | undefined) => JSDocTypeLiteral; + /** @deprecated Use `factory.createJSDocImplementsTag` or the factory supplied by your transformation context instead. */ + const createJSDocImplementsTag: (tagName: Identifier | undefined, className: ExpressionWithTypeArguments & { + readonly expression: Identifier | PropertyAccessEntityNameExpression; + }, comment?: string | undefined) => JSDocImplementsTag; + /** @deprecated Use `factory.createJSDocAuthorTag` or the factory supplied by your transformation context instead. */ + const createJSDocAuthorTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocAuthorTag; + /** @deprecated Use `factory.createJSDocPublicTag` or the factory supplied by your transformation context instead. */ + const createJSDocPublicTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocPublicTag; + /** @deprecated Use `factory.createJSDocPrivateTag` or the factory supplied by your transformation context instead. */ + const createJSDocPrivateTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocPrivateTag; + /** @deprecated Use `factory.createJSDocProtectedTag` or the factory supplied by your transformation context instead. */ + const createJSDocProtectedTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocProtectedTag; + /** @deprecated Use `factory.createJSDocReadonlyTag` or the factory supplied by your transformation context instead. */ + const createJSDocReadonlyTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocReadonlyTag; + /** @deprecated Use `factory.createJSDocUnknownTag` or the factory supplied by your transformation context instead. */ + const createJSDocTag: (tagName: Identifier, comment?: string | undefined) => JSDocUnknownTag; + /** @deprecated Use `factory.createJsxElement` or the factory supplied by your transformation context instead. */ + const createJsxElement: (openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) => JsxElement; + /** @deprecated Use `factory.updateJsxElement` or the factory supplied by your transformation context instead. */ + const updateJsxElement: (node: JsxElement, openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) => JsxElement; + /** @deprecated Use `factory.createJsxSelfClosingElement` or the factory supplied by your transformation context instead. */ + const createJsxSelfClosingElement: (tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) => JsxSelfClosingElement; + /** @deprecated Use `factory.updateJsxSelfClosingElement` or the factory supplied by your transformation context instead. */ + const updateJsxSelfClosingElement: (node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) => JsxSelfClosingElement; + /** @deprecated Use `factory.createJsxOpeningElement` or the factory supplied by your transformation context instead. */ + const createJsxOpeningElement: (tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) => JsxOpeningElement; + /** @deprecated Use `factory.updateJsxOpeningElement` or the factory supplied by your transformation context instead. */ + const updateJsxOpeningElement: (node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: readonly TypeNode[] | undefined, attributes: JsxAttributes) => JsxOpeningElement; + /** @deprecated Use `factory.createJsxClosingElement` or the factory supplied by your transformation context instead. */ + const createJsxClosingElement: (tagName: JsxTagNameExpression) => JsxClosingElement; + /** @deprecated Use `factory.updateJsxClosingElement` or the factory supplied by your transformation context instead. */ + const updateJsxClosingElement: (node: JsxClosingElement, tagName: JsxTagNameExpression) => JsxClosingElement; + /** @deprecated Use `factory.createJsxFragment` or the factory supplied by your transformation context instead. */ + const createJsxFragment: (openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) => JsxFragment; + /** @deprecated Use `factory.createJsxText` or the factory supplied by your transformation context instead. */ + const createJsxText: (text: string, containsOnlyTriviaWhiteSpaces?: boolean | undefined) => JsxText; + /** @deprecated Use `factory.updateJsxText` or the factory supplied by your transformation context instead. */ + const updateJsxText: (node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean | undefined) => JsxText; + /** @deprecated Use `factory.createJsxOpeningFragment` or the factory supplied by your transformation context instead. */ + const createJsxOpeningFragment: () => JsxOpeningFragment; + /** @deprecated Use `factory.createJsxJsxClosingFragment` or the factory supplied by your transformation context instead. */ + const createJsxJsxClosingFragment: () => JsxClosingFragment; + /** @deprecated Use `factory.updateJsxFragment` or the factory supplied by your transformation context instead. */ + const updateJsxFragment: (node: JsxFragment, openingFragment: JsxOpeningFragment, children: readonly JsxChild[], closingFragment: JsxClosingFragment) => JsxFragment; + /** @deprecated Use `factory.createJsxAttribute` or the factory supplied by your transformation context instead. */ + const createJsxAttribute: (name: Identifier, initializer: StringLiteral | JsxExpression | undefined) => JsxAttribute; + /** @deprecated Use `factory.updateJsxAttribute` or the factory supplied by your transformation context instead. */ + const updateJsxAttribute: (node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression | undefined) => JsxAttribute; + /** @deprecated Use `factory.createJsxAttributes` or the factory supplied by your transformation context instead. */ + const createJsxAttributes: (properties: readonly JsxAttributeLike[]) => JsxAttributes; + /** @deprecated Use `factory.updateJsxAttributes` or the factory supplied by your transformation context instead. */ + const updateJsxAttributes: (node: JsxAttributes, properties: readonly JsxAttributeLike[]) => JsxAttributes; + /** @deprecated Use `factory.createJsxSpreadAttribute` or the factory supplied by your transformation context instead. */ + const createJsxSpreadAttribute: (expression: Expression) => JsxSpreadAttribute; + /** @deprecated Use `factory.updateJsxSpreadAttribute` or the factory supplied by your transformation context instead. */ + const updateJsxSpreadAttribute: (node: JsxSpreadAttribute, expression: Expression) => JsxSpreadAttribute; + /** @deprecated Use `factory.createJsxExpression` or the factory supplied by your transformation context instead. */ + const createJsxExpression: (dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) => JsxExpression; + /** @deprecated Use `factory.updateJsxExpression` or the factory supplied by your transformation context instead. */ + const updateJsxExpression: (node: JsxExpression, expression: Expression | undefined) => JsxExpression; + /** @deprecated Use `factory.createCaseClause` or the factory supplied by your transformation context instead. */ + const createCaseClause: (expression: Expression, statements: readonly Statement[]) => CaseClause; + /** @deprecated Use `factory.updateCaseClause` or the factory supplied by your transformation context instead. */ + const updateCaseClause: (node: CaseClause, expression: Expression, statements: readonly Statement[]) => CaseClause; + /** @deprecated Use `factory.createDefaultClause` or the factory supplied by your transformation context instead. */ + const createDefaultClause: (statements: readonly Statement[]) => DefaultClause; + /** @deprecated Use `factory.updateDefaultClause` or the factory supplied by your transformation context instead. */ + const updateDefaultClause: (node: DefaultClause, statements: readonly Statement[]) => DefaultClause; + /** @deprecated Use `factory.createHeritageClause` or the factory supplied by your transformation context instead. */ + const createHeritageClause: (token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword, types: readonly ExpressionWithTypeArguments[]) => HeritageClause; + /** @deprecated Use `factory.updateHeritageClause` or the factory supplied by your transformation context instead. */ + const updateHeritageClause: (node: HeritageClause, types: readonly ExpressionWithTypeArguments[]) => HeritageClause; + /** @deprecated Use `factory.createCatchClause` or the factory supplied by your transformation context instead. */ + const createCatchClause: (variableDeclaration: string | VariableDeclaration | undefined, block: Block) => CatchClause; + /** @deprecated Use `factory.updateCatchClause` or the factory supplied by your transformation context instead. */ + const updateCatchClause: (node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block) => CatchClause; + /** @deprecated Use `factory.createPropertyAssignment` or the factory supplied by your transformation context instead. */ + const createPropertyAssignment: (name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, initializer: Expression) => PropertyAssignment; + /** @deprecated Use `factory.updatePropertyAssignment` or the factory supplied by your transformation context instead. */ + const updatePropertyAssignment: (node: PropertyAssignment, name: PropertyName, initializer: Expression) => PropertyAssignment; + /** @deprecated Use `factory.createShorthandPropertyAssignment` or the factory supplied by your transformation context instead. */ + const createShorthandPropertyAssignment: (name: string | Identifier, objectAssignmentInitializer?: Expression | undefined) => ShorthandPropertyAssignment; + /** @deprecated Use `factory.updateShorthandPropertyAssignment` or the factory supplied by your transformation context instead. */ + const updateShorthandPropertyAssignment: (node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) => ShorthandPropertyAssignment; + /** @deprecated Use `factory.createSpreadAssignment` or the factory supplied by your transformation context instead. */ + const createSpreadAssignment: (expression: Expression) => SpreadAssignment; + /** @deprecated Use `factory.updateSpreadAssignment` or the factory supplied by your transformation context instead. */ + const updateSpreadAssignment: (node: SpreadAssignment, expression: Expression) => SpreadAssignment; + /** @deprecated Use `factory.createEnumMember` or the factory supplied by your transformation context instead. */ + const createEnumMember: (name: string | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier, initializer?: Expression | undefined) => EnumMember; + /** @deprecated Use `factory.updateEnumMember` or the factory supplied by your transformation context instead. */ + const updateEnumMember: (node: EnumMember, name: PropertyName, initializer: Expression | undefined) => EnumMember; + /** @deprecated Use `factory.updateSourceFile` or the factory supplied by your transformation context instead. */ + const updateSourceFileNode: (node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean | undefined, referencedFiles?: readonly FileReference[] | undefined, typeReferences?: readonly FileReference[] | undefined, hasNoDefaultLib?: boolean | undefined, libReferences?: readonly FileReference[] | undefined) => SourceFile; + /** @deprecated Use `factory.createNotEmittedStatement` or the factory supplied by your transformation context instead. */ + const createNotEmittedStatement: (original: Node) => NotEmittedStatement; + /** @deprecated Use `factory.createPartiallyEmittedExpression` or the factory supplied by your transformation context instead. */ + const createPartiallyEmittedExpression: (expression: Expression, original?: Node | undefined) => PartiallyEmittedExpression; + /** @deprecated Use `factory.updatePartiallyEmittedExpression` or the factory supplied by your transformation context instead. */ + const updatePartiallyEmittedExpression: (node: PartiallyEmittedExpression, expression: Expression) => PartiallyEmittedExpression; + /** @deprecated Use `factory.createCommaList` or the factory supplied by your transformation context instead. */ + const createCommaList: (elements: readonly Expression[]) => CommaListExpression; + /** @deprecated Use `factory.updateCommaList` or the factory supplied by your transformation context instead. */ + const updateCommaList: (node: CommaListExpression, elements: readonly Expression[]) => CommaListExpression; + /** @deprecated Use `factory.createBundle` or the factory supplied by your transformation context instead. */ + const createBundle: (sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[] | undefined) => Bundle; + /** @deprecated Use `factory.updateBundle` or the factory supplied by your transformation context instead. */ + const updateBundle: (node: Bundle, sourceFiles: readonly SourceFile[], prepends?: readonly (UnparsedSource | InputFiles)[] | undefined) => Bundle; + /** @deprecated Use `factory.createImmediatelyInvokedFunctionExpression` or the factory supplied by your transformation context instead. */ + const createImmediatelyInvokedFunctionExpression: { + (statements: readonly Statement[]): CallExpression; + (statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + }; + /** @deprecated Use `factory.createImmediatelyInvokedArrowFunction` or the factory supplied by your transformation context instead. */ + const createImmediatelyInvokedArrowFunction: { + (statements: readonly Statement[]): CallExpression; + (statements: readonly Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression; + }; + /** @deprecated Use `factory.createVoidZero` or the factory supplied by your transformation context instead. */ + const createVoidZero: () => VoidExpression; + /** @deprecated Use `factory.createExportDefault` or the factory supplied by your transformation context instead. */ + const createExportDefault: (expression: Expression) => ExportAssignment; + /** @deprecated Use `factory.createExternalModuleExport` or the factory supplied by your transformation context instead. */ + const createExternalModuleExport: (exportName: Identifier) => ExportDeclaration; + /** @deprecated Use `factory.createNamespaceExport` or the factory supplied by your transformation context instead. */ + const createNamespaceExport: (name: Identifier) => NamespaceExport; + /** @deprecated Use `factory.updateNamespaceExport` or the factory supplied by your transformation context instead. */ + const updateNamespaceExport: (node: NamespaceExport, name: Identifier) => NamespaceExport; + /** @deprecated Use `factory.createToken` or the factory supplied by your transformation context instead. */ + const createToken: (kind: TKind) => Token; + /** @deprecated Use `factory.createIdentifier` or the factory supplied by your transformation context instead. */ + const createIdentifier: (text: string) => Identifier; + /** @deprecated Use `factory.createTempVariable` or the factory supplied by your transformation context instead. */ + const createTempVariable: (recordTempVariable: ((node: Identifier) => void) | undefined) => Identifier; + /** @deprecated Use `factory.getGeneratedNameForNode` or the factory supplied by your transformation context instead. */ + const getGeneratedNameForNode: (node: Node | undefined) => Identifier; + /** @deprecated Use `factory.createUniqueName(text, GeneratedIdentifierFlags.Optimistic)` or the factory supplied by your transformation context instead. */ + const createOptimisticUniqueName: (text: string) => Identifier; + /** @deprecated Use `factory.createUniqueName(text, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)` or the factory supplied by your transformation context instead. */ + const createFileLevelUniqueName: (text: string) => Identifier; + /** @deprecated Use `factory.createIndexSignature` or the factory supplied by your transformation context instead. */ + const createIndexSignature: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => IndexSignatureDeclaration; + /** @deprecated Use `factory.createTypePredicateNode` or the factory supplied by your transformation context instead. */ + const createTypePredicateNode: (parameterName: Identifier | ThisTypeNode | string, type: TypeNode) => TypePredicateNode; + /** @deprecated Use `factory.updateTypePredicateNode` or the factory supplied by your transformation context instead. */ + const updateTypePredicateNode: (node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) => TypePredicateNode; + /** @deprecated Use `factory.createStringLiteral`, `factory.createStringLiteralFromNode`, `factory.createNumericLiteral`, `factory.createBigIntLiteral`, `factory.createTrue`, `factory.createFalse`, or the factory supplied by your transformation context instead. */ + const createLiteral: { + (value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; + (value: number | PseudoBigInt): NumericLiteral; + (value: boolean): BooleanLiteral; + (value: string | number | PseudoBigInt | boolean): PrimaryExpression; + }; + /** @deprecated Use `factory.createMethodSignature` or the factory supplied by your transformation context instead. */ + const createMethodSignature: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined) => MethodSignature; + /** @deprecated Use `factory.updateMethodSignature` or the factory supplied by your transformation context instead. */ + const updateMethodSignature: (node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined) => MethodSignature; + /** @deprecated Use `factory.createTypeOperatorNode` or the factory supplied by your transformation context instead. */ + const createTypeOperatorNode: { + (type: TypeNode): TypeOperatorNode; + (operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode; + }; + /** @deprecated Use `factory.createTaggedTemplate` or the factory supplied by your transformation context instead. */ + const createTaggedTemplate: { + (tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + (tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + }; + /** @deprecated Use `factory.updateTaggedTemplate` or the factory supplied by your transformation context instead. */ + const updateTaggedTemplate: { + (node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + (node: TaggedTemplateExpression, tag: Expression, typeArguments: readonly TypeNode[] | undefined, template: TemplateLiteral): TaggedTemplateExpression; + }; + /** @deprecated Use `factory.updateBinary` or the factory supplied by your transformation context instead. */ + const updateBinary: (node: BinaryExpression, left: Expression, right: Expression, operator?: BinaryOperator | BinaryOperatorToken) => BinaryExpression; + /** @deprecated Use `factory.createConditional` or the factory supplied by your transformation context instead. */ + const createConditional: { + (condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression; + (condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression; + }; + /** @deprecated Use `factory.createYield` or the factory supplied by your transformation context instead. */ + const createYield: { + (expression?: Expression | undefined): YieldExpression; + (asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; + }; + /** @deprecated Use `factory.createClassExpression` or the factory supplied by your transformation context instead. */ + const createClassExpression: (modifiers: readonly Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]) => ClassExpression; + /** @deprecated Use `factory.updateClassExpression` or the factory supplied by your transformation context instead. */ + const updateClassExpression: (node: ClassExpression, modifiers: readonly Modifier[] | undefined, name: Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, heritageClauses: readonly HeritageClause[] | undefined, members: readonly ClassElement[]) => ClassExpression; + /** @deprecated Use `factory.createPropertySignature` or the factory supplied by your transformation context instead. */ + const createPropertySignature: (modifiers: readonly Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer?: Expression | undefined) => PropertySignature; + /** @deprecated Use `factory.updatePropertySignature` or the factory supplied by your transformation context instead. */ + const updatePropertySignature: (node: PropertySignature, modifiers: readonly Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) => PropertySignature; + /** @deprecated Use `factory.createExpressionWithTypeArguments` or the factory supplied by your transformation context instead. */ + const createExpressionWithTypeArguments: (typeArguments: readonly TypeNode[] | undefined, expression: Expression) => ExpressionWithTypeArguments; + /** @deprecated Use `factory.updateExpressionWithTypeArguments` or the factory supplied by your transformation context instead. */ + const updateExpressionWithTypeArguments: (node: ExpressionWithTypeArguments, typeArguments: readonly TypeNode[] | undefined, expression: Expression) => ExpressionWithTypeArguments; + /** @deprecated Use `factory.createArrowFunction` or the factory supplied by your transformation context instead. */ + const createArrowFunction: { + (modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction; + (modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + }; + /** @deprecated Use `factory.updateArrowFunction` or the factory supplied by your transformation context instead. */ + const updateArrowFunction: { + (node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody): ArrowFunction; + (node: ArrowFunction, modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody): ArrowFunction; + }; + /** @deprecated Use `factory.createVariableDeclaration` or the factory supplied by your transformation context instead. */ + const createVariableDeclaration: { + (name: string | BindingName, type?: TypeNode | undefined, initializer?: Expression | undefined): VariableDeclaration; + (name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + }; + /** @deprecated Use `factory.updateVariableDeclaration` or the factory supplied by your transformation context instead. */ + const updateVariableDeclaration: { + (node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + (node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration; + }; + /** @deprecated Use `factory.createImportClause` or the factory supplied by your transformation context instead. */ + const createImportClause: (name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly?: any) => ImportClause; + /** @deprecated Use `factory.updateImportClause` or the factory supplied by your transformation context instead. */ + const updateImportClause: (node: ImportClause, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, isTypeOnly: boolean) => ImportClause; + /** @deprecated Use `factory.createExportDeclaration` or the factory supplied by your transformation context instead. */ + const createExportDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression | undefined, isTypeOnly?: any) => ExportDeclaration; + /** @deprecated Use `factory.updateExportDeclaration` or the factory supplied by your transformation context instead. */ + const updateExportDeclaration: (node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined, isTypeOnly: boolean) => ExportDeclaration; + /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ + const createJSDocParamTag: (name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocParameterTag; + /** @deprecated Use `factory.createComma` or the factory supplied by your transformation context instead. */ + const createComma: (left: Expression, right: Expression) => Expression; + /** @deprecated Use `factory.createLessThan` or the factory supplied by your transformation context instead. */ + const createLessThan: (left: Expression, right: Expression) => Expression; + /** @deprecated Use `factory.createAssignment` or the factory supplied by your transformation context instead. */ + const createAssignment: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createStrictEquality` or the factory supplied by your transformation context instead. */ + const createStrictEquality: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createStrictInequality` or the factory supplied by your transformation context instead. */ + const createStrictInequality: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createAdd` or the factory supplied by your transformation context instead. */ + const createAdd: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createSubtract` or the factory supplied by your transformation context instead. */ + const createSubtract: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createLogicalAnd` or the factory supplied by your transformation context instead. */ + const createLogicalAnd: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createLogicalOr` or the factory supplied by your transformation context instead. */ + const createLogicalOr: (left: Expression, right: Expression) => BinaryExpression; + /** @deprecated Use `factory.createPostfixIncrement` or the factory supplied by your transformation context instead. */ + const createPostfixIncrement: (operand: Expression) => PostfixUnaryExpression; + /** @deprecated Use `factory.createLogicalNot` or the factory supplied by your transformation context instead. */ + const createLogicalNot: (operand: Expression) => PrefixUnaryExpression; + /** @deprecated Use an appropriate `factory` method instead. */ + const createNode: (kind: SyntaxKind, pos?: any, end?: any) => Node; + /** + * Creates a shallow, memberwise clone of a node ~for mutation~ with its `pos`, `end`, and `parent` set. + * + * NOTE: It is unsafe to change any properties of a `Node` that relate to its AST children, as those changes won't be + * captured with respect to transformations. + * + * @deprecated Use `factory.cloneNode` instead and use `setCommentRange` or `setSourceMapRange` and avoid setting `parent`. + */ + const getMutableClone: (node: T) => T; + /** @deprecated Use `isTypeAssertionExpression` instead. */ + const isTypeAssertion: (node: Node) => node is TypeAssertion; +} export = ts; \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts index 3518b017050ee..7118f38b1bad8 100644 --- a/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts @@ -1,5 +1,7 @@ /// +// @target: esnext + ////const f: () => number | string = () => { //// await Promise.resolve('foo'); ////} diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts index 1cfce8eda2e39..0b3b80a402d69 100644 --- a/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts @@ -6,7 +6,7 @@ // should not change type if it's incorrectly set verify.codeFix({ - index: 2, + index: 0, description: "Add async modifier to containing function", newFileContent: `const f: string = async () => { diff --git a/tests/cases/fourslash/codeFixCorrectReturnValue27.ts b/tests/cases/fourslash/codeFixCorrectReturnValue27.ts new file mode 100644 index 0000000000000..51011310208a4 --- /dev/null +++ b/tests/cases/fourslash/codeFixCorrectReturnValue27.ts @@ -0,0 +1,5 @@ +/// + +//// const a: ((() => number) | (() => undefined)) = () => { "" } + +verify.not.codeFixAvailable();