@qooxdoo/framework 7.0.0-beta.3 → 7.0.0-beta.7
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 +3 -0
- package/Manifest.json +1 -1
- package/README.md +9 -3
- package/lib/compiler/compile-info.json +60 -58
- package/lib/compiler/index.js +3242 -1883
- package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -1
- package/lib/resource/qx/tool/loadsass.js +6 -4
- package/lib/resource/qx/tool/schema/compile-1-0-0.json +6 -11
- package/package.json +17 -3
- package/source/class/qx/Bootstrap.js +22 -1
- package/source/class/qx/bom/Blocker.js +2 -1
- package/source/class/qx/core/Environment.js +3 -12
- package/source/class/qx/core/MProperty.js +1 -1
- package/source/class/qx/dev/unit/Sinon.js +1 -1
- package/source/class/qx/io/__init__.js +5 -3
- package/source/class/qx/io/exception/Cancel.js +34 -0
- package/source/class/qx/io/exception/Exception.js +38 -0
- package/source/class/qx/io/exception/Protocol.js +26 -0
- package/source/class/qx/io/exception/Transport.js +39 -0
- package/source/class/qx/io/exception/__init__.js +4 -0
- package/source/class/qx/io/graphql/Client.js +112 -0
- package/source/class/qx/io/graphql/__init__.js +9 -0
- package/source/class/qx/io/graphql/protocol/Message.js +65 -0
- package/source/class/qx/io/graphql/protocol/Request.js +95 -0
- package/source/class/qx/io/graphql/protocol/Response.js +61 -0
- package/source/class/qx/io/graphql/protocol/__init__.js +6 -0
- package/source/class/qx/io/jsonrpc/Client.js +323 -0
- package/source/class/qx/io/jsonrpc/__init__.js +15 -0
- package/source/class/qx/io/jsonrpc/protocol/Batch.js +97 -0
- package/source/class/qx/io/jsonrpc/protocol/Error.js +63 -0
- package/source/class/qx/io/jsonrpc/protocol/Message.js +48 -0
- package/source/class/qx/io/jsonrpc/protocol/Notification.js +45 -0
- package/source/class/qx/io/jsonrpc/protocol/Parser.js +81 -0
- package/source/class/qx/io/jsonrpc/protocol/Request.js +93 -0
- package/source/class/qx/io/jsonrpc/protocol/Result.js +48 -0
- package/source/class/qx/io/jsonrpc/protocol/__init__.js +5 -0
- package/source/class/qx/io/request/authentication/Bearer.js +52 -0
- package/source/class/qx/io/transport/AbstractClient.js +100 -0
- package/source/class/qx/io/transport/AbstractTransport.js +41 -0
- package/source/class/qx/io/transport/Fetch.js +95 -0
- package/source/class/qx/io/transport/ITransport.js +40 -0
- package/source/class/qx/io/transport/PostMessage.js +55 -0
- package/source/class/qx/io/transport/Websocket.js +97 -0
- package/source/class/qx/io/transport/Xhr.js +139 -0
- package/source/class/qx/io/transport/__init__.js +18 -0
- package/source/class/qx/test/core/Assert.js +1 -1
- package/source/class/qx/test/core/Environment.js +0 -3
- package/source/class/qx/test/io/MAssert.js +46 -0
- package/source/class/qx/test/io/graphql/Client.js +169 -0
- package/source/class/qx/test/io/graphql/ClientFetch.js +34 -0
- package/source/class/qx/test/io/graphql/Request.js +42 -0
- package/source/class/qx/test/io/jsonrpc/Client.js +267 -0
- package/source/class/qx/test/io/jsonrpc/Protocol.js +80 -0
- package/source/class/qx/test/io/transport/PostMessage.js +56 -0
- package/source/class/qx/test/io/transport/Websocket.js +63 -0
- package/source/class/qx/test/ui/embed/Iframe.js +1 -1
- package/source/class/qx/test/util/DateFormat.js +45 -6
- package/source/class/qx/tool/cli/Cli.js +1 -0
- package/source/class/qx/tool/cli/commands/Compile.js +13 -3
- package/source/class/qx/tool/cli/commands/Es6ify.js +93 -0
- package/source/class/qx/tool/cli/commands/package/Install.js +1 -1
- package/source/class/qx/tool/cli/commands/package/Publish.js +14 -0
- package/source/class/qx/tool/compiler/ClassFile.js +67 -27
- package/source/class/qx/tool/compiler/Es6ify.js +368 -0
- package/source/class/qx/tool/compiler/makers/AppMaker.js +2 -1
- package/source/class/qx/tool/compiler/targets/Target.js +57 -47
- package/source/class/qx/tool/compiler/targets/meta/AbstractJavascriptMeta.js +25 -18
- package/source/class/qx/tool/compiler/targets/meta/BootJs.js +16 -16
- package/source/class/qx/tool/compiler/targets/meta/PolyfillJs.js +11 -3
- package/source/class/qx/tool/compiler/targets/meta/Uglify.js +10 -10
- package/source/class/qx/ui/core/Widget.js +70 -0
- package/source/class/qx/ui/decoration/MLinearBackgroundGradient.js +2 -1
- package/source/class/qx/ui/form/ComboBox.js +8 -3
- package/source/class/qx/ui/form/DateField.js +16 -1
- package/source/class/qx/ui/form/MenuButton.js +8 -4
- package/source/class/qx/ui/form/SelectBox.js +8 -3
- package/source/class/qx/ui/menu/AbstractButton.js +12 -8
- package/source/class/qx/ui/menu/Menu.js +18 -8
- package/source/class/qx/ui/table/pane/Model.js +10 -4
- package/source/class/qx/ui/window/Window.js +8 -0
- package/source/class/qx/util/format/DateFormat.js +44 -17
- package/source/resource/qx/tool/loadsass.js +6 -4
- package/source/resource/qx/tool/schema/compile-1-0-0.json +6 -11
- package/source/translation/hr.po +297 -0
- package/lib/resource/qx/static/blank.gif +0 -0
- package/source/class/qx/io/remote/Exchange.js +0 -1063
- package/source/class/qx/io/remote/Request.js +0 -1021
- package/source/class/qx/io/remote/RequestQueue.js +0 -521
- package/source/class/qx/io/remote/Response.js +0 -137
- package/source/class/qx/io/remote/Rpc.js +0 -1075
- package/source/class/qx/io/remote/RpcError.js +0 -198
- package/source/class/qx/io/remote/__init__.js +0 -88
- package/source/class/qx/io/remote/transport/Abstract.js +0 -513
- package/source/class/qx/io/remote/transport/Iframe.js +0 -652
- package/source/class/qx/io/remote/transport/Script.js +0 -475
- package/source/class/qx/io/remote/transport/XmlHttp.js +0 -1019
- package/source/class/qx/io/remote/transport/__init__.js +0 -3
- package/source/class/qx/test/io/remote/AbstractRequest.js +0 -150
- package/source/class/qx/test/io/remote/RequestIframe.js +0 -105
- package/source/class/qx/test/io/remote/RequestXhr.js +0 -151
- package/source/class/qx/test/io/remote/Rpc.js +0 -205
- package/source/class/qx/test/io/remote/__init__.js +0 -4
- package/source/class/qx/test/io/remote/transport/Iframe.js +0 -67
- package/source/class/qx/test/io/remote/transport/XmlHttp.js +0 -133
- package/source/class/qx/test/io/remote/transport/__init__.js +0 -4
|
@@ -99,6 +99,14 @@ qx.Class.define("qx.tool.cli.commands.package.Publish", {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
|
+
events: {
|
|
103
|
+
/**
|
|
104
|
+
* Fired before commit happens. Data is an object with
|
|
105
|
+
* version: new_version,
|
|
106
|
+
* argv: this.argv
|
|
107
|
+
*/
|
|
108
|
+
"beforeCommit": "qx.event.type.Data"
|
|
109
|
+
},
|
|
102
110
|
|
|
103
111
|
members: {
|
|
104
112
|
|
|
@@ -337,6 +345,12 @@ qx.Class.define("qx.tool.cli.commands.package.Publish", {
|
|
|
337
345
|
}
|
|
338
346
|
}
|
|
339
347
|
|
|
348
|
+
await this.fireDataEventAsync("beforeCommit", {
|
|
349
|
+
version: new_version,
|
|
350
|
+
argv: this.argv
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
|
|
340
354
|
if (argv.dryrun) {
|
|
341
355
|
qx.tool.compiler.Console.info(`Dry run: not creating tag and release '${tag}' of ${repo_name}...`);
|
|
342
356
|
return;
|
|
@@ -43,6 +43,9 @@ function collapseMemberExpression(node) {
|
|
|
43
43
|
if (node.type == "ThisExpression") {
|
|
44
44
|
return "this";
|
|
45
45
|
}
|
|
46
|
+
if (node.type == "Super") {
|
|
47
|
+
return "super";
|
|
48
|
+
}
|
|
46
49
|
if (node.type == "Identifier") {
|
|
47
50
|
return node.name;
|
|
48
51
|
}
|
|
@@ -362,7 +365,10 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
362
365
|
[ require.resolve("@babel/preset-typescript") ],
|
|
363
366
|
[ require.resolve("@babel/preset-react"), qx.tool.compiler.ClassFile.JSX_OPTIONS ]
|
|
364
367
|
],
|
|
365
|
-
parserOpts: {
|
|
368
|
+
parserOpts: {
|
|
369
|
+
allowSuperOutsideMethod: true,
|
|
370
|
+
sourceType: "script"
|
|
371
|
+
},
|
|
366
372
|
passPerPreset: true
|
|
367
373
|
};
|
|
368
374
|
if (extraPreset[0].plugins.length) {
|
|
@@ -780,7 +786,9 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
780
786
|
return meta;
|
|
781
787
|
}
|
|
782
788
|
|
|
789
|
+
var es6ClassDeclarations = 0;
|
|
783
790
|
var needsQxCoreEnvironment = false;
|
|
791
|
+
|
|
784
792
|
var COLLECT_CLASS_NAMES_VISITOR = {
|
|
785
793
|
MemberExpression(path) {
|
|
786
794
|
var self = this;
|
|
@@ -794,6 +802,15 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
794
802
|
};
|
|
795
803
|
|
|
796
804
|
const CODE_ELIMINATION_VISITOR = {
|
|
805
|
+
ClassBody: {
|
|
806
|
+
enter(path) {
|
|
807
|
+
es6ClassDeclarations++;
|
|
808
|
+
},
|
|
809
|
+
exit(path) {
|
|
810
|
+
es6ClassDeclarations--;
|
|
811
|
+
}
|
|
812
|
+
},
|
|
813
|
+
|
|
797
814
|
CallExpression(path) {
|
|
798
815
|
const name = collapseMemberExpression(path.node.callee);
|
|
799
816
|
|
|
@@ -921,8 +938,12 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
921
938
|
let nextJsonPath = jsonPath ? jsonPath + "." : "";
|
|
922
939
|
node.properties.forEach(function(prop) {
|
|
923
940
|
var key = prop.key.name;
|
|
924
|
-
|
|
925
|
-
|
|
941
|
+
if (prop.type == "ObjectMethod") {
|
|
942
|
+
result[key] = "[[ ObjectMethod Function ]]";
|
|
943
|
+
} else {
|
|
944
|
+
var value = collectJson(prop.value, isProperties, nextJsonPath + key);
|
|
945
|
+
result[key] = value;
|
|
946
|
+
}
|
|
926
947
|
});
|
|
927
948
|
} else if (node.type == "Literal" ||
|
|
928
949
|
node.type == "StringLiteral" ||
|
|
@@ -1080,6 +1101,15 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1080
1101
|
}
|
|
1081
1102
|
|
|
1082
1103
|
var CLASS_DEF_VISITOR = {
|
|
1104
|
+
ClassBody: {
|
|
1105
|
+
enter(path) {
|
|
1106
|
+
es6ClassDeclarations++;
|
|
1107
|
+
},
|
|
1108
|
+
exit(path) {
|
|
1109
|
+
es6ClassDeclarations--;
|
|
1110
|
+
}
|
|
1111
|
+
},
|
|
1112
|
+
|
|
1083
1113
|
ObjectMethod(path) {
|
|
1084
1114
|
if (path.parentPath.parentPath != this.classDefPath) {
|
|
1085
1115
|
path.skip();
|
|
@@ -1304,6 +1334,16 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1304
1334
|
}
|
|
1305
1335
|
},
|
|
1306
1336
|
|
|
1337
|
+
// Babel seems to be suppressing ClassDeclarations...
|
|
1338
|
+
ClassBody: {
|
|
1339
|
+
enter(path) {
|
|
1340
|
+
es6ClassDeclarations++;
|
|
1341
|
+
},
|
|
1342
|
+
exit(path) {
|
|
1343
|
+
es6ClassDeclarations--;
|
|
1344
|
+
}
|
|
1345
|
+
},
|
|
1346
|
+
|
|
1307
1347
|
Literal(path) {
|
|
1308
1348
|
if (typeof path.node.value == "string") {
|
|
1309
1349
|
path.node.value = t.encodePrivate(path.node.value, false, path.loc);
|
|
@@ -1420,7 +1460,7 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1420
1460
|
}
|
|
1421
1461
|
}
|
|
1422
1462
|
|
|
1423
|
-
if (types.isMemberExpression(path.node.callee)) {
|
|
1463
|
+
if (types.isMemberExpression(path.node.callee) || (es6ClassDeclarations == 0 && (path.node.callee.object?.type == "Super" || path.node.callee.type == "Super"))) {
|
|
1424
1464
|
let name = collapseMemberExpression(path.node.callee);
|
|
1425
1465
|
let thisAlias = null;
|
|
1426
1466
|
|
|
@@ -1431,7 +1471,7 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1431
1471
|
// var that = this, args = arguments;
|
|
1432
1472
|
// (function() { that.base(args); })();
|
|
1433
1473
|
// ```
|
|
1434
|
-
if (path.node.callee.object
|
|
1474
|
+
if (path.node.callee.object?.type == "Identifier") {
|
|
1435
1475
|
let originalAlias = path.node.callee.object.name;
|
|
1436
1476
|
let alias = originalAlias;
|
|
1437
1477
|
let aliasIsThis = false;
|
|
@@ -1536,7 +1576,7 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1536
1576
|
path.skip();
|
|
1537
1577
|
path.traverse(VISITOR);
|
|
1538
1578
|
|
|
1539
|
-
} else if (name == "this.base") {
|
|
1579
|
+
} else if (name == "this.base" || (es6ClassDeclarations == 0 && (name == "super" || name.startsWith("super.")))) {
|
|
1540
1580
|
let expr;
|
|
1541
1581
|
|
|
1542
1582
|
// For mixins, there is never a valid time to call this.base() in the constructor; but it is
|
|
@@ -1558,10 +1598,11 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1558
1598
|
} else {
|
|
1559
1599
|
expr = expandMemberExpression(t.__classMeta.superClass + ".prototype." + t.__classMeta.functionName + ".call");
|
|
1560
1600
|
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1601
|
+
let thisArgument = thisAlias ? types.identifier(thisAlias) : types.thisExpression();
|
|
1602
|
+
if (name.startsWith("super")) {
|
|
1603
|
+
path.node.arguments.unshift(thisArgument);
|
|
1563
1604
|
} else {
|
|
1564
|
-
path.node.arguments[0] =
|
|
1605
|
+
path.node.arguments[0] = thisArgument;
|
|
1565
1606
|
}
|
|
1566
1607
|
let callExpr = types.callExpression(expr, path.node.arguments);
|
|
1567
1608
|
path.replaceWith(callExpr);
|
|
@@ -1727,25 +1768,24 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1727
1768
|
},
|
|
1728
1769
|
|
|
1729
1770
|
ObjectMethod(path) {
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1771
|
+
// Methods within a top level object (ie "members" or "statics"), record the method name and meta data
|
|
1772
|
+
if (t.__classMeta &&
|
|
1773
|
+
t.__classMeta._topLevel &&
|
|
1774
|
+
t.__classMeta._topLevel.path == path.parentPath.parentPath) {
|
|
1775
|
+
t.__classMeta.functionName = getKeyName(path.node.key);
|
|
1776
|
+
makeMeta(t.__classMeta._topLevel.keyName, t.__classMeta.functionName, path.node);
|
|
1777
|
+
path.skip();
|
|
1778
|
+
enterFunction(path);
|
|
1779
|
+
path.traverse(VISITOR);
|
|
1780
|
+
exitFunction(path);
|
|
1781
|
+
t.__classMeta.functionName = null;
|
|
1741
1782
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
}
|
|
1783
|
+
// Otherwise traverse method as normal
|
|
1784
|
+
} else {
|
|
1785
|
+
path.skip();
|
|
1786
|
+
enterFunction(path);
|
|
1787
|
+
path.traverse(VISITOR);
|
|
1788
|
+
exitFunction(path);
|
|
1749
1789
|
}
|
|
1750
1790
|
},
|
|
1751
1791
|
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the new era of web development
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2021 Zenesis Ltd
|
|
9
|
+
|
|
10
|
+
License:
|
|
11
|
+
MIT: https://opensource.org/licenses/MIT
|
|
12
|
+
See the LICENSE file in the project's top-level directory for details.
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
* John Spackman (john.spackman@zenesis.com, @johnspackman)
|
|
16
|
+
|
|
17
|
+
************************************************************************ */
|
|
18
|
+
|
|
19
|
+
const fs = require("fs");
|
|
20
|
+
const path = require("path");
|
|
21
|
+
const babelCore = require("@babel/core");
|
|
22
|
+
|
|
23
|
+
const types = require("@babel/types");
|
|
24
|
+
const babylon = require("@babel/parser");
|
|
25
|
+
const prettier = require("prettier");
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Helper method that collapses the MemberExpression into a string
|
|
29
|
+
* @param node
|
|
30
|
+
* @returns {string}
|
|
31
|
+
*/
|
|
32
|
+
function collapseMemberExpression(node) {
|
|
33
|
+
var done = false;
|
|
34
|
+
function doCollapse(node) {
|
|
35
|
+
if (node.type == "ThisExpression") {
|
|
36
|
+
return "this";
|
|
37
|
+
}
|
|
38
|
+
if (node.type == "Identifier") {
|
|
39
|
+
return node.name;
|
|
40
|
+
}
|
|
41
|
+
if (node.type == "ArrayExpression") {
|
|
42
|
+
var result = [];
|
|
43
|
+
node.elements.forEach(element => result.push(doCollapse(element)));
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
if (node.type != "MemberExpression") {
|
|
47
|
+
return "(" + node.type + ")";
|
|
48
|
+
}
|
|
49
|
+
if (types.isIdentifier(node.object)) {
|
|
50
|
+
let str = node.object.name;
|
|
51
|
+
if (node.property.name) {
|
|
52
|
+
str += "." + node.property.name;
|
|
53
|
+
} else {
|
|
54
|
+
done = true;
|
|
55
|
+
}
|
|
56
|
+
return str;
|
|
57
|
+
}
|
|
58
|
+
var str;
|
|
59
|
+
if (node.object.type == "ArrayExpression") {
|
|
60
|
+
str = "[]";
|
|
61
|
+
} else {
|
|
62
|
+
str = doCollapse(node.object);
|
|
63
|
+
}
|
|
64
|
+
if (done) {
|
|
65
|
+
return str;
|
|
66
|
+
}
|
|
67
|
+
// `computed` is set if the expression is a subscript, eg `abc[def]`
|
|
68
|
+
if (node.computed) {
|
|
69
|
+
done = true;
|
|
70
|
+
} else if (node.property.name) {
|
|
71
|
+
str += "." + node.property.name;
|
|
72
|
+
} else {
|
|
73
|
+
done = true;
|
|
74
|
+
}
|
|
75
|
+
return str;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return doCollapse(node);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Processes a .js source file and tries to upgrade to ES6 syntax
|
|
83
|
+
*
|
|
84
|
+
* This is a reliable but fairly unintrusive upgrade, provided that `arrowFunctions` property is
|
|
85
|
+
* `careful`. The issue is that this code: `setTimeout(function() { something(); })` can be
|
|
86
|
+
* changed to `setTimeout(() => something())` and that is often desirable, but it also means that
|
|
87
|
+
* the `this` will be different because an arrow function always has the `this` from where the
|
|
88
|
+
* code is written.
|
|
89
|
+
*
|
|
90
|
+
* However, if you use an API which changes `this` then the switch to arrow functions will break
|
|
91
|
+
* your code. Mostly, in Qooxdoo, changes to `this` are done via an explicit API (eg
|
|
92
|
+
* `obj.addListener("changeXyx", function() {}, this)`) and so those known APIs can be translated,
|
|
93
|
+
* but there are places which do not work this way (eg the unit tests `qx.dev.unit.TestCase.resume()`).
|
|
94
|
+
* Third party integrations are of course completely unknown.
|
|
95
|
+
*
|
|
96
|
+
* If `arrowFunctions` is set to aggressive, then all functions are switched to arrow functions except
|
|
97
|
+
* where there is a known API that does not support it (eg any call to `.resume` in a test class); this
|
|
98
|
+
* could break your code.
|
|
99
|
+
*
|
|
100
|
+
* If `arrowFunctions is set to `careful` (the default), then functions are only switched to arrow
|
|
101
|
+
* functions where the API is known (eg `.addListener`).
|
|
102
|
+
*
|
|
103
|
+
* The final step is that the ES6ify will use https://prettier.io/ to reformat the code, and will use
|
|
104
|
+
* the nearest `prettierrc.json` for configuration
|
|
105
|
+
*/
|
|
106
|
+
qx.Class.define("qx.tool.compiler.Es6ify", {
|
|
107
|
+
extend: qx.core.Object,
|
|
108
|
+
|
|
109
|
+
construct(filename) {
|
|
110
|
+
this.base(arguments);
|
|
111
|
+
this.__filename = filename;
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
properties: {
|
|
115
|
+
/** Whether to convert functions to arrow functions; careful means only on things like addListener callbacks */
|
|
116
|
+
arrowFunctions: {
|
|
117
|
+
init: "careful",
|
|
118
|
+
check: [ "never", "always", "careful", "aggressive" ],
|
|
119
|
+
nullable: true
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
/** Whether to overwrite the original file */
|
|
123
|
+
overwrite: {
|
|
124
|
+
init: false,
|
|
125
|
+
check: "Boolean"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
members: {
|
|
130
|
+
__filename: null,
|
|
131
|
+
|
|
132
|
+
async transform() {
|
|
133
|
+
let src = await fs.promises.readFile(this.__filename, "utf8");
|
|
134
|
+
|
|
135
|
+
let babelConfig = {};
|
|
136
|
+
let options = qx.lang.Object.clone(babelConfig.options || {}, true);
|
|
137
|
+
options.modules = false;
|
|
138
|
+
let plugins = [
|
|
139
|
+
require("@babel/plugin-syntax-jsx"),
|
|
140
|
+
this.__pluginFunctionExpressions()
|
|
141
|
+
];
|
|
142
|
+
if (this.getArrowFunctions() != "never") {
|
|
143
|
+
plugins.push(this.__pluginArrowFunctions());
|
|
144
|
+
}
|
|
145
|
+
plugins.push(this.__pluginRemoveUnnecessaryThis());
|
|
146
|
+
plugins.push(this.__pluginSwitchToSuper());
|
|
147
|
+
var config = {
|
|
148
|
+
ast: true,
|
|
149
|
+
babelrc: false,
|
|
150
|
+
sourceFileName: this.__filename,
|
|
151
|
+
filename: this.__filename,
|
|
152
|
+
sourceMaps: false,
|
|
153
|
+
presets: [
|
|
154
|
+
[
|
|
155
|
+
{
|
|
156
|
+
plugins: plugins
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
],
|
|
160
|
+
parserOpts: {
|
|
161
|
+
allowSuperOutsideMethod: true,
|
|
162
|
+
sourceType: "script"
|
|
163
|
+
},
|
|
164
|
+
generatorOpts: {
|
|
165
|
+
retainLines: true
|
|
166
|
+
},
|
|
167
|
+
passPerPreset: true
|
|
168
|
+
};
|
|
169
|
+
let result = babelCore.transform(src, config);
|
|
170
|
+
|
|
171
|
+
let prettierConfig = await prettier.resolveConfig(this.__filename, { editorConfig: true })||{};
|
|
172
|
+
prettierConfig.parser = "babel";
|
|
173
|
+
let prettyCode = prettier.format(result.code, prettierConfig);
|
|
174
|
+
|
|
175
|
+
let outname = this.__filename + (this.isOverwrite() ? "" : ".es6ify");
|
|
176
|
+
await fs.promises.writeFile(outname, prettyCode, "utf8");
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Plugin that converts object properties which are functions into object methods, eg
|
|
181
|
+
* ```
|
|
182
|
+
* {
|
|
183
|
+
* myMethod: function() {}
|
|
184
|
+
* }
|
|
185
|
+
* ```
|
|
186
|
+
* becomes
|
|
187
|
+
* ```
|
|
188
|
+
* {
|
|
189
|
+
* myMethod() {}
|
|
190
|
+
* }
|
|
191
|
+
* ```
|
|
192
|
+
* @returns
|
|
193
|
+
*/
|
|
194
|
+
__pluginFunctionExpressions() {
|
|
195
|
+
return {
|
|
196
|
+
visitor: {
|
|
197
|
+
ObjectExpression(path) {
|
|
198
|
+
for (let i = 0; i < path.node.properties.length; i++) {
|
|
199
|
+
let propNode = path.node.properties[i];
|
|
200
|
+
if (
|
|
201
|
+
propNode.type == "ObjectProperty" &&
|
|
202
|
+
propNode.value.type == "FunctionExpression"
|
|
203
|
+
) {
|
|
204
|
+
let replacement = types.objectMethod(
|
|
205
|
+
"method",
|
|
206
|
+
propNode.key,
|
|
207
|
+
propNode.value.params,
|
|
208
|
+
propNode.value.body,
|
|
209
|
+
propNode.value.computed,
|
|
210
|
+
propNode.value.generator,
|
|
211
|
+
propNode.value.async
|
|
212
|
+
);
|
|
213
|
+
replacement.loc = propNode.loc;
|
|
214
|
+
replacement.start = propNode.start;
|
|
215
|
+
replacement.end = propNode.end;
|
|
216
|
+
replacement.leadingComments = propNode.leadingComments;
|
|
217
|
+
path.node.properties[i] = replacement;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
__toArrowExpression(argNode) {
|
|
226
|
+
let body = argNode.body;
|
|
227
|
+
if (body.body.length == 1 && body.body[0].type == "ReturnStatement") {
|
|
228
|
+
body = body.body[0].argument;
|
|
229
|
+
}
|
|
230
|
+
let replacement = types.arrowFunctionExpression(
|
|
231
|
+
argNode.params,
|
|
232
|
+
body,
|
|
233
|
+
argNode.async
|
|
234
|
+
);
|
|
235
|
+
replacement.loc = argNode.loc;
|
|
236
|
+
replacement.start = argNode.start;
|
|
237
|
+
replacement.end = argNode.end;
|
|
238
|
+
replacement.leadingComments = argNode.leadingComments;
|
|
239
|
+
return replacement;
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Tries to convert functions into arrow functions
|
|
244
|
+
* @returns
|
|
245
|
+
*/
|
|
246
|
+
__pluginArrowFunctions() {
|
|
247
|
+
let t = this;
|
|
248
|
+
const isTest = this.__filename.indexOf("/test/") > -1;
|
|
249
|
+
let arrowFunctions = this.getArrowFunctions();
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
visitor: {
|
|
253
|
+
CallExpression(path) {
|
|
254
|
+
if (path.node.callee.type == "MemberExpression") {
|
|
255
|
+
let callee = collapseMemberExpression(path.node.callee);
|
|
256
|
+
if (arrowFunctions == "careful") {
|
|
257
|
+
if (!callee.endsWith(".addListener")) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (
|
|
261
|
+
path.node.arguments.length != 3 ||
|
|
262
|
+
path.node.arguments[0].type != "StringLiteral" ||
|
|
263
|
+
path.node.arguments[1].type != "ArrowFunctionExpression" ||
|
|
264
|
+
path.node.arguments[2].type != "ThisExpression"
|
|
265
|
+
) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
} else if (arrowFunctions == "aggressive") {
|
|
270
|
+
if (callee == "qx.event.GlobalError.observeMethod" ||
|
|
271
|
+
callee == "this.assertException" ||
|
|
272
|
+
callee == "this.assertEventFired" ||
|
|
273
|
+
callee == "qx.core.Assert.assertEventFired" ||
|
|
274
|
+
(isTest && callee.endsWith(".resume"))) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
} else if (arrowFunctions == "careful") {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
for (let i = 0; i < path.node.arguments.length; i++){
|
|
282
|
+
let argNode = path.node.arguments[i];
|
|
283
|
+
if (argNode.type == "FunctionExpression") {
|
|
284
|
+
path.node.arguments[i] = t.__toArrowExpression(argNode);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Where a function has been translated into an arrow function, the this binding is not needed
|
|
294
|
+
* and can be removed
|
|
295
|
+
* @returns
|
|
296
|
+
*/
|
|
297
|
+
__pluginRemoveUnnecessaryThis() {
|
|
298
|
+
return {
|
|
299
|
+
visitor: {
|
|
300
|
+
CallExpression(path) {
|
|
301
|
+
if (
|
|
302
|
+
path.node.callee.type == "MemberExpression" &&
|
|
303
|
+
path.node.callee.object.type == "ThisExpression" &&
|
|
304
|
+
path.node.callee.property.type == "Identifier" &&
|
|
305
|
+
path.node.callee.property.name == "addListener" &&
|
|
306
|
+
path.node.arguments.length == 3 &&
|
|
307
|
+
path.node.arguments[0].type == "StringLiteral" &&
|
|
308
|
+
path.node.arguments[1].type == "ArrowFunctionExpression" &&
|
|
309
|
+
path.node.arguments[2].type == "ThisExpression"
|
|
310
|
+
) {
|
|
311
|
+
qx.lang.Array.removeAt(path.node.arguments, 2);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Translates `this.base(arguments...)` into `super`
|
|
320
|
+
* @returns
|
|
321
|
+
*/
|
|
322
|
+
__pluginSwitchToSuper() {
|
|
323
|
+
let methodNameStack = [];
|
|
324
|
+
function peekMethodName() {
|
|
325
|
+
for (let i = methodNameStack.length - 1; i >= 0; i--) {
|
|
326
|
+
let methodName = methodNameStack[i];
|
|
327
|
+
if (methodName) {
|
|
328
|
+
return methodName;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
visitor: {
|
|
335
|
+
ObjectMethod: {
|
|
336
|
+
enter(path) {
|
|
337
|
+
methodNameStack.push(path.node.key.name||null);
|
|
338
|
+
},
|
|
339
|
+
exit(path) {
|
|
340
|
+
methodNameStack.pop();
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
CallExpression(path) {
|
|
344
|
+
if (
|
|
345
|
+
path.node.callee.type == "MemberExpression" &&
|
|
346
|
+
path.node.callee.object.type == "ThisExpression" &&
|
|
347
|
+
path.node.callee.property.type == "Identifier" &&
|
|
348
|
+
path.node.callee.property.name == "base" &&
|
|
349
|
+
path.node.arguments.length >= 1
|
|
350
|
+
) {
|
|
351
|
+
let args = qx.lang.Array.clone(path.node.arguments);
|
|
352
|
+
args.shift();
|
|
353
|
+
let methodName = peekMethodName();
|
|
354
|
+
if (methodName == "construct") {
|
|
355
|
+
path.node.callee = types.super();
|
|
356
|
+
path.node.arguments = args;
|
|
357
|
+
} else if (methodName) {
|
|
358
|
+
let replacement = types.memberExpression(types.super(), types.identifier(methodName), false, false);
|
|
359
|
+
path.node.callee = replacement;
|
|
360
|
+
path.node.arguments = args;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
});
|