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(); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy