flow-upgrade 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +10 -0
  2. package/dist/Styled.js +12 -14
  3. package/dist/Types.js +21 -1
  4. package/dist/bin/runSpecificCodemod.js +117 -0
  5. package/dist/bin/upgrade.js +75 -0
  6. package/dist/codemodUtils/getClassMemberName.js +27 -0
  7. package/dist/codemodUtils/replaceMethodWithArrowProp.js +60 -0
  8. package/dist/codemods/collapseObjectInitialization.js +250 -0
  9. package/dist/codemods/convertImplicitInexactObjectTypes.js +35 -0
  10. package/dist/codemods/removeAnnotationsInDestructuring.js +40 -0
  11. package/dist/codemods/removeDuplicateClassProperties.js +268 -0
  12. package/dist/findFlowFiles.js +136 -158
  13. package/dist/runCodemods.js +36 -0
  14. package/dist/upgrade.js +127 -153
  15. package/dist/upgrades/0.170.0/index.js +25 -0
  16. package/dist/upgrades/0.176.0/index.js +25 -0
  17. package/dist/upgrades/0.84.0/index.js +25 -0
  18. package/dist/upgrades/index.js +29 -0
  19. package/dist/utils/redirectConsole.js +59 -0
  20. package/package.json +29 -21
  21. package/dist/codemods/ReactUtils.js +0 -140
  22. package/dist/codemods/createAggregateCodemod.js +0 -36
  23. package/dist/codemods/runCodemods.js +0 -54
  24. package/dist/index.js +0 -38
  25. package/dist/upgrades/0.53.0/ReactComponentExplicitTypeArgs/codemod.js +0 -154
  26. package/dist/upgrades/0.53.0/ReactComponentExplicitTypeArgs/index.js +0 -75
  27. package/dist/upgrades/0.53.0/ReactComponentSimplifyTypeArgs/codemod.js +0 -65
  28. package/dist/upgrades/0.53.0/ReactComponentSimplifyTypeArgs/index.js +0 -52
  29. package/dist/upgrades/0.53.0/ReactUtilityTypes/codemod.js +0 -156
  30. package/dist/upgrades/0.53.0/ReactUtilityTypes/index.js +0 -59
  31. package/dist/upgrades/0.84.0/ExplicitInexactObjectSyntax/codemod.js +0 -18
  32. package/dist/upgrades/0.84.0/ExplicitInexactObjectSyntax/index.js +0 -25
