From e65a6ed7a9a5cd8c043891e78c51aff56fc03600 Mon Sep 17 00:00:00 2001 From: jasonreyes9 Date: Sat, 24 Oct 2020 15:25:15 +1300 Subject: [PATCH] Use NodeFactory to create and update nodes Most ts.create* and ts.update* functions are deprecated as of TypeScript 4.0. The current plan is to emit noiser and noisier warnings with each version until the deprecated functions are removed in 4.3. See this pull request for more details: https://github.com/microsoft/TypeScript/pull/35282 Some method signatures and names have changed slightly. The easy way to update is to use the global ts.factory object. TypeScript transformations also have access to a NodeFactory in their transformation contexts. Note that we still use the deprecate getMutableClone function because its replacement is not included in the TypeScript declarations. See https://github.com/microsoft/TypeScript/issues/40507 --- .../src/example-plugin-ts.ts | 8 +- .../src/plugins/hoist-class-statics.ts | 23 +++-- .../ts-migrate-plugins/src/plugins/jsdoc.ts | 62 +++++++------ .../src/plugins/member-accessibility.ts | 5 +- .../plugins/react-class-lifecycle-methods.ts | 19 ++-- .../src/plugins/react-class-state.ts | 18 ++-- .../src/plugins/react-default-props.ts | 44 +++++---- .../src/plugins/react-props.ts | 28 +++--- .../src/plugins/react-shape.ts | 47 ++++++---- .../src/plugins/utils/imports.ts | 67 ++++++++------ .../src/plugins/utils/react-props.ts | 91 ++++++++++--------- 11 files changed, 227 insertions(+), 185 deletions(-) diff --git a/packages/ts-migrate-example/src/example-plugin-ts.ts b/packages/ts-migrate-example/src/example-plugin-ts.ts index e86656c..a07db83 100644 --- a/packages/ts-migrate-example/src/example-plugin-ts.ts +++ b/packages/ts-migrate-example/src/example-plugin-ts.ts @@ -29,24 +29,24 @@ const examplePluginTs: Plugin = { if (options.shouldReplaceText && hasTwoParams && multiplierReturn) { // create a new function declaration with a new type - const newFunctionDeclaration = ts.createFunctionDeclaration( + const newFunctionDeclaration = ts.factory.createFunctionDeclaration( functionDeclaration.decorators, functionDeclaration.modifiers, functionDeclaration.asteriskToken, functionDeclaration.name, functionDeclaration.typeParameters, functionDeclaration.parameters.map((x) => - ts.createParameter( + ts.factory.createParameterDeclaration( x.decorators, x.modifiers, x.dotDotDotToken, x.name, x.questionToken, - ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), x.initializer, ), ), - ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), functionDeclaration.body, ); diff --git a/packages/ts-migrate-plugins/src/plugins/hoist-class-statics.ts b/packages/ts-migrate-plugins/src/plugins/hoist-class-statics.ts index ba40d20..4199515 100644 --- a/packages/ts-migrate-plugins/src/plugins/hoist-class-statics.ts +++ b/packages/ts-migrate-plugins/src/plugins/hoist-class-statics.ts @@ -15,8 +15,8 @@ type Options = { const hoistClassStaticsPlugin: Plugin = { name: 'hoist-class-statics', - run({ fileName, text, options }) { - return hoistStaticClassProperties(fileName, text, options); + run({ sourceFile, text, options }) { + return hoistStaticClassProperties(sourceFile, text, options); }, }; @@ -90,11 +90,10 @@ function isAlreadyHoisted( } function hoistStaticClassProperties( - fileName: string, + sourceFile: ts.SourceFile, sourceText: string, options: Options, ): string { - const sourceFile = ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest, true); const printer = ts.createPrinter(); const updates: SourceTextUpdate[] = []; @@ -126,9 +125,9 @@ function hoistStaticClassProperties( canHoistExpression(statement.expression.right, classDeclaration.pos, knownDefinitions) ) { properties.push( - ts.createProperty( + ts.factory.createPropertyDeclaration( undefined, - [ts.createModifier(ts.SyntaxKind.StaticKeyword)], + [ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)], statement.expression.left.name.text, undefined, undefined, @@ -143,14 +142,14 @@ function hoistStaticClassProperties( } else { // otherwise add a static type annotation for this expression properties.push( - ts.createProperty( + ts.factory.createPropertyDeclaration( undefined, - [ts.createModifier(ts.SyntaxKind.StaticKeyword)], + [ts.factory.createModifier(ts.SyntaxKind.StaticKeyword)], statement.expression.left.name.text, undefined, options.anyAlias != null - ? ts.createTypeReferenceNode(options.anyAlias, undefined) - : ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), + ? ts.factory.createTypeReferenceNode(options.anyAlias, undefined) + : ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), undefined, ), ); @@ -160,14 +159,14 @@ function hoistStaticClassProperties( if (properties.length > 0) { if (classDeclaration.members.length === 0) { - const updatedClassDeclaration = ts.updateClassDeclaration( + const updatedClassDeclaration = ts.factory.updateClassDeclaration( classDeclaration, classDeclaration.decorators, classDeclaration.modifiers, classDeclaration.name, classDeclaration.typeParameters, classDeclaration.heritageClauses, - ts.createNodeArray(properties), + ts.factory.createNodeArray(properties), ); let index = classDeclaration.pos; diff --git a/packages/ts-migrate-plugins/src/plugins/jsdoc.ts b/packages/ts-migrate-plugins/src/plugins/jsdoc.ts index c58bfd5..15fcdb8 100644 --- a/packages/ts-migrate-plugins/src/plugins/jsdoc.ts +++ b/packages/ts-migrate-plugins/src/plugins/jsdoc.ts @@ -63,9 +63,10 @@ const jsDocTransformerFactory = ({ anyAlias, typeMap: optionsTypeMap, }: Options) => (context: ts.TransformationContext) => { + const { factory } = context; const anyType = anyAlias - ? ts.createTypeReferenceNode(anyAlias, undefined) - : ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + ? factory.createTypeReferenceNode(anyAlias, undefined) + : factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); const typeMap: TypeMap = { ...defaultTypeMap, ...optionsTypeMap }; function visit(origNode: T): T { @@ -78,7 +79,9 @@ const jsDocTransformerFactory = ({ function visitFunctionLike(node: T, insideClass: boolean): T { const modifiers = - ts.isMethodDeclaration(node) && insideClass ? modifiersFromJSDoc(node) : node.modifiers; + ts.isMethodDeclaration(node) && insideClass + ? modifiersFromJSDoc(node, factory) + : node.modifiers; const parameters = visitParameters(node); const returnType = annotateReturns ? visitReturnType(node) : node.type; if ( @@ -90,8 +93,8 @@ const jsDocTransformerFactory = ({ } const newNode = ts.getMutableClone(node) as any; - newNode.modifiers = ts.createNodeArray(modifiers); - newNode.parameters = ts.createNodeArray(parameters); + newNode.modifiers = factory.createNodeArray(modifiers); + newNode.parameters = factory.createNodeArray(parameters); newNode.type = returnType; return newNode; } @@ -121,10 +124,10 @@ const jsDocTransformerFactory = ({ !param.initializer && ts.isIdentifier(param.name) && (paramNode.isBracketed || ts.isJSDocOptionalType(typeNode)) - ? ts.createToken(ts.SyntaxKind.QuestionToken) + ? factory.createToken(ts.SyntaxKind.QuestionToken) : param.questionToken; - const newParam = ts.createParameter( + const newParam = factory.createParameterDeclaration( param.decorators, param.modifiers, param.dotDotDotToken, @@ -192,25 +195,25 @@ const jsDocTransformerFactory = ({ } function visitJSDocOptionalType(node: ts.JSDocOptionalType) { - return ts.createUnionTypeNode([ + return factory.createUnionTypeNode([ ts.visitNode(node.type, visitJSDocType), - ts.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword), + factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword), ]); } function visitJSDocNullableType(node: ts.JSDocNullableType) { - return ts.createUnionTypeNode([ + return factory.createUnionTypeNode([ ts.visitNode(node.type, visitJSDocType), - ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword as any), + factory.createKeywordTypeNode(ts.SyntaxKind.NullKeyword as any), ]); } function visitJSDocVariadicType(node: ts.JSDocVariadicType) { - return ts.createArrayTypeNode(ts.visitNode(node.type, visitJSDocType)); + return factory.createArrayTypeNode(ts.visitNode(node.type, visitJSDocType)); } function visitJSDocFunctionType(node: ts.JSDocFunctionType) { - return ts.createFunctionTypeNode( + return factory.createFunctionTypeNode( undefined, node.parameters.map(visitJSDocParameter), node.type ?? anyType, @@ -227,7 +230,7 @@ const jsDocTransformerFactory = ({ } }); } - return ts.createTypeLiteralNode(propertySignatures); + return factory.createTypeLiteralNode(propertySignatures); } function visitJSDocPropertyLikeTag(node: ts.JSDocPropertyLikeTag) { @@ -240,12 +243,14 @@ const jsDocTransformerFactory = ({ type = anyType; } const questionToken = - node.isBracketed || optionalType ? ts.createToken(ts.SyntaxKind.QuestionToken) : undefined; + node.isBracketed || optionalType + ? factory.createToken(ts.SyntaxKind.QuestionToken) + : undefined; if (ts.isIdentifier(node.name)) { - return ts.createPropertySignature(undefined, node.name, questionToken, type, undefined); + return factory.createPropertySignature(undefined, node.name, questionToken, type); } // Assumption: the leaf field on the QualifiedName belongs directly to the parent object type. - return ts.createPropertySignature(undefined, node.name.right, questionToken, type, undefined); + return factory.createPropertySignature(undefined, node.name.right, questionToken, type); } function visitJSDocParameter(node: ts.ParameterDeclaration) { @@ -257,8 +262,10 @@ const jsDocTransformerFactory = ({ node.type.kind === ts.SyntaxKind.JSDocVariadicType && index === node.parent.parameters.length - 1; const name = node.name || (isRest ? 'rest' : `arg${index}`); - const dotdotdot = isRest ? ts.createToken(ts.SyntaxKind.DotDotDotToken) : node.dotDotDotToken; - return ts.createParameter( + const dotdotdot = isRest + ? factory.createToken(ts.SyntaxKind.DotDotDotToken) + : node.dotDotDotToken; + return factory.createParameterDeclaration( node.decorators, node.modifiers, dotdotdot, @@ -290,9 +297,9 @@ const jsDocTransformerFactory = ({ } } - name = ts.createIdentifier(text); + name = factory.createIdentifier(text); if ((text === 'Array' || text === 'Promise') && !node.typeArguments) { - args = ts.createNodeArray([anyType]); + args = factory.createNodeArray([anyType]); } else if (acceptsTypeParameters) { args = ts.visitNodes(node.typeArguments, visitJSDocType); } @@ -300,25 +307,25 @@ const jsDocTransformerFactory = ({ args = undefined; } } - return ts.createTypeReferenceNode(name, args); + return factory.createTypeReferenceNode(name, args); } function visitJSDocIndexSignature(node: ts.TypeReferenceNode) { const typeArguments = node.typeArguments!; - const index = ts.createParameter( + const index = factory.createParameterDeclaration( /* decorators */ undefined, /* modifiers */ undefined, /* dotDotDotToken */ undefined, typeArguments[0].kind === ts.SyntaxKind.NumberKeyword ? 'n' : 's', /* questionToken */ undefined, - ts.createTypeReferenceNode( + factory.createTypeReferenceNode( typeArguments[0].kind === ts.SyntaxKind.NumberKeyword ? 'number' : 'string', [], ), /* initializer */ undefined, ); - const indexSignature = ts.createTypeLiteralNode([ - ts.createIndexSignature( + const indexSignature = factory.createTypeLiteralNode([ + factory.createIndexSignature( /* decorators */ undefined, /* modifiers */ undefined, [index], @@ -337,6 +344,7 @@ const accessibilityMask = function modifiersFromJSDoc( methodDeclaration: ts.MethodDeclaration, + factory: ts.NodeFactory, ): ReadonlyArray | undefined { let modifierFlags = ts.getCombinedModifierFlags(methodDeclaration); if ((modifierFlags & accessibilityMask) !== 0) { @@ -354,7 +362,7 @@ function modifiersFromJSDoc( return methodDeclaration.modifiers; } - return ts.createModifiersFromModifierFlags(modifierFlags); + return factory.createModifiersFromModifierFlags(modifierFlags); } // Copied from: https://github.com/microsoft/TypeScript/blob/v4.0.2/src/compiler/utilities.ts#L1879 diff --git a/packages/ts-migrate-plugins/src/plugins/member-accessibility.ts b/packages/ts-migrate-plugins/src/plugins/member-accessibility.ts index df3ffc6..8c6dbce 100644 --- a/packages/ts-migrate-plugins/src/plugins/member-accessibility.ts +++ b/packages/ts-migrate-plugins/src/plugins/member-accessibility.ts @@ -32,6 +32,7 @@ const accessibilityMask = const memberAccessibilityTransformerFactory = (options: Options) => ( context: ts.TransformationContext, ) => { + const { factory } = context; let defaultAccessibility: ts.ModifierFlags; switch (options.defaultAccessibility) { case 'private': @@ -77,8 +78,8 @@ const memberAccessibilityTransformerFactory = (options: Options) => ( } const newNode = ts.getMutableClone(node) as any; - newNode.modifiers = ts.createNodeArray( - ts.createModifiersFromModifierFlags(modifierFlags | accessibilityFlag), + newNode.modifiers = factory.createNodeArray( + factory.createModifiersFromModifierFlags(modifierFlags | accessibilityFlag), ); return newNode; } diff --git a/packages/ts-migrate-plugins/src/plugins/react-class-lifecycle-methods.ts b/packages/ts-migrate-plugins/src/plugins/react-class-lifecycle-methods.ts index 82bb3ad..cbeb011 100644 --- a/packages/ts-migrate-plugins/src/plugins/react-class-lifecycle-methods.ts +++ b/packages/ts-migrate-plugins/src/plugins/react-class-lifecycle-methods.ts @@ -7,9 +7,9 @@ type Options = { force?: boolean }; const reactClassLifecycleMethodsPlugin: Plugin = { name: 'react-class-lifecycle-methods', - run({ fileName, text, options }) { + run({ fileName, sourceFile, text, options }) { return /\.tsx$/.test(fileName) - ? annotateReactComponentLifecycleMethods(fileName, text, options.force) + ? annotateReactComponentLifecycleMethods(sourceFile, text, options.force) : undefined; }, }; @@ -37,7 +37,7 @@ const reactLifecycleMethodAnnotations: { [method: string]: AnnotationKind[] } = }; function updateParameterType(parameter: ts.ParameterDeclaration, type: ts.TypeNode | undefined) { - return ts.updateParameter( + return ts.factory.updateParameterDeclaration( parameter, parameter.decorators, parameter.modifiers, @@ -50,11 +50,10 @@ function updateParameterType(parameter: ts.ParameterDeclaration, type: ts.TypeNo } function annotateReactComponentLifecycleMethods( - fileName: string, + sourceFile: ts.SourceFile, sourceText: string, force = false, ) { - const sourceFile = ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest, true); const printer = ts.createPrinter(); const updates: SourceTextUpdate[] = []; @@ -62,12 +61,14 @@ function annotateReactComponentLifecycleMethods( if (ts.isClassDeclaration(statement) && isReactClassComponent(statement)) { const heritageType = getReactComponentHeritageType(statement)!; const heritageTypeArgs = heritageType.typeArguments || []; - const propsType = heritageTypeArgs[0] || ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); - const stateType = heritageTypeArgs[1] || ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + const propsType = + heritageTypeArgs[0] || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + const stateType = + heritageTypeArgs[1] || ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); const annotationToType = { [AnnotationKind.Props]: propsType, [AnnotationKind.State]: stateType, - [AnnotationKind.Context]: ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), + [AnnotationKind.Context]: ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), }; statement.members.forEach((member) => { @@ -110,7 +111,7 @@ function annotateReactComponentLifecycleMethods( let text = printer.printList( ts.ListFormat.Parameters, - ts.createNodeArray(parametersToPrint), + ts.factory.createNodeArray(parametersToPrint), sourceFile, ); // Remove surrounding parentheses diff --git a/packages/ts-migrate-plugins/src/plugins/react-class-state.ts b/packages/ts-migrate-plugins/src/plugins/react-class-state.ts index 787837b..c02db86 100644 --- a/packages/ts-migrate-plugins/src/plugins/react-class-state.ts +++ b/packages/ts-migrate-plugins/src/plugins/react-class-state.ts @@ -59,9 +59,9 @@ const reactClassStatePlugin: Plugin = { const stateTypeName = getStateTypeName(); const anyType = options.anyAlias != null - ? ts.createTypeReferenceNode(options.anyAlias, undefined) - : ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); - const newStateType = ts.createTypeAliasDeclaration( + ? ts.factory.createTypeReferenceNode(options.anyAlias, undefined) + : ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + const newStateType = ts.factory.createTypeAliasDeclaration( undefined, undefined, stateTypeName, @@ -81,14 +81,10 @@ const reactClassStatePlugin: Plugin = { length: heritageType.end - heritageType.pos, text: ` ${printer.printNode( ts.EmitHint.Unspecified, - ts.updateExpressionWithTypeArguments( - heritageType, - [ - propsType || ts.createTypeLiteralNode([]), - ts.createTypeReferenceNode(stateTypeName, undefined), - ], - heritageType.expression, - ), + ts.factory.updateExpressionWithTypeArguments(heritageType, heritageType.expression, [ + propsType || ts.factory.createTypeLiteralNode([]), + ts.factory.createTypeReferenceNode(stateTypeName, undefined), + ]), sourceFile, )}`, }); diff --git a/packages/ts-migrate-plugins/src/plugins/react-default-props.ts b/packages/ts-migrate-plugins/src/plugins/react-default-props.ts index 6af1d54..5551a5c 100644 --- a/packages/ts-migrate-plugins/src/plugins/react-default-props.ts +++ b/packages/ts-migrate-plugins/src/plugins/react-default-props.ts @@ -102,9 +102,9 @@ const reactDefaultPropsPlugin: Plugin = { ts.isIntersectionTypeNode(propsTypeAliasDeclaration.type) && indexOfTypeValue === -1; const propsTypeValueNode = ts.isIntersectionTypeNode(propsTypeAliasDeclaration.type) - ? ts.updateIntersectionTypeNode( + ? ts.factory.updateIntersectionTypeNode( propsTypeAliasDeclaration.type, - ts.createNodeArray( + ts.factory.createNodeArray( propsTypeAliasDeclaration.type.types.filter( (_, k) => propTypesAreOnlyReferences || indexOfTypeValue === k, ), @@ -120,11 +120,11 @@ const reactDefaultPropsPlugin: Plugin = { // rename type PropName -> type OwnPropName const updatedPropTypesName = doesPropsTypeHaveExport ? propsTypeName : `Own${propsTypeName}`; - const updatedPropTypeAlias = ts.updateTypeAliasDeclaration( + const updatedPropTypeAlias = ts.factory.updateTypeAliasDeclaration( propsTypeAliasDeclaration, propsTypeAliasDeclaration.decorators, propsTypeAliasDeclaration.modifiers, - ts.createIdentifier(updatedPropTypesName), + ts.factory.createIdentifier(updatedPropTypesName), propsTypeAliasDeclaration.typeParameters, propsTypeValueNode, ); @@ -136,26 +136,26 @@ const reactDefaultPropsPlugin: Plugin = { // create type Props = WithDefaultProps & types; const newPropsTypeValue = options.useDefaultPropsHelper - ? ts.createTypeReferenceNode(WITH_DEFAULT_PROPS_HELPER, [ - ts.createTypeReferenceNode(updatedPropTypesName, undefined), - ts.createTypeQueryNode(ts.createIdentifier(defaultPropsTypeName)), + ? ts.factory.createTypeReferenceNode(WITH_DEFAULT_PROPS_HELPER, [ + ts.factory.createTypeReferenceNode(updatedPropTypesName, undefined), + ts.factory.createTypeQueryNode(ts.factory.createIdentifier(defaultPropsTypeName)), ]) - : ts.createIntersectionTypeNode([ - ts.createTypeReferenceNode(updatedPropTypesName, undefined), - ts.createTypeQueryNode(ts.createIdentifier(defaultPropsTypeName)), + : ts.factory.createIntersectionTypeNode([ + ts.factory.createTypeReferenceNode(updatedPropTypesName, undefined), + ts.factory.createTypeQueryNode(ts.factory.createIdentifier(defaultPropsTypeName)), ]); const componentPropsTypeName = doesPropsTypeHaveExport ? `Private${propsTypeName}` : propsTypeName; - const newPropsTypeAlias = ts.createTypeAliasDeclaration( + const newPropsTypeAlias = ts.factory.createTypeAliasDeclaration( undefined, undefined, - ts.createIdentifier(componentPropsTypeName), + ts.factory.createIdentifier(componentPropsTypeName), undefined, ts.isIntersectionTypeNode(propsTypeAliasDeclaration.type) - ? ts.createIntersectionTypeNode([ + ? ts.factory.createIntersectionTypeNode([ newPropsTypeValue, ...propsTypeAliasDeclaration.type.types.filter((el, k) => propTypesAreOnlyReferences @@ -175,9 +175,9 @@ const reactDefaultPropsPlugin: Plugin = { // we should rename component prop type in that case if (doesPropsTypeHaveExport) { - const updatedComponentTypeReference = ts.updateTypeReferenceNode( + const updatedComponentTypeReference = ts.factory.updateTypeReferenceNode( componentTypeReference, - ts.createIdentifier(componentPropsTypeName), + ts.factory.createIdentifier(componentPropsTypeName), undefined, ); @@ -333,16 +333,20 @@ const reactDefaultPropsPlugin: Plugin = { // the target project might not have this as an internal dependency in project.json // It would have to be manually added, otherwise CI will complain about it function getWithDefaultPropsImport() { - return ts.createImportDeclaration( + return ts.factory.createImportDeclaration( undefined, undefined, - ts.createImportClause( + ts.factory.createImportClause( + false, undefined, - ts.createNamedImports([ - ts.createImportSpecifier(undefined, ts.createIdentifier('WithDefaultProps')), + ts.factory.createNamedImports([ + ts.factory.createImportSpecifier( + undefined, + ts.factory.createIdentifier('WithDefaultProps'), + ), ]), ), - ts.createStringLiteral(':ts-utils/types/WithDefaultProps'), + ts.factory.createStringLiteral(':ts-utils/types/WithDefaultProps'), ); } diff --git a/packages/ts-migrate-plugins/src/plugins/react-props.ts b/packages/ts-migrate-plugins/src/plugins/react-props.ts index d6b5b69..6874a17 100644 --- a/packages/ts-migrate-plugins/src/plugins/react-props.ts +++ b/packages/ts-migrate-plugins/src/plugins/react-props.ts @@ -96,7 +96,7 @@ const spreadReplacements: SpreadReplacement[] = [ namedImport: 'withStylesPropTypes', moduleSpecifier: ':dls-themes/withStyles', }, - typeRef: ts.createTypeReferenceNode('WithStylesProps', undefined), + typeRef: ts.factory.createTypeReferenceNode('WithStylesProps', undefined), typeImport: { namedImport: 'WithStylesProps', moduleSpecifier: ':dls-themes/withStyles', @@ -108,7 +108,7 @@ const spreadReplacements: SpreadReplacement[] = [ namedImport: 'withBreakpointPropTypes', moduleSpecifier: ':dls-core/components/breakpoints/withBreakpoint', }, - typeRef: ts.createTypeReferenceNode('WithBreakpointProps', undefined), + typeRef: ts.factory.createTypeReferenceNode('WithBreakpointProps', undefined), typeImport: { namedImport: 'WithBreakpointProps', moduleSpecifier: ':dls-core/components/breakpoints/withBreakpoint', @@ -120,8 +120,8 @@ const spreadReplacements: SpreadReplacement[] = [ defaultImport: 'withRouterPropTypes', moduleSpecifier: ':routing/shapes/RR4PropTypes', }, - typeRef: ts.createTypeReferenceNode('RouteConfigComponentProps', [ - ts.createTypeLiteralNode([]), + typeRef: ts.factory.createTypeReferenceNode('RouteConfigComponentProps', [ + ts.factory.createTypeLiteralNode([]), ]), typeImport: { namedImport: 'RouteConfigComponentProps', @@ -181,13 +181,13 @@ function updatePropTypes( length: forwardRefComponent.expression.end - forwardRefComponent.expression.pos, text: ` ${printer.printNode( ts.EmitHint.Unspecified, - ts.updateExpressionWithTypeArguments( + ts.factory.updateExpressionWithTypeArguments( forwardRefComponent as any, + forwardRefComponent.expression, [ - ts.createTypeReferenceNode(options.anyAlias || 'any', undefined), - ts.createTypeReferenceNode(propsTypeName, undefined), + ts.factory.createTypeReferenceNode(options.anyAlias || 'any', undefined), + ts.factory.createTypeReferenceNode(propsTypeName, undefined), ].filter(isNotNull) as any, - forwardRefComponent.expression, ), sourceFile, )}`, @@ -199,14 +199,14 @@ function updatePropTypes( length: propsParam.end - propsParam.pos, text: printer.printNode( ts.EmitHint.Unspecified, - ts.updateParameter( + ts.factory.updateParameterDeclaration( propsParam, propsParam.decorators, propsParam.modifiers, propsParam.dotDotDotToken, propsParam.name, propsParam.questionToken, - ts.createTypeReferenceNode(propsTypeName, undefined), + ts.factory.createTypeReferenceNode(propsTypeName, undefined), propsParam.initializer, ), sourceFile, @@ -235,12 +235,12 @@ function updatePropTypes( length: heritageType.end - heritageType.pos, text: ` ${printer.printNode( ts.EmitHint.Unspecified, - ts.updateExpressionWithTypeArguments( + ts.factory.updateExpressionWithTypeArguments( heritageType, - [ts.createTypeReferenceNode(propsTypeName, undefined), stateType].filter( + heritageType.expression, + [ts.factory.createTypeReferenceNode(propsTypeName, undefined), stateType].filter( isNotNull, ) as any, - heritageType.expression, ), sourceFile, )}`, @@ -277,7 +277,7 @@ function updateObjectLiteral( spreadReplacements, propTypeIdentifiers, }); - let propsTypeAlias = ts.createTypeAliasDeclaration( + let propsTypeAlias = ts.factory.createTypeAliasDeclaration( undefined, undefined, propsTypeName, diff --git a/packages/ts-migrate-plugins/src/plugins/react-shape.ts b/packages/ts-migrate-plugins/src/plugins/react-shape.ts index 4a427a9..97d5dde 100644 --- a/packages/ts-migrate-plugins/src/plugins/react-shape.ts +++ b/packages/ts-migrate-plugins/src/plugins/react-shape.ts @@ -50,13 +50,13 @@ const reactShapePlugin: Plugin = { length: EXPORT_KEYWOARD.length + 1, }); - const newExport = ts.createExportDeclaration( + const newExport = ts.factory.createExportDeclaration( undefined, undefined, - ts.createNamedExports([ - ts.createExportSpecifier(undefined, ts.createIdentifier(shapeName)), + false, + ts.factory.createNamedExports([ + ts.factory.createExportSpecifier(undefined, ts.factory.createIdentifier(shapeName)), ]), - undefined, ); updates.push({ kind: 'insert', @@ -106,9 +106,10 @@ const reactShapePlugin: Plugin = { )}`, }); } - const updatedVariableDeclaration = ts.updateVariableDeclaration( + const updatedVariableDeclaration = ts.factory.updateVariableDeclaration( variableDeclaration, variableDeclaration.name, + undefined, getShapeTypeNode(shapeName), variableDeclaration.initializer, ); @@ -179,10 +180,17 @@ const reactShapePlugin: Plugin = { length: node.end, text: `${ts.sys.newLine}${printer.printNode( ts.EmitHint.Unspecified, - ts.createVariableStatement( + ts.factory.createVariableStatement( [], - ts.createVariableDeclarationList( - [ts.createVariableDeclaration(shapeName, getShapeTypeNode(shapeName), shapeNode)], + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + shapeName, + undefined, + getShapeTypeNode(shapeName), + shapeNode, + ), + ], ts.NodeFlags.Const, ), ), @@ -192,11 +200,11 @@ const reactShapePlugin: Plugin = { const exportShapeExpression = `${ts.sys.newLine}${printer.printNode( ts.EmitHint.Unspecified, - ts.createExportAssignment( + ts.factory.createExportAssignment( undefined, undefined, undefined, - ts.createIdentifier(shapeName), + ts.factory.createIdentifier(shapeName), ), sourceFile, )}`; @@ -228,12 +236,12 @@ function getTypeForTheShape( spreadReplacements: [], }, ); - const propsTypeAlias = ts.createTypeAliasDeclaration( + const propsTypeAlias = ts.factory.createTypeAliasDeclaration( undefined, undefined, shapeName, undefined, - isArrayShapeType ? ts.createArrayTypeNode(shapeTypeVariable) : shapeTypeVariable, + isArrayShapeType ? ts.factory.createArrayTypeNode(shapeTypeVariable) : shapeTypeVariable, ); return ts.moveSyntheticComments(propsTypeAlias, shapeTypeVariable); } @@ -251,19 +259,22 @@ function isPropTypesArrayOfShapes(node: ts.CallExpression) { } function getPropTypesImportNode() { - return ts.createImportDeclaration( + return ts.factory.createImportDeclaration( undefined, undefined, - ts.createImportClause(ts.createIdentifier('PropTypes'), undefined), - ts.createStringLiteral('prop-types'), + ts.factory.createImportClause(false, ts.factory.createIdentifier('PropTypes'), undefined), + ts.factory.createStringLiteral('prop-types'), ); } // @TODO: PropTypes.Requireable doesn't works with react-validators Shapes function getShapeTypeNode(shapeName: string) { - return ts.createTypeReferenceNode( - ts.createQualifiedName(ts.createIdentifier('PropTypes'), ts.createIdentifier('Requireable')), - [ts.createTypeReferenceNode(ts.createIdentifier(shapeName), undefined)], + return ts.factory.createTypeReferenceNode( + ts.factory.createQualifiedName( + ts.factory.createIdentifier('PropTypes'), + ts.factory.createIdentifier('Requireable'), + ), + [ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(shapeName), undefined)], ); } diff --git a/packages/ts-migrate-plugins/src/plugins/utils/imports.ts b/packages/ts-migrate-plugins/src/plugins/utils/imports.ts index df265d4..b8e19ff 100644 --- a/packages/ts-migrate-plugins/src/plugins/utils/imports.ts +++ b/packages/ts-migrate-plugins/src/plugins/utils/imports.ts @@ -63,11 +63,11 @@ export function updateImports( importClause.name && !usedIdentifiers.has(importClause.name.text) ) { - importClause = ts.updateImportClause( + importClause = ts.factory.updateImportClause( importClause, + importClause.isTypeOnly, undefined, importClause.namedBindings, - importClause.isTypeOnly, ); } @@ -83,11 +83,11 @@ export function updateImports( .filter(isModuleSpecifier) .filter(isNotAdded); if (nameToAdd.length > 0 && importClause.name == null) { - importClause = ts.updateImportClause( + importClause = ts.factory.updateImportClause( importClause, - ts.createIdentifier(nameToAdd[0].defaultImport), - importClause.namedBindings, importClause.isTypeOnly, + ts.factory.createIdentifier(nameToAdd[0].defaultImport), + importClause.namedBindings, ); added.add(nameToAdd[0]); } @@ -98,11 +98,11 @@ export function updateImports( ts.isNamespaceImport(importClause.namedBindings) && !usedIdentifiers.has(importClause.namedBindings.name.text) ) { - importClause = ts.updateImportClause( + importClause = ts.factory.updateImportClause( importClause, + importClause.isTypeOnly, importClause.name, undefined, - importClause.isTypeOnly, ); } @@ -129,13 +129,13 @@ export function updateImports( .forEach((cur) => added.add(cur)); if (elements.length !== importClause.namedBindings.elements.length) { - importClause = ts.updateImportClause( + importClause = ts.factory.updateImportClause( importClause, + importClause.isTypeOnly, importClause.name, elements.length > 0 - ? ts.updateNamedImports(importClause.namedBindings, elements) + ? ts.factory.updateNamedImports(importClause.namedBindings, elements) : undefined, - importClause.isTypeOnly, ); } } @@ -145,18 +145,21 @@ export function updateImports( .filter(isModuleSpecifier) .filter(isNotAdded); if (namedToAdd.length > 0) { - importClause = ts.updateImportClause( + importClause = ts.factory.updateImportClause( importClause, + importClause.isTypeOnly, importClause.name, - ts.createNamedImports([ + ts.factory.createNamedImports([ ...(importClause.namedBindings && ts.isNamedImports(importClause.namedBindings) ? importClause.namedBindings.elements : []), ...namedToAdd.map((cur) => - ts.createImportSpecifier(undefined, ts.createIdentifier(cur.namedImport)), + ts.factory.createImportSpecifier( + undefined, + ts.factory.createIdentifier(cur.namedImport), + ), ), ]), - importClause.isTypeOnly, ); namedToAdd.forEach((cur) => added.add(cur)); } @@ -176,7 +179,7 @@ export function updateImports( } if (numImports > 0) { - const upImpDec = ts.updateImportDeclaration( + const upImpDec = ts.factory.updateImportDeclaration( importDeclaration, importDeclaration.decorators, importDeclaration.modifiers, @@ -220,41 +223,51 @@ export function updateImports( const namedImports = namedToAdd.length > 0 - ? ts.createNamedImports( + ? ts.factory.createNamedImports( namedToAdd.map((cur) => - ts.createImportSpecifier(undefined, ts.createIdentifier(cur.namedImport)), + ts.factory.createImportSpecifier( + undefined, + ts.factory.createIdentifier(cur.namedImport), + ), ), ) : undefined; if (nameToAdd.length <= 1) { nodes.push( - ts.createImportDeclaration( + ts.factory.createImportDeclaration( undefined, undefined, - ts.createImportClause( - nameToAdd.length === 1 ? ts.createIdentifier(nameToAdd[0].defaultImport) : undefined, + ts.factory.createImportClause( + false, + nameToAdd.length === 1 + ? ts.factory.createIdentifier(nameToAdd[0].defaultImport) + : undefined, namedImports, ), - ts.createStringLiteral(moduleSpecifier), + ts.factory.createStringLiteral(moduleSpecifier), ), ); } else { nodes.push( - ts.createImportDeclaration( + ts.factory.createImportDeclaration( undefined, undefined, - ts.createImportClause(undefined, namedImports), - ts.createStringLiteral(moduleSpecifier), + ts.factory.createImportClause(false, undefined, namedImports), + ts.factory.createStringLiteral(moduleSpecifier), ), ); nameToAdd.forEach((cur) => { nodes.push( - ts.createImportDeclaration( + ts.factory.createImportDeclaration( undefined, undefined, - ts.createImportClause(ts.createIdentifier(cur.defaultImport), undefined), - ts.createStringLiteral(moduleSpecifier), + ts.factory.createImportClause( + false, + ts.factory.createIdentifier(cur.defaultImport), + undefined, + ), + ts.factory.createStringLiteral(moduleSpecifier), ), ); }); diff --git a/packages/ts-migrate-plugins/src/plugins/utils/react-props.ts b/packages/ts-migrate-plugins/src/plugins/utils/react-props.ts index 0784a9b..1580c4f 100644 --- a/packages/ts-migrate-plugins/src/plugins/utils/react-props.ts +++ b/packages/ts-migrate-plugins/src/plugins/utils/react-props.ts @@ -51,9 +51,11 @@ export default function getTypeFromPropTypesObjectLiteral( } } - let node: ts.TypeLiteralNode | ts.IntersectionTypeNode = ts.createTypeLiteralNode(members); + let node: ts.TypeLiteralNode | ts.IntersectionTypeNode = ts.factory.createTypeLiteralNode( + members, + ); if (intersectionTypes.length > 0) { - node = ts.createIntersectionTypeNode([node, ...intersectionTypes]); + node = ts.factory.createIntersectionTypeNode([node, ...intersectionTypes]); } if (comments.length > 0) { node = ts.addSyntheticLeadingComment( @@ -93,12 +95,11 @@ function convertPropertyAssignment( const typeNode = getTypeFromPropTypeExpression(typeExpression, sourceFile, params); - let propertySignature = ts.createPropertySignature( + let propertySignature = ts.factory.createPropertySignature( undefined, name, - isRequired ? undefined : ts.createToken(ts.SyntaxKind.QuestionToken), + isRequired ? undefined : ts.factory.createToken(ts.SyntaxKind.QuestionToken), typeNode, - undefined, ); propertySignature = ts.moveSyntheticComments(propertySignature, typeNode); return propertySignature; @@ -133,67 +134,75 @@ function getTypeFromPropTypeExpression( * PropTypes.any, */ if (/string/.test(text)) { - result = ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); + result = ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); } else if (/any/.test(text)) { if (anyAlias) { - result = ts.createTypeReferenceNode(anyAlias, undefined); + result = ts.factory.createTypeReferenceNode(anyAlias, undefined); } else { - result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + result = ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } } else if (/array/.test(text)) { if (anyAlias) { - result = ts.createArrayTypeNode(ts.createTypeReferenceNode(anyAlias, undefined)); + result = ts.factory.createArrayTypeNode( + ts.factory.createTypeReferenceNode(anyAlias, undefined), + ); } else { - result = ts.createArrayTypeNode(ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)); + result = ts.factory.createArrayTypeNode( + ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), + ); } } else if (/bool/.test(text)) { - result = ts.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword); + result = ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword); } else if (/number/.test(text)) { - result = ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); + result = ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); } else if (/object/.test(text)) { if (anyAlias) { - result = ts.createTypeReferenceNode(anyAlias, undefined); + result = ts.factory.createTypeReferenceNode(anyAlias, undefined); } else { - result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + result = ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } } else if (/node/.test(text)) { - result = ts.createTypeReferenceNode('React.ReactNode', undefined); + result = ts.factory.createTypeReferenceNode('React.ReactNode', undefined); } else if (/element/.test(text)) { - result = ts.createTypeReferenceNode('React.ReactElement', undefined); + result = ts.factory.createTypeReferenceNode('React.ReactElement', undefined); } else if (/func/.test(text)) { if (anyFunctionAlias) { - result = ts.createTypeReferenceNode(anyFunctionAlias, undefined); + result = ts.factory.createTypeReferenceNode(anyFunctionAlias, undefined); } else if (anyAlias) { - result = ts.createFunctionTypeNode( + result = ts.factory.createFunctionTypeNode( undefined, [ - ts.createParameter( + ts.factory.createParameterDeclaration( undefined, undefined, - ts.createToken(ts.SyntaxKind.DotDotDotToken), + ts.factory.createToken(ts.SyntaxKind.DotDotDotToken), 'args', undefined, - ts.createArrayTypeNode(ts.createTypeReferenceNode(anyAlias, undefined)), + ts.factory.createArrayTypeNode( + ts.factory.createTypeReferenceNode(anyAlias, undefined), + ), undefined, ), ], - ts.createTypeReferenceNode(anyAlias, undefined), + ts.factory.createTypeReferenceNode(anyAlias, undefined), ); } else { - result = ts.createFunctionTypeNode( + result = ts.factory.createFunctionTypeNode( undefined, [ - ts.createParameter( + ts.factory.createParameterDeclaration( undefined, undefined, - ts.createToken(ts.SyntaxKind.DotDotDotToken), + ts.factory.createToken(ts.SyntaxKind.DotDotDotToken), 'args', undefined, - ts.createArrayTypeNode(ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), + ts.factory.createArrayTypeNode( + ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), + ), undefined, ), ], - ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), ); } } @@ -211,9 +220,9 @@ function getTypeFromPropTypeExpression( const argument = node.arguments[0]; if (ts.isArrayLiteralExpression(argument)) { if (argument.elements.every((elm) => ts.isStringLiteral(elm) || ts.isNumericLiteral(elm))) { - result = ts.createUnionTypeNode( + result = ts.factory.createUnionTypeNode( (argument.elements as ts.NodeArray).map((elm) => - ts.createLiteralTypeNode(elm), + ts.factory.createLiteralTypeNode(elm), ), ); } @@ -222,7 +231,7 @@ function getTypeFromPropTypeExpression( const argument = node.arguments[0]; if (ts.isArrayLiteralExpression(argument)) { const children: ts.Node[] = []; - result = ts.createUnionTypeNode( + result = ts.factory.createUnionTypeNode( argument.elements.map((elm) => { const child = getTypeFromPropTypeExpression(elm, sourceFile, params); children.push(child); @@ -237,25 +246,25 @@ function getTypeFromPropTypeExpression( const argument = node.arguments[0]; if (argument) { const child = getTypeFromPropTypeExpression(argument, sourceFile, params); - result = ts.createArrayTypeNode(child); + result = ts.factory.createArrayTypeNode(child); result = ts.moveSyntheticComments(result, child); } } else if (/objectOf$/.test(expressionText)) { const argument = node.arguments[0]; if (argument) { const child = getTypeFromPropTypeExpression(argument, sourceFile, params); - result = ts.createTypeLiteralNode([ - ts.createIndexSignature( + result = ts.factory.createTypeLiteralNode([ + ts.factory.createIndexSignature( undefined, undefined, [ - ts.createParameter( + ts.factory.createParameterDeclaration( undefined, undefined, undefined, 'key', undefined, - ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), ), ], child, @@ -270,12 +279,12 @@ function getTypeFromPropTypeExpression( } } } else if (ts.isIdentifier(node) && node.text === 'textlike') { - result = ts.createUnionTypeNode([ - ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), - ts.createTypeReferenceNode('React.ReactNode', undefined), + result = ts.factory.createUnionTypeNode([ + ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), + ts.factory.createTypeReferenceNode('React.ReactNode', undefined), ]); } else if (ts.isIdentifier(node)) { - result = ts.createTypeReferenceNode(node.text, undefined); + result = ts.factory.createTypeReferenceNode(node.text, undefined); } /** @@ -284,9 +293,9 @@ function getTypeFromPropTypeExpression( */ if (!result) { if (anyAlias) { - result = ts.createTypeReferenceNode(anyAlias, undefined); + result = ts.factory.createTypeReferenceNode(anyAlias, undefined); } else { - result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); + result = ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword); } // Add comment about what the original proptype was.