babel-plugin-transform-modules-ui5 7.0.5 → 7.0.6
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.
- package/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/dist/classes/helpers/classes.js +25 -61
- package/dist/classes/helpers/decorators.js +0 -10
- package/dist/classes/helpers/jsdoc.js +9 -34
- package/dist/classes/visitor.js +17 -48
- package/dist/index.js +15 -19
- package/dist/modules/helpers/exports.js +6 -29
- package/dist/modules/helpers/wrapper.js +14 -36
- package/dist/modules/visitor.js +30 -60
- package/dist/utils/ast.js +27 -55
- package/dist/utils/templates.js +12 -12
- package/package.json +36 -30
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
## [7.0.6](https://github.com/ui5-community/babel-plugin-transform-modules-ui5/compare/v7.0.5...v7.0.6) (2023-02-21)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package babel-plugin-transform-modules-ui5
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 Ryan Murphy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -5,33 +5,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.convertClassToUI5Extend = convertClassToUI5Extend;
|
|
7
7
|
exports.getClassInfo = getClassInfo;
|
|
8
|
-
|
|
9
8
|
var _core = require("@babel/core");
|
|
10
|
-
|
|
11
9
|
var _path = _interopRequireDefault(require("path"));
|
|
12
|
-
|
|
13
10
|
var _objectAssignDefined = _interopRequireDefault(require("object-assign-defined"));
|
|
14
|
-
|
|
15
11
|
var th = _interopRequireWildcard(require("../../utils/templates"));
|
|
16
|
-
|
|
17
12
|
var ast = _interopRequireWildcard(require("../../utils/ast"));
|
|
18
|
-
|
|
19
13
|
var _jsdoc = require("./jsdoc");
|
|
20
|
-
|
|
21
14
|
var _decorators = require("./decorators");
|
|
22
|
-
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
26
|
-
|
|
15
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
16
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
27
17
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
28
|
-
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
34
|
-
|
|
18
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
19
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
20
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
21
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
22
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
35
23
|
/**
|
|
36
24
|
* Converts an ES6 class to a UI5 extend.
|
|
37
25
|
* Any static methods or properties will be moved outside the class body.
|
|
@@ -41,12 +29,10 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
41
29
|
if (!(_core.types.isClassDeclaration(node) || _core.types.isClassExpression(node))) {
|
|
42
30
|
return node;
|
|
43
31
|
}
|
|
44
|
-
|
|
45
32
|
const staticMembers = [];
|
|
46
33
|
const classNameIdentifier = node.id;
|
|
47
34
|
const className = classNameIdentifier.name;
|
|
48
35
|
const superClass = node.superClass; // Identifier node.
|
|
49
|
-
|
|
50
36
|
const superClassName = superClass.name;
|
|
51
37
|
const isController = className.includes("Controller") || !!classInfo.controller;
|
|
52
38
|
const moveControllerConstructorToOnInit = isController && !!opts.moveControllerConstructorToOnInit;
|
|
@@ -59,27 +45,22 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
59
45
|
const propsByName = {};
|
|
60
46
|
let constructor;
|
|
61
47
|
let constructorComments;
|
|
62
|
-
const staticPropsToAdd = moveStaticStaticPropsToExtend ? Object.keys(extraStaticProps) : ["metadata", "renderer"];
|
|
63
|
-
|
|
48
|
+
const staticPropsToAdd = moveStaticStaticPropsToExtend ? Object.keys(extraStaticProps) : ["metadata", "renderer", "overrides"];
|
|
64
49
|
for (const propName of staticPropsToAdd) {
|
|
65
50
|
if (extraStaticProps[propName]) {
|
|
66
51
|
extendProps.push(_core.types.objectProperty(_core.types.identifier(propName), extraStaticProps[propName]));
|
|
67
52
|
}
|
|
68
53
|
}
|
|
69
|
-
|
|
70
54
|
for (const member of node.body.body) {
|
|
71
55
|
const memberName = member.key.name;
|
|
72
|
-
|
|
73
56
|
if (_core.types.isClassMethod(member)) {
|
|
74
57
|
const func = _core.types.functionExpression(member.key, member.params, member.body, member.generator, member.async);
|
|
75
|
-
|
|
76
58
|
if (member.static) {
|
|
77
|
-
staticMembers.push(buildMemberAssignmentStatement(classNameIdentifier, _objectSpread({}, member, {
|
|
59
|
+
staticMembers.push(buildMemberAssignmentStatement(classNameIdentifier, _objectSpread(_objectSpread({}, member), {}, {
|
|
78
60
|
value: func
|
|
79
61
|
})));
|
|
80
62
|
} else {
|
|
81
63
|
propsByName[memberName] = func;
|
|
82
|
-
|
|
83
64
|
if (member.kind === "get" || member.kind === "set") {
|
|
84
65
|
extendProps.push(_core.types.objectMethod(member.kind, member.key, member.params, member.body, member.computed));
|
|
85
66
|
} else {
|
|
@@ -87,24 +68,21 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
87
68
|
if (memberName === CONSTRUCTOR) {
|
|
88
69
|
constructorComments = member.leadingComments;
|
|
89
70
|
constructor = func;
|
|
90
|
-
|
|
91
71
|
if (moveControllerPropsToOnInit) {
|
|
92
72
|
continue; // don't push to props yet
|
|
93
73
|
}
|
|
94
74
|
}
|
|
95
75
|
|
|
96
76
|
func.id = path.scope.generateUidIdentifier(func.id.name); // Give the function a unique name
|
|
97
|
-
|
|
98
|
-
extendProps.push(buildObjectProperty(_objectSpread({}, member, {
|
|
77
|
+
extendProps.push(buildObjectProperty(_objectSpread(_objectSpread({}, member), {}, {
|
|
99
78
|
value: func
|
|
100
79
|
})));
|
|
101
80
|
}
|
|
102
81
|
}
|
|
103
82
|
} else if (_core.types.isClassProperty(member)) {
|
|
104
83
|
if (!member.value) continue; // un-initialized static class prop (typescript)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
// Special handling for TypeScript limitation where metadata and renderer must be properties.
|
|
84
|
+
if (memberName === "metadata" || memberName === "renderer" || memberName === "overrides") {
|
|
85
|
+
// Special handling for TypeScript limitation where metadata, renderer and overrides must be properties.
|
|
108
86
|
extendProps.unshift(buildObjectProperty(member));
|
|
109
87
|
} else if (member.static) {
|
|
110
88
|
if (moveStaticStaticPropsToExtend) {
|
|
@@ -114,11 +92,9 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
114
92
|
}
|
|
115
93
|
} else {
|
|
116
94
|
propsByName[memberName] = member.value;
|
|
117
|
-
|
|
118
95
|
if (memberName === "constructor") {
|
|
119
96
|
constructorComments = member.leadingComments;
|
|
120
97
|
constructor = member.value;
|
|
121
|
-
|
|
122
98
|
if (moveControllerPropsToOnInit) {
|
|
123
99
|
continue; // don't push to props yet
|
|
124
100
|
}
|
|
@@ -131,24 +107,27 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
131
107
|
}
|
|
132
108
|
}
|
|
133
109
|
}
|
|
134
|
-
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Arrow function properties need to get moved to the constructor so that
|
|
135
113
|
// they're bound properly to the class instance, to align with the spec.
|
|
136
114
|
// For controllers, use onInit rather than constructor, since controller constructors don't work.
|
|
137
115
|
// Also move the constructor's statements to the onInit.
|
|
138
116
|
|
|
139
|
-
|
|
140
117
|
const bindToConstructor = !moveControllerPropsToOnInit;
|
|
141
|
-
const bindToMethodName = moveControllerPropsToOnInit ? "onInit" : "constructor";
|
|
118
|
+
const bindToMethodName = moveControllerPropsToOnInit ? "onInit" : "constructor";
|
|
142
119
|
|
|
120
|
+
// avoid getting a prop named constructor as it may return {}'s
|
|
143
121
|
let bindMethod = moveControllerPropsToOnInit ? propsByName[bindToMethodName] : constructor;
|
|
144
122
|
const constructorJsdoc = (0, _jsdoc.getTags)(constructorComments);
|
|
145
|
-
const keepConstructor = !moveControllerConstructorToOnInit || classInfo.keepConstructor || constructorJsdoc.keep;
|
|
123
|
+
const keepConstructor = !moveControllerConstructorToOnInit || classInfo.keepConstructor || constructorJsdoc.keep;
|
|
146
124
|
|
|
147
|
-
|
|
125
|
+
// See if we need either constructor or onInit
|
|
126
|
+
const needsBindingMethod = boundProps.length || moveControllerPropsToOnInit && constructor && !keepConstructor;
|
|
148
127
|
|
|
128
|
+
// See if we need to create a new 'constructor' or 'onInit' method, depending which one we'll bind to.
|
|
149
129
|
if (needsBindingMethod && !bindMethod) {
|
|
150
130
|
const bindToId = _core.types.identifier(bindToMethodName);
|
|
151
|
-
|
|
152
131
|
const bindMethodDeclaration = bindToConstructor ? th.buildInheritingConstructor({
|
|
153
132
|
SUPER: _core.types.identifier(superClassName)
|
|
154
133
|
}) : th.buildInheritingFunction({
|
|
@@ -158,7 +137,6 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
158
137
|
bindMethod = ast.convertFunctionDeclarationToExpression(bindMethodDeclaration);
|
|
159
138
|
extendProps.unshift(_core.types.objectProperty(bindToId, bindMethod));
|
|
160
139
|
}
|
|
161
|
-
|
|
162
140
|
if (constructor && moveControllerPropsToOnInit) {
|
|
163
141
|
if (keepConstructor) {
|
|
164
142
|
extendProps.unshift(_core.types.objectProperty(_core.types.identifier(CONSTRUCTOR), constructor));
|
|
@@ -167,13 +145,12 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
167
145
|
bindMethod.body.body.unshift(...constructor.body.body.filter(node => !ast.isSuperCallExpression(node.expression)));
|
|
168
146
|
}
|
|
169
147
|
}
|
|
170
|
-
|
|
171
148
|
if (boundProps.length) {
|
|
172
149
|
// We need to inject the bound props into the bind method (constructor or onInit),
|
|
173
150
|
// but not until after the super call (if applicable)
|
|
151
|
+
|
|
174
152
|
const mappedProps = boundProps.map(member => buildThisMemberAssignmentStatement(member));
|
|
175
153
|
const superIndex = bindMethod.body.body.findIndex(node => ast.isSuperCallExpression(node.expression) || ast.isSuperPrototypeCallOf(node.expression, superClassName, bindToMethodName));
|
|
176
|
-
|
|
177
154
|
if (superIndex === -1) {
|
|
178
155
|
// If there's no super, just add the bound props at the start
|
|
179
156
|
bindMethod.body.body.unshift(...mappedProps);
|
|
@@ -183,7 +160,6 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
183
160
|
bindMethod.body.body = [...upToSuper, ...mappedProps, ...afterSuper];
|
|
184
161
|
}
|
|
185
162
|
}
|
|
186
|
-
|
|
187
163
|
const extendAssign = th.buildExtendAssign({
|
|
188
164
|
NAME: classNameIdentifier,
|
|
189
165
|
SUPER: superClass,
|
|
@@ -193,7 +169,6 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, opts)
|
|
|
193
169
|
});
|
|
194
170
|
return [extendAssign, ...staticMembers];
|
|
195
171
|
}
|
|
196
|
-
|
|
197
172
|
function getFullyQualifiedName(classInfo) {
|
|
198
173
|
if (classInfo.alias) return classInfo.alias;
|
|
199
174
|
if (classInfo.name) return classInfo.name;
|
|
@@ -201,7 +176,6 @@ function getFullyQualifiedName(classInfo) {
|
|
|
201
176
|
const separator = namespace ? "." : "";
|
|
202
177
|
return `${namespace}${separator}${classInfo.localName}`;
|
|
203
178
|
}
|
|
204
|
-
|
|
205
179
|
function getClassInfo(path, node, parent, pluginOpts) {
|
|
206
180
|
const defaults = {
|
|
207
181
|
localName: node.id.name,
|
|
@@ -209,43 +183,33 @@ function getClassInfo(path, node, parent, pluginOpts) {
|
|
|
209
183
|
fileNamespace: getFileBaseNamespace(path, pluginOpts) || ""
|
|
210
184
|
};
|
|
211
185
|
const decoratorInfo = (0, _decorators.getDecoratorClassInfo)(node);
|
|
212
|
-
const jsDocInfo = (0, _jsdoc.getJsDocClassInfo)(node, parent);
|
|
186
|
+
const jsDocInfo = (0, _jsdoc.getJsDocClassInfo)(node, parent);
|
|
213
187
|
|
|
188
|
+
// like Object.assign, but ignoring undefined values.
|
|
214
189
|
return (0, _objectAssignDefined.default)(defaults, decoratorInfo, jsDocInfo);
|
|
215
190
|
}
|
|
191
|
+
|
|
216
192
|
/**
|
|
217
193
|
* Reads the namespace from the file path (but not the name).
|
|
218
194
|
*/
|
|
219
|
-
|
|
220
|
-
|
|
221
195
|
function getFileBaseNamespace(path, pluginOpts) {
|
|
222
196
|
const opts = path.hub.file.opts;
|
|
223
|
-
|
|
224
197
|
const filename = _path.default.resolve(opts.filename);
|
|
225
|
-
|
|
226
198
|
const sourceRoot = opts.sourceRoot ? _path.default.resolve(process.cwd(), opts.sourceRoot) : process.cwd();
|
|
227
|
-
|
|
228
199
|
if (filename.startsWith(sourceRoot)) {
|
|
229
200
|
const filenameRelative = _path.default.relative(sourceRoot, filename);
|
|
230
|
-
|
|
231
201
|
const {
|
|
232
202
|
dir
|
|
233
203
|
} = _path.default.parse(filenameRelative);
|
|
234
|
-
|
|
235
204
|
const namespaceParts = dir.split(_path.default.sep);
|
|
236
|
-
|
|
237
205
|
if (pluginOpts.namespacePrefix) {
|
|
238
206
|
namespaceParts.unshift(pluginOpts.namespacePrefix);
|
|
239
207
|
}
|
|
240
|
-
|
|
241
208
|
return namespaceParts.join(".");
|
|
242
209
|
} else {
|
|
243
210
|
return undefined;
|
|
244
211
|
}
|
|
245
212
|
}
|
|
246
|
-
|
|
247
213
|
const buildObjectProperty = member => _core.types.objectProperty(member.key, member.value, member.computed);
|
|
248
|
-
|
|
249
214
|
const buildMemberAssignmentStatement = (objectIdentifier, member) => _core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.memberExpression(objectIdentifier, member.key, member.computed), member.value));
|
|
250
|
-
|
|
251
215
|
const buildThisMemberAssignmentStatement = buildMemberAssignmentStatement.bind(null, _core.types.thisExpression());
|
|
@@ -6,36 +6,27 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.getDecoratorClassInfo = getDecoratorClassInfo;
|
|
7
7
|
const classInfoValueTags = ["alias", "name", "namespace", "metadata", "renderer"];
|
|
8
8
|
const classInfoBoolTags = ["nonUI5"];
|
|
9
|
-
|
|
10
9
|
function getDecoratorClassInfo(node) {
|
|
11
10
|
const decorators = node.decorators;
|
|
12
|
-
|
|
13
11
|
if (!decorators || !decorators.length) {
|
|
14
12
|
return {};
|
|
15
13
|
}
|
|
16
|
-
|
|
17
14
|
const decoratorsByName = groupByName(decorators);
|
|
18
15
|
const info = {};
|
|
19
|
-
|
|
20
16
|
for (const tagName of classInfoValueTags) {
|
|
21
17
|
const value = getDecoratorValue(decoratorsByName[tagName.toLowerCase()]);
|
|
22
|
-
|
|
23
18
|
if (value) {
|
|
24
19
|
info[tagName] = value;
|
|
25
20
|
}
|
|
26
21
|
}
|
|
27
|
-
|
|
28
22
|
for (const tagName of classInfoBoolTags) {
|
|
29
23
|
const value = !!decoratorsByName[tagName.toLowerCase()];
|
|
30
|
-
|
|
31
24
|
if (value) {
|
|
32
25
|
info[tagName] = value;
|
|
33
26
|
}
|
|
34
27
|
}
|
|
35
|
-
|
|
36
28
|
return info;
|
|
37
29
|
}
|
|
38
|
-
|
|
39
30
|
function groupByName(decorators) {
|
|
40
31
|
return decorators.reduce((accumulator, decorator) => {
|
|
41
32
|
const expression = decorator.expression;
|
|
@@ -44,7 +35,6 @@ function groupByName(decorators) {
|
|
|
44
35
|
return accumulator;
|
|
45
36
|
}, {});
|
|
46
37
|
}
|
|
47
|
-
|
|
48
38
|
function getDecoratorValue(decorator) {
|
|
49
39
|
return (decorator && decorator.expression.arguments[0] || {}).value;
|
|
50
40
|
}
|
|
@@ -6,122 +6,97 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.getJsDocClassInfo = getJsDocClassInfo;
|
|
7
7
|
exports.getTags = getTags;
|
|
8
8
|
exports.hasJsdocGlobalExportFlag = hasJsdocGlobalExportFlag;
|
|
9
|
-
|
|
10
9
|
var _core = require("@babel/core");
|
|
11
|
-
|
|
12
10
|
var _doctrine = _interopRequireDefault(require("doctrine"));
|
|
13
|
-
|
|
14
11
|
var _ignoreCase = _interopRequireDefault(require("ignore-case"));
|
|
15
|
-
|
|
16
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
18
13
|
const classInfoValueTags = ["alias", "name", "namespace"];
|
|
19
14
|
const classInfoBoolTags = ["nonUI5", "controller", "keepConstructor"];
|
|
20
|
-
|
|
21
15
|
function getJsDocClassInfo(node, parent) {
|
|
22
16
|
if (node.leadingComments) {
|
|
23
17
|
return node.leadingComments.filter(isCommentBlock).map(comment => {
|
|
24
18
|
const docAST = _doctrine.default.parse(comment.value, {
|
|
25
19
|
unwrap: true
|
|
26
20
|
});
|
|
27
|
-
|
|
28
21
|
const tags = docAST.tags || [];
|
|
29
22
|
const info = {};
|
|
30
|
-
|
|
31
23
|
for (const tagName of classInfoValueTags) {
|
|
32
24
|
const value = getJsDocTagValue(tags, tagName);
|
|
33
|
-
|
|
34
25
|
if (value) {
|
|
35
26
|
info[tagName] = value;
|
|
36
27
|
}
|
|
37
28
|
}
|
|
38
|
-
|
|
39
29
|
for (const tagName of classInfoBoolTags) {
|
|
40
30
|
const value = !!getJsDocTag(tags, tagName);
|
|
41
|
-
|
|
42
31
|
if (value) {
|
|
43
32
|
info[tagName] = value;
|
|
44
33
|
}
|
|
45
34
|
}
|
|
46
|
-
|
|
47
35
|
return info;
|
|
48
36
|
}).filter(notEmpty)[0];
|
|
49
|
-
}
|
|
37
|
+
}
|
|
38
|
+
// Else see if the JSDoc are on the return statement (eg. return class X extends SAPClass)
|
|
50
39
|
// or export statement (eg. export default class X extends SAPClass)
|
|
51
40
|
else if (_core.types.isClassExpression(node) && _core.types.isReturnStatement(parent) || _core.types.isClassDeclaration(node) && _core.types.isExportDefaultDeclaration(parent)) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
return getJsDocClassInfo(parent);
|
|
42
|
+
} else {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
56
45
|
}
|
|
46
|
+
|
|
57
47
|
/**
|
|
58
48
|
* Returns a map of tags by name.
|
|
59
49
|
* Converts empty to bool. Also converts bool value
|
|
60
50
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
51
|
function getTags(comments) {
|
|
64
52
|
if (!comments) {
|
|
65
53
|
return {};
|
|
66
54
|
}
|
|
67
|
-
|
|
68
55
|
for (const comment of comments) {
|
|
69
56
|
if (!isCommentBlock(comment)) {
|
|
70
57
|
continue;
|
|
71
58
|
}
|
|
72
|
-
|
|
73
59
|
const docAST = _doctrine.default.parse(comment.value, {
|
|
74
60
|
unwrap: true
|
|
75
61
|
});
|
|
76
|
-
|
|
77
62
|
const tags = docAST.tags;
|
|
78
|
-
|
|
79
63
|
if (!tags || !tags.length) {
|
|
80
64
|
continue;
|
|
81
65
|
}
|
|
82
|
-
|
|
83
66
|
const map = {};
|
|
84
|
-
|
|
85
67
|
for (const tag of tags) {
|
|
86
68
|
const title = tag.title;
|
|
87
69
|
let value = tag.name || tag.description || true;
|
|
88
70
|
if (value === "false") value = false;
|
|
89
71
|
map[title] = value;
|
|
90
72
|
}
|
|
91
|
-
|
|
92
73
|
return map;
|
|
93
74
|
}
|
|
94
|
-
|
|
95
75
|
return {};
|
|
96
76
|
}
|
|
97
|
-
|
|
98
77
|
function getJsDocTagValue(tags, name) {
|
|
99
78
|
const tag = getJsDocTag(tags, name);
|
|
100
79
|
return tag && (tag.name || tag.description);
|
|
101
80
|
}
|
|
102
|
-
|
|
103
81
|
function getJsDocTag(tags, name) {
|
|
104
82
|
return tags.find(t => _ignoreCase.default.equals(name, t.title));
|
|
105
83
|
}
|
|
106
|
-
|
|
107
84
|
function notEmpty(obj) {
|
|
108
85
|
return Object.values(obj).some(value => value);
|
|
109
86
|
}
|
|
110
|
-
|
|
111
87
|
function hasJsdocGlobalExportFlag(node) {
|
|
112
88
|
if (!node.leadingComments) {
|
|
113
89
|
return false;
|
|
114
90
|
}
|
|
115
|
-
|
|
116
91
|
return node.leadingComments.filter(isCommentBlock).some(comment => {
|
|
117
92
|
return _doctrine.default.parse(comment.value, {
|
|
118
93
|
unwrap: true,
|
|
119
94
|
tags: ["global"]
|
|
120
95
|
}).tags.length > 0;
|
|
121
96
|
});
|
|
122
|
-
}
|
|
123
|
-
|
|
97
|
+
}
|
|
124
98
|
|
|
99
|
+
// This doesn't exist on babel-types
|
|
125
100
|
function isCommentBlock(node) {
|
|
126
101
|
return node && node.type === "CommentBlock";
|
|
127
102
|
}
|
package/dist/classes/visitor.js
CHANGED
|
@@ -4,25 +4,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.ClassTransformVisitor = void 0;
|
|
7
|
-
|
|
8
7
|
var _core = require("@babel/core");
|
|
9
|
-
|
|
10
8
|
var th = _interopRequireWildcard(require("../utils/templates"));
|
|
11
|
-
|
|
12
9
|
var ast = _interopRequireWildcard(require("../utils/ast"));
|
|
13
|
-
|
|
14
10
|
var classes = _interopRequireWildcard(require("./helpers/classes"));
|
|
15
|
-
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
19
|
-
|
|
11
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
12
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
20
13
|
const CONSTRUCTOR = "constructor";
|
|
21
14
|
const ClassTransformVisitor = {
|
|
22
15
|
ImportDefaultSpecifier(path) {
|
|
23
16
|
this.importNames.push(path.node.local.name);
|
|
24
17
|
},
|
|
25
|
-
|
|
26
18
|
/**
|
|
27
19
|
* ClassDeclaration visitor.
|
|
28
20
|
* Use both enter() and exit() to track when the visitor is inside a UI5 class,
|
|
@@ -39,35 +31,32 @@ const ClassTransformVisitor = {
|
|
|
39
31
|
parent,
|
|
40
32
|
parentPath
|
|
41
33
|
} = path;
|
|
42
|
-
|
|
43
34
|
if (opts.neverConvertClass) {
|
|
44
35
|
return;
|
|
45
36
|
}
|
|
46
|
-
|
|
47
37
|
if (!doesClassExtendFromImport(node, [...this.importNames])) {
|
|
48
38
|
// If it doesn't extend from an import, treat it as plain ES2015 class.
|
|
49
39
|
return;
|
|
50
|
-
}
|
|
51
|
-
// and therefore may need to be transformed to .extend() syntax.
|
|
52
|
-
|
|
40
|
+
}
|
|
53
41
|
|
|
42
|
+
// If the super class is one of the imports, we'll assume it's a UI5 managed class,
|
|
43
|
+
// and therefore may need to be transformed to .extend() syntax.
|
|
54
44
|
const classInfo = classes.getClassInfo(path, node, path.parent, opts);
|
|
55
|
-
|
|
56
45
|
if (!shouldConvertClass(file, node, opts, classInfo)) {
|
|
57
46
|
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
47
|
+
}
|
|
60
48
|
|
|
61
|
-
|
|
49
|
+
// Save super class name for converting super calls
|
|
50
|
+
this.superClassName = classInfo.superClassName;
|
|
62
51
|
|
|
52
|
+
// Find the Block scoped parent (Program or Function body) and search for assigned properties within that (eg. MyClass.X = "X").
|
|
63
53
|
const {
|
|
64
54
|
name: className
|
|
65
55
|
} = node.id;
|
|
66
56
|
const blockParent = path.findParent(path => path.isBlock()).node;
|
|
67
|
-
const staticProps = ast.groupPropertiesByName(ast.getOtherPropertiesOfIdentifier(blockParent, className));
|
|
68
|
-
|
|
57
|
+
const staticProps = ast.groupPropertiesByName(ast.getOtherPropertiesOfIdentifier(blockParent, className));
|
|
58
|
+
// TODO: flag metadata and renderer for removal if applicable
|
|
69
59
|
const ui5ExtendClass = classes.convertClassToUI5Extend(path, node, classInfo, staticProps, opts);
|
|
70
|
-
|
|
71
60
|
if (path.isClassDeclaration()) {
|
|
72
61
|
if (_core.types.isExportDefaultDeclaration(parent)) {
|
|
73
62
|
path.parentPath.replaceWithMultiple([...ui5ExtendClass, th.buildExportDefault({
|
|
@@ -85,17 +74,13 @@ const ClassTransformVisitor = {
|
|
|
85
74
|
ID: _core.types.identifier(classInfo.localName)
|
|
86
75
|
}));
|
|
87
76
|
}
|
|
88
|
-
|
|
89
77
|
parentPath.replaceWithMultiple(ui5ExtendClass);
|
|
90
78
|
}
|
|
91
79
|
},
|
|
92
|
-
|
|
93
80
|
exit() {
|
|
94
81
|
this.superClassName = null;
|
|
95
82
|
}
|
|
96
|
-
|
|
97
83
|
},
|
|
98
|
-
|
|
99
84
|
/*!
|
|
100
85
|
* Visits function calls.
|
|
101
86
|
*/
|
|
@@ -105,8 +90,8 @@ const ClassTransformVisitor = {
|
|
|
105
90
|
} = path;
|
|
106
91
|
const {
|
|
107
92
|
callee
|
|
108
|
-
} = node;
|
|
109
|
-
|
|
93
|
+
} = node;
|
|
94
|
+
// If the file already has sap.ui.define, get the names of variables it creates to use for the class logic.
|
|
110
95
|
if (ast.isCallExpressionCalling(node, "sap.ui.define")) {
|
|
111
96
|
this.importNames.push(...getRequiredParamsOfSAPUIDefine(path, node).map(req => req.name));
|
|
112
97
|
return;
|
|
@@ -120,7 +105,6 @@ const ClassTransformVisitor = {
|
|
|
120
105
|
}
|
|
121
106
|
}
|
|
122
107
|
},
|
|
123
|
-
|
|
124
108
|
/**
|
|
125
109
|
* Convert object method constructor() to constructor: function constructor(),
|
|
126
110
|
* since a UI5 class is not a real class.
|
|
@@ -129,7 +113,6 @@ const ClassTransformVisitor = {
|
|
|
129
113
|
const {
|
|
130
114
|
node
|
|
131
115
|
} = path;
|
|
132
|
-
|
|
133
116
|
if (node.key.name === CONSTRUCTOR) {
|
|
134
117
|
// The keyword 'constructor' should not be used as a shorthand
|
|
135
118
|
// method name in an object. It might(?) work on some objects,
|
|
@@ -137,79 +120,65 @@ const ClassTransformVisitor = {
|
|
|
137
120
|
path.replaceWith(_core.types.objectProperty(_core.types.identifier(CONSTRUCTOR), _core.types.functionExpression(_core.types.identifier(CONSTRUCTOR), node.params, node.body)));
|
|
138
121
|
}
|
|
139
122
|
}
|
|
140
|
-
|
|
141
123
|
};
|
|
142
124
|
exports.ClassTransformVisitor = ClassTransformVisitor;
|
|
143
|
-
|
|
144
125
|
function isSuperApply(callee) {
|
|
145
126
|
return _core.types.isIdentifier(callee.property, {
|
|
146
|
-
|
|
127
|
+
name: "apply"
|
|
147
128
|
}) && _core.types.isSuper(callee.object.object);
|
|
148
129
|
}
|
|
149
|
-
|
|
150
130
|
function getRequiredParamsOfSAPUIDefine(path, node) {
|
|
151
131
|
const defineArgs = node.arguments;
|
|
152
132
|
const callbackNode = defineArgs.find(argNode => _core.types.isFunction(argNode));
|
|
153
133
|
return callbackNode.params; // Identifier
|
|
154
134
|
}
|
|
135
|
+
|
|
155
136
|
/**
|
|
156
137
|
* Replace super() call
|
|
157
138
|
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
139
|
function replaceConstructorSuperCall(path, node, superClassName) {
|
|
161
140
|
replaceSuperNamedCall(path, node, superClassName, CONSTRUCTOR);
|
|
162
141
|
}
|
|
142
|
+
|
|
163
143
|
/**
|
|
164
144
|
* Replace super.method() call
|
|
165
145
|
*/
|
|
166
|
-
|
|
167
|
-
|
|
168
146
|
function replaceObjectSuperCall(path, node, superClassName) {
|
|
169
147
|
replaceSuperNamedCall(path, node, superClassName, node.callee.property.name);
|
|
170
148
|
}
|
|
149
|
+
|
|
171
150
|
/**
|
|
172
151
|
* Replace super.method.apply() call
|
|
173
152
|
*/
|
|
174
|
-
|
|
175
|
-
|
|
176
153
|
function replaceSuperApplyCall(path, node, superClassName) {
|
|
177
154
|
const methodName = node.callee.object.property.name;
|
|
178
155
|
path.replaceWith(_core.types.callExpression(_core.types.identifier(`${superClassName}.prototype.${methodName}.apply`), node.arguments));
|
|
179
156
|
}
|
|
180
|
-
|
|
181
157
|
function replaceSuperNamedCall(path, node, superClassName, methodName) {
|
|
182
158
|
// .call() is better for simple args (or not args) but doesn't work right for spread args
|
|
183
159
|
// if it gets further transpiled by babel spread args transform (will be .call.apply(...).
|
|
184
160
|
const thisEx = _core.types.thisExpression();
|
|
185
|
-
|
|
186
161
|
const hasSpread = node.arguments.some(_core.types.isSpreadElement);
|
|
187
162
|
const caller = hasSpread ? "apply" : "call";
|
|
188
163
|
const callArgs = hasSpread ? [thisEx, _core.types.arrayExpression(node.arguments)] : [thisEx, ...node.arguments];
|
|
189
164
|
path.replaceWith(_core.types.callExpression(_core.types.identifier(`${superClassName}.prototype.${methodName}.${caller}`), callArgs));
|
|
190
165
|
}
|
|
191
|
-
|
|
192
166
|
function doesClassExtendFromImport(node, imports) {
|
|
193
167
|
const superClass = node.superClass;
|
|
194
168
|
return superClass && imports.some(imported => imported === superClass.name);
|
|
195
169
|
}
|
|
196
|
-
|
|
197
170
|
function shouldConvertClass(file, node, opts, classInfo) {
|
|
198
171
|
if (classInfo.nonUI5) {
|
|
199
172
|
return false;
|
|
200
173
|
}
|
|
201
|
-
|
|
202
174
|
if (opts.autoConvertAllExtendClasses == true) {
|
|
203
175
|
return true;
|
|
204
176
|
}
|
|
205
|
-
|
|
206
177
|
if (classInfo.name || classInfo.alias || classInfo.controller || classInfo.namespace) {
|
|
207
178
|
return true;
|
|
208
179
|
}
|
|
209
|
-
|
|
210
180
|
if (/.*[.]controller[.]js$/.test(file.opts.filename) && opts.autoConvertControllerClass !== false) {
|
|
211
181
|
return true;
|
|
212
182
|
}
|
|
213
|
-
|
|
214
183
|
return false;
|
|
215
184
|
}
|