@@ -1,156 +0,0 @@
1
- /**
2
- * @format
3
- */
4
-
5
- 'use strict';
6
-
7
- // All the event names that we need to add <> to.
8
-
9
- const SYNTHETIC_EVENT_NAMES = new Set(['SyntheticEvent', 'SyntheticAnimationEvent', 'SyntheticClipboardEvent', 'SyntheticCompositionEvent', 'SyntheticInputEvent', 'SyntheticUIEvent', 'SyntheticFocusEvent', 'SyntheticKeyboardEvent', 'SyntheticMouseEvent', 'SyntheticDragEvent', 'SyntheticWheelEvent', 'SyntheticTouchEvent', 'SyntheticTransitionEvent']);
10
-
11
- /**
12
- * This codemod alters, removes, and replaces various React utilities that
13
- * had API changes when upgrading to this version. This includes the following
14
- * list:
15
- *
16
- * - `React$Node`.
17
- * - `React$Element`.
18
- * - `ReactClass`.
19
- * - `ReactComponent`.
20
- * - The return type of React component render.
21
- */
22
- module.exports = (j, root) => {
23
- const ReactUtils = require('../../../codemods/ReactUtils')(j);
24
- const reactName = ReactUtils.getImportedReactName(root);
25
- const componentPattern = ReactUtils.getImportedComponentClassPattern(root);
26
- const hasElement = ReactUtils.hasDestructuredElement(root, reactName);
27
-
28
- root.find(j.GenericTypeAnnotation).forEach(visitGenericTypeAnnotation);
29
- root.find(j.ImportDeclaration).forEach(visitImportDeclaration);
30
-
31
- function visitImportDeclaration(path) {
32
- const node = path.node;
33
-
34
- // import React from 'react'; ==> import * as React from 'react';
35
- if (node.importKind === 'value' && node.source && node.source.type === 'Literal' && node.source.value === 'react' && node.specifiers.length === 1 && node.specifiers[0].type === 'ImportDefaultSpecifier') {
36
- node.specifiers[0] = j.importNamespaceSpecifier(node.specifiers[0].local);
37
- }
38
- }
39
-
40
- function visitGenericTypeAnnotation(path) {
41
- const node = path.node;
42
-
43
- // React$Node<any> ==> React.Node
44
- if (node.id.type === 'Identifier' && (node.id.name === 'React$Node' || node.id.name === 'ReactNode')) {
45
- // React.Node no longer has type parameters.
46
- node.typeParameters = null;
47
- // Use the exported type from the React module. If it does not exist then
48
- // use React$Node.
49
- node.id = reactName ? j.qualifiedTypeIdentifier(j.identifier(reactName), j.identifier('Node')) : j.identifier('React$Node');
50
- }
51
-
52
- // React$Element<Config> ==> React.Element<React.ComponentType<Props>>
53
- else if (
54
- // React$Element or ReactElement
55
- node.id.type === 'Identifier' && (node.id.name === 'React$Element' || node.id.name === 'ReactElement') ||
56
- // React.Element
57
- node.id.type === 'QualifiedTypeIdentifier' && node.id.qualification && node.id.qualification.type === 'Identifier' && node.id.qualification.name === reactName && node.id.id && node.id.id.type === 'Identifier' && node.id.id.name === 'Element' ||
58
- // const {Element} = React;
59
- // Element
60
- hasElement && node.id.type === 'Identifier' && node.id.name === 'Element') {
61
- // If we have no type parameters then add an empty type parameter
62
- // instantiation.
63
- if (!node.typeParameters) {
64
- node.typeParameters = j.typeParameterInstantiation([]);
65
- }
66
- // If we have a first type parameter...
67
- if (node.typeParameters.params[0]) {
68
- const firstTypeParam = node.typeParameters.params[0];
69
- // ...and that type parameter is not `any`, `mixed`, or `*`...
70
- if (firstTypeParam && firstTypeParam.type !== 'AnyTypeAnnotation' && firstTypeParam.type !== 'ExistsTypeAnnotation') {
71
- // ...then wrap the type parameter with `React.ComponentType<Props>`.
72
- node.typeParameters.params[0] = j.genericTypeAnnotation(
73
- // Get the `React.ComponentType` type name, or use the global.
74
- reactName ? j.qualifiedTypeIdentifier(j.identifier(reactName), j.identifier('ComponentType')) : j.identifier('React$ComponentType'),
75
- // Put the type param we are wrapping as the first and only
76
- // type argument.
77
- j.typeParameterInstantiation([firstTypeParam]));
78
- }
79
- }
80
- // If we do not have a first type parameter, or our type parameter is `*`
81
- // then we want to use `any` instead. This is because using `*` will often
82
- // cause errors that are unrelated to whether or not the code is correct.
83
- // Almost all of the time when a user writes `React.Element<*>` they meant
84
- // `React.Element<any>`. They just felt bad about writing `any`.
85
- if (node.typeParameters.params.length === 0 || node.typeParameters.params[0].type === 'ExistsTypeAnnotation') {
86
- node.typeParameters = j.typeParameterInstantiation([j.anyTypeAnnotation()]);
87
- }
88
- // Update the type identifier to be `React.Element` or the
89
- // equivalent global.
90
- node.id = reactName ? j.qualifiedTypeIdentifier(j.identifier(reactName), j.identifier('Element')) : j.identifier('React$Element');
91
- }
92
-
93
- // ReactClass<Config> ==> React.ComponentType<Props>
94
- else if (node.id.type === 'Identifier' && node.id.name === 'ReactClass' && node.typeParameters && node.typeParameters.type === 'TypeParameterInstantiation') {
95
- // Replace ReactClass with the new type.
96
- // Get the component type name. Either as a qualified name from our
97
- // React import or using the global.
98
- node.id = reactName ? j.qualifiedTypeIdentifier(j.identifier(reactName), j.identifier('ComponentType')) : j.identifier('React$ComponentType');
99
- }
100
-
101
- // React$Component<Defaults, Props, State> ==> React.Component<Props, State>
102
- else if ((node.id.type === 'Identifier' && (node.id.name === 'ReactComponent' || node.id.name === 'React$Component') || componentPattern && componentPattern(node.id)) && node.typeParameters && node.typeParameters.type === 'TypeParameterInstantiation') {
103
- // Remove the default props type argument.
104
- if (node.typeParameters.params.length >= 3) {
105
- node.typeParameters.params.shift();
106
- }
107
- // If the user has destructured React and used Component or PureComponent
108
- // directly then we should not update the identifier of this node.
109
- if (!(node.id.type === 'Identifier' && (node.id.name === 'Component' || node.id.name === 'PureComponent'))) {
110
- node.id = reactName ? j.qualifiedTypeIdentifier(j.identifier(reactName), j.identifier('Component')) : j.identifier('React$Component');
111
- }
112
- }
113
-
114
- // SyntheticEvent ==> SyntheticEvent<>
115
- else if (node.id.type === 'Identifier' && SYNTHETIC_EVENT_NAMES.has(node.id.name)) {
116
- node.typeParameters = j.typeParameterInstantiation([]);
117
- }
118
- }
119
-
120
- // render(): React.Element<any> ==> render(): React.Node
121
- if (componentPattern) {
122
- root.find(j.ClassDeclaration, {
123
- superClass: componentPattern,
124
- body: { type: 'ClassBody' }
125
- }).forEach(handleReactClassPath);
126
-
127
- root.find(j.ClassExpression, {
128
- superClass: componentPattern,
129
- body: { type: 'ClassBody' }
130
- }).forEach(handleReactClassPath);
131
- }
132
-
133
- function handleReactClassPath(path) {
134
- // For every member in the class's body...
135
- path.node.body.body.forEach(method => {
136
- // If this member is the component's render method and it has a
137
- // return type...
138
- if (method.type === 'MethodDefinition' && method.key && method.key.type === 'Identifier' && method.key.name === 'render' && method.value && method.value.type === 'FunctionExpression' && method.value.returnType && method.value.returnType.type === 'TypeAnnotation') {
139
- const returnType = method.value.returnType;
140
- // If this is a return type from render that people commonly use then
141
- // replace it with the new recommendation. React.Node
142
- if (isRenderReturnReactElement(returnType.typeAnnotation) || returnType.typeAnnotation.type === 'NullableTypeAnnotation' && isRenderReturnReactElement(returnType.typeAnnotation.typeAnnotation)) {
143
- returnType.typeAnnotation = reactName ? j.qualifiedTypeIdentifier(j.identifier(reactName), j.identifier('Node')) : j.identifier('React$Node');
144
- }
145
- }
146
- });
147
- }
148
-
149
- function isRenderReturnReactElement(node) {
150
- // Is the node React.Element<any>, React.Element<mixed>,
151
- // or React.Element<*>?
152
- return reactName && node && node.type === 'GenericTypeAnnotation' && node.id.type === 'QualifiedTypeIdentifier' && node.id.qualification.type === 'Identifier' && node.id.qualification.name === reactName && node.id.id.type === 'Identifier' && node.id.id.name === 'Element' && node.typeParameters && node.typeParameters.type === 'TypeParameterInstantiation' && (node.typeParameters.params.length === 0 || node.typeParameters.params[0] && (node.typeParameters.params[0].type === 'AnyTypeAnnotation' || node.typeParameters.params[0].type === 'ExistsTypeAnnotation'));
153
- }
154
-
155
- return true;
156
- };
@@ -1,59 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * @format
5
- *
6
- */
7
-
8
- const path = require('path');
9
- const Styled = require('../../../Styled');
10
-
11
- exports.kind = 'codemod';
12
-
13
- exports.title = 'Remove and replace old React utility types.';
14
-
15
- exports.description = `
16
- In the past Flow has some very confusing and inconvenient utility types for
17
- React. We removed these utility types and replaced them with types which should
18
- make a lot more sense. These types will make it a lot easier to effectively type
19
- advanced React features like higher order components.
20
-
21
- Some of the most powerful new utility types can be seen in the following
22
- example:
23
-
24
- ${Styled.codeblock(`
25
- import * as React from 'react';
26
-
27
- function MyComponent(props: Props): React.Node {
28
- /* ... */
29
- }
30
- (React.createElement(MyComponent): React.Element<typeof MyComponent>);
31
-
32
- class MyStatefulComponent extends React.Component<Props> {
33
- /* ... */
34
- }
35
- (React.createElement(MyComponent): React.Element<typeof MyStatefulComponent>);
36
-
37
- function myHOC(
38
- Component: React.ComponentType<Props>,
39
- ): React.ComponentType<NewProps> {
40
- return class extends React.Component<NewProps> {
41
- /* ... */
42
- };
43
- }`.slice(1))}
44
-
45
- ${Styled.list([`React.Node is the new return type for render methods. This codemod will
46
- replace any render methods that return the type ?React.Element<any> with
47
- React.Node.`, `React.Element<Component> now takes the type of a component as its type
48
- argument instead of the type of a the component's props as it used to. This
49
- codemod will upgrade everywhere you use React.Element<Props> to
50
- React.Element<React.ComponentType<Props>>.`, `Speaking of React.ComponentType<Props>, this is a new utility type which
51
- represents either a class component, or a stateless functional component. This
52
- type is very useful when you want to type higher order components. We will
53
- replace everywhere you use ReactClass<Props> in your codebase with
54
- React.ComponentType<Props>. (ReactClass<Props> was very buggy and so this may
55
- cause a lot of new errors!)`, `Also note that we used import * as React from 'react'. You must use the
56
- import * syntax if you want to use the new utility types. This codemod will
57
- update your code to use this new style of import.`])}`.slice(1);
58
-
59
- exports.transformPath = path.join(__dirname, './codemod.js');
@@ -1,18 +0,0 @@
1
- /**
2
- * Copyright (c) 2013-present, Facebook, Inc.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- *
9
- */
10
-
11
- 'use strict';
12
-
13
- module.exports = (j, root) => {
14
- root.find(j.ObjectTypeAnnotation, { inexact: false, exact: false }).forEach(path => {
15
- path.node.inexact = true;
16
- });
17
- return root.toSource({ tabWidth: 2 });
18
- };
@@ -1,25 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Copyright (c) 2013-present, Facebook, Inc.
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE file in the root directory of this source tree.
8
- *
9
- * @format
10
- *
11
- */
12
-
13
- const path = require('path');
14
- const Styled = require('../../../Styled');
15
-
16
- exports.kind = 'codemod';
17
-
18
- exports.title = 'Adds `...` to the end of all inexact object types.';
19
-
20
- exports.description = `
21
- Flow is changing its object type syntax to be exact by default. See the blog
22
- post at https://medium.com/flow-type/on-the-roadmap-exact-objects-by-default-16b72933c5cf
23
- for details. This codemod will add '...' to the end of all inexact object types.
24
- `;
25
- exports.transformPath = path.join(__dirname, './codemod.js');