-
Notifications
You must be signed in to change notification settings - Fork 26
/
v3-Modal-method-with-icon-to-v4.js
148 lines (129 loc) · 4.45 KB
/
v3-Modal-method-with-icon-to-v4.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
const {
parseStrToArray,
removeEmptyModuleImport,
addSubmoduleImport,
} = require('./utils');
const { printOptions } = require('./utils/config');
const { addIconRelatedMsg } = require('./utils/summary');
const { markDependency } = require('./utils/marker');
const {
getV4IconComponentName,
createIconJSXElement,
} = require('./utils/icon');
const modalMethodNames = ['info', 'success', 'error', 'warning', 'confirm'];
module.exports = (file, api, options) => {
const j = api.jscodeshift;
const root = j(file.source);
const antdPkgNames = parseStrToArray(options.antdPkgNames || 'antd');
function importV4SpecificIcon(j, iconName, before) {
const iconJSXElement = createIconJSXElement(j, iconName);
addSubmoduleImport(j, root, {
moduleName: '@ant-design/icons',
importedName: iconName,
before,
});
markDependency('@ant-design/icons');
return iconJSXElement;
}
function importLegacyIcon(j, iconProperty, before) {
// handle it with `@ant-design/compatible`
const typeAttr = j.jsxAttribute(
j.jsxIdentifier('type'),
j.jsxExpressionContainer(iconProperty.value),
);
const iconJSXElement = createIconJSXElement(j, 'LegacyIcon', [typeAttr]);
// add @ant-design/compatible imports
addSubmoduleImport(j, root, {
moduleName: '@ant-design/compatible',
importedName: 'Icon',
localName: 'LegacyIcon',
before,
});
markDependency('@ant-design/compatible');
return iconJSXElement;
}
// rename old Model.method() calls with `icon#string` argument
function renameV3ModalMethodCalls(j, root) {
let hasChanged = false;
root
.find(j.Identifier)
.filter(
path =>
path.node.name === 'Modal' &&
path.parent.node.type === 'ImportSpecifier' &&
antdPkgNames.includes(path.parent.parent.node.source.value),
)
.forEach(path => {
const localComponentName = path.parent.node.local.name;
const antdPkgName = path.parent.parent.node.source.value;
root
.find(j.CallExpression, {
callee: {
object: {
type: 'Identifier',
name: localComponentName,
},
property: {
type: 'Identifier',
},
},
})
.filter(nodePath =>
modalMethodNames.includes(nodePath.node.callee.property.name),
)
.forEach(nodePath => {
if (
!Array.isArray(nodePath.node.arguments) ||
!nodePath.node.arguments[0] ||
nodePath.node.arguments[0].type !== 'ObjectExpression'
) {
// FIXME: need log?
// but we cannot know it contains `icon` property
return;
}
const args = nodePath.node.arguments[0];
const iconProperty = args.properties.find(
property =>
property.key.type === 'Identifier' &&
property.key.name === 'icon',
);
// v3-Icon-to-v4-Icon should handle with JSXElement
if (!iconProperty || iconProperty.value.type === 'JSXElement') {
return;
}
hasChanged = true;
if (iconProperty.value.type === 'StringLiteral') {
const v3IconName = iconProperty.value.value;
const v4IconComponentName = getV4IconComponentName(v3IconName);
if (v4IconComponentName) {
const jsxElement = importV4SpecificIcon(
j,
v4IconComponentName,
antdPkgName,
);
iconProperty.value = jsxElement;
return;
}
// FIXME: use parent jsxElement
const location = nodePath.node.loc.start;
addIconRelatedMsg(file, location, j(nodePath).toSource());
}
const jsxElement = importLegacyIcon(j, iconProperty, antdPkgName);
iconProperty.value = jsxElement;
});
});
return hasChanged;
}
// step1. // rename old Model.method() calls
// step2. cleanup antd import if empty
let hasChanged = false;
hasChanged = renameV3ModalMethodCalls(j, root) || hasChanged;
if (hasChanged) {
antdPkgNames.forEach(antdPkgName => {
removeEmptyModuleImport(j, root, antdPkgName);
});
}
return hasChanged
? root.toSource(options.printOptions || printOptions)
: null;
};