babel-plugin-vasille 3.1.5 → 3.2.1
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/README.md +5 -4
- package/lib/bridge.js +173 -0
- package/lib/call.js +30 -19
- package/lib/css-transformer.js +4 -4
- package/lib/expression.js +50 -23
- package/lib/jsx.js +20 -6
- package/lib/lib.js +26 -20
- package/lib/mesh.js +182 -50
- package/lib/router.js +41 -0
- package/lib/transformer.js +6 -0
- package/lib/utils.js +50 -0
- package/lib-node/bridge.js +173 -0
- package/lib-node/call.js +30 -19
- package/lib-node/css-transformer.js +4 -4
- package/lib-node/expression.js +50 -23
- package/lib-node/jsx.js +25 -11
- package/lib-node/lib.js +26 -20
- package/lib-node/mesh.js +182 -50
- package/lib-node/router.js +41 -0
- package/lib-node/transformer.js +6 -0
- package/lib-node/utils.js +50 -0
- package/package.json +10 -11
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* [Installation](#installation)
|
|
12
12
|
* [How to use Vasille](#how-to-use-vasille)
|
|
13
13
|
* [How SAFE is Vasille](#how-safe-is-vasille)
|
|
14
|
-
* [How
|
|
14
|
+
* [How INTUITIVE is Vasille](#how-intuitive-is-vasille)
|
|
15
15
|
* [How POWERFUL is Vasille](#how-powerful-is-vasille)
|
|
16
16
|
* [Road Map](#road-map)
|
|
17
17
|
|
|
@@ -44,6 +44,7 @@ $ npx degit vasille-js/example-javascript my-project
|
|
|
44
44
|
|
|
45
45
|
### Full documentation:
|
|
46
46
|
* [Learn `Vasille` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/v3/doc/V3-API.md)
|
|
47
|
+
* [Vasille Router Documentation](https://github.com/vasille-js/vasille-js/blob/v3/doc/Router-API.md)
|
|
47
48
|
|
|
48
49
|
### Examples
|
|
49
50
|
* [TypeScript Example](https://github.com/vasille-js/example-typescript)
|
|
@@ -60,7 +61,7 @@ The safe of your application is ensured by
|
|
|
60
61
|
* `strong typing` makes your javascript/typescript code safe as C++ code.
|
|
61
62
|
All entities of `vasille` core library are strongly typed, including:
|
|
62
63
|
* data fields & properties.
|
|
63
|
-
* computed properties (function parameters
|
|
64
|
+
* computed properties (function parameters and result).
|
|
64
65
|
* methods.
|
|
65
66
|
* events (defined handlers & event emit).
|
|
66
67
|
* DOM events & DOM operation (attributing, styling, etc.).
|
|
@@ -68,7 +69,7 @@ All entities of `vasille` core library are strongly typed, including:
|
|
|
68
69
|
* references to children.
|
|
69
70
|
* No asynchronous code, when the line of code is executed, the DOM and reactive things are already synced.
|
|
70
71
|
|
|
71
|
-
## How
|
|
72
|
+
## How INTUITIVE is Vasille
|
|
72
73
|
|
|
73
74
|
There is the "Hello World":
|
|
74
75
|
```typescript jsx
|
|
@@ -105,7 +106,7 @@ All of these are supported:
|
|
|
105
106
|
* [x] Develop the `Vasille Babel Plugin`.
|
|
106
107
|
* [x] `100%` Test Coverage fot babel plugin.
|
|
107
108
|
* [x] Add CSS support (define styles in components).
|
|
108
|
-
* [
|
|
109
|
+
* [x] Add router.
|
|
109
110
|
* [ ] Add SSR (server side rendering).
|
|
110
111
|
* [ ] Develop tools extension for debugging.
|
|
111
112
|
|
package/lib/bridge.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.processBridgeCall = processBridgeCall;
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
const expression_1 = require("./expression");
|
|
39
|
+
const lib_1 = require("./lib");
|
|
40
|
+
const mesh_1 = require("./mesh");
|
|
41
|
+
const utils_1 = require("./utils");
|
|
42
|
+
const bridgeConstName = "bridge";
|
|
43
|
+
function processBridgeCall(path, internal, search) {
|
|
44
|
+
const node = path.node;
|
|
45
|
+
if (t.isCallExpression(node) && t.isMemberExpression(node.callee)) {
|
|
46
|
+
const callee = node.callee;
|
|
47
|
+
let propName = null;
|
|
48
|
+
if (t.isIdentifier(callee.object)) {
|
|
49
|
+
const mapped = internal.mapping.get(callee.object.name);
|
|
50
|
+
if (mapped && mapped === bridgeConstName && internal.stack.get(callee.object.name) === undefined) {
|
|
51
|
+
propName = (0, utils_1.stringify)(callee.property);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (t.isMemberExpression(callee.object) && t.isIdentifier(callee.object.object)) {
|
|
55
|
+
const rootName = callee.object.object.name;
|
|
56
|
+
if (rootName === internal.global &&
|
|
57
|
+
internal.stack.get(rootName) === undefined &&
|
|
58
|
+
(0, utils_1.stringify)(callee.object.property) === bridgeConstName) {
|
|
59
|
+
propName = (0, utils_1.stringify)(callee.property);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (propName) {
|
|
63
|
+
const getArg = (mesh = true) => {
|
|
64
|
+
if (node.arguments.length !== 1 || !t.isExpression(node.arguments[0])) {
|
|
65
|
+
throw path.buildCodeFrameError("Vasille: Expected 1 argument");
|
|
66
|
+
}
|
|
67
|
+
if (mesh) {
|
|
68
|
+
(0, mesh_1.meshExpression)(path.get("arguments")[0], internal);
|
|
69
|
+
}
|
|
70
|
+
return node.arguments[0];
|
|
71
|
+
};
|
|
72
|
+
const callWithArg = (name) => {
|
|
73
|
+
path.replaceWith(t.callExpression(t.memberExpression(internal.id, t.identifier(name)), [getArg()]));
|
|
74
|
+
};
|
|
75
|
+
const callWithOptionalArg = (name) => {
|
|
76
|
+
if (node.arguments.length === 0) {
|
|
77
|
+
path.replaceWith(t.callExpression(t.memberExpression(internal.id, t.identifier(name)), []));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
callWithArg(name);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
switch (propName) {
|
|
84
|
+
case "ref": {
|
|
85
|
+
callWithArg("r");
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "bind": {
|
|
89
|
+
const arg = getArg(false);
|
|
90
|
+
const result = (0, expression_1.checkNode)(path.get("arguments")[0], internal);
|
|
91
|
+
if (result.self) {
|
|
92
|
+
path.replaceWith(result.self);
|
|
93
|
+
}
|
|
94
|
+
else if (result.found.size > 0) {
|
|
95
|
+
const found = result.found;
|
|
96
|
+
path.replaceWith(t.callExpression(t.memberExpression(internal.id, t.identifier("ex")), [
|
|
97
|
+
t.arrowFunctionExpression([...found.keys()].map(expression_1.encodeName), arg),
|
|
98
|
+
t.arrayExpression([...found.values()]),
|
|
99
|
+
]));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
callWithArg("r");
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case "calculate":
|
|
107
|
+
case "watch": {
|
|
108
|
+
const args = (0, lib_1.processCalculateCall)(path, internal);
|
|
109
|
+
path.replaceWith(t.callExpression(t.memberExpression(internal.id, t.identifier("ex")), args));
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case "arrayModel": {
|
|
113
|
+
callWithOptionalArg("sam");
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case "setModel": {
|
|
117
|
+
callWithOptionalArg("ssm");
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case "mapModel": {
|
|
121
|
+
callWithOptionalArg("smm");
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
case "reactiveObject": {
|
|
125
|
+
callWithArg("sro");
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case "value": {
|
|
129
|
+
if (!search) {
|
|
130
|
+
path.replaceWith(t.memberExpression(getArg(), t.identifier("$")));
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
path.replaceWith(getArg());
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case "setValue": {
|
|
138
|
+
if (node.arguments.length !== 2 || !t.isExpression(node.arguments[0]) || !t.isExpression(node.arguments[1])) {
|
|
139
|
+
throw path.buildCodeFrameError("Vasille: Expected 2 arguments");
|
|
140
|
+
}
|
|
141
|
+
(0, mesh_1.meshExpression)(path.get("arguments")[0], internal);
|
|
142
|
+
if (search) {
|
|
143
|
+
(0, expression_1.checkExpression)(path.get("arguments")[1], search);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
(0, mesh_1.meshExpression)(path.get("arguments")[1], internal);
|
|
147
|
+
}
|
|
148
|
+
path.replaceWith(t.assignmentExpression("=", t.memberExpression(node.arguments[0], t.identifier("$")), node.arguments[1]));
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case "stored": {
|
|
152
|
+
const arg = getArg(false);
|
|
153
|
+
if ((t.isIdentifier(arg) && (0, expression_1.idIsIValue)(path.get("arguments")[0], internal)) ||
|
|
154
|
+
(t.isMemberExpression(arg) && (0, expression_1.memberIsIValue)(arg, internal))) {
|
|
155
|
+
path.replaceWith(t.memberExpression(arg, t.identifier("$")));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
callWithArg("rv");
|
|
159
|
+
}
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case "destroy": {
|
|
163
|
+
path.replaceWith(t.callExpression(t.memberExpression(getArg(true), t.identifier("destroy")), []));
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
default:
|
|
167
|
+
throw path.buildCodeFrameError(`Vasille: Unknown bridge method "${propName}"`);
|
|
168
|
+
}
|
|
169
|
+
return propName;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return false;
|
|
173
|
+
}
|
package/lib/call.js
CHANGED
|
@@ -40,6 +40,7 @@ const internal_js_1 = require("./internal.js");
|
|
|
40
40
|
exports.composeOnly = [
|
|
41
41
|
"forward",
|
|
42
42
|
"watch",
|
|
43
|
+
"calculate",
|
|
43
44
|
"ref",
|
|
44
45
|
"bind",
|
|
45
46
|
"value",
|
|
@@ -48,6 +49,8 @@ exports.composeOnly = [
|
|
|
48
49
|
"mapModel",
|
|
49
50
|
"setModel",
|
|
50
51
|
"reactiveObject",
|
|
52
|
+
"router",
|
|
53
|
+
"runOnDestroy",
|
|
51
54
|
];
|
|
52
55
|
exports.styleOnly = [
|
|
53
56
|
"theme",
|
|
@@ -61,29 +64,37 @@ exports.styleOnly = [
|
|
|
61
64
|
];
|
|
62
65
|
exports.requiresContext = ["awaited"];
|
|
63
66
|
const requiresContextSet = new Set(exports.requiresContext);
|
|
64
|
-
function
|
|
67
|
+
function checkCall(path, name, internal) {
|
|
68
|
+
const node = path.node;
|
|
69
|
+
if (requiresContextSet.has(name) && t.isCallExpression(node)) {
|
|
70
|
+
if (internal.stateOnly) {
|
|
71
|
+
throw path.buildCodeFrameError(`Vasille: ${name} function can be used only in components`);
|
|
72
|
+
}
|
|
73
|
+
node.arguments.unshift(internal_js_1.ctx);
|
|
74
|
+
}
|
|
75
|
+
if (name === "store") {
|
|
76
|
+
internal.stateOnly = true;
|
|
77
|
+
}
|
|
78
|
+
if (["compose", "view", "mvcView", "mvvmView", "hybridView", "screen"].includes(name)) {
|
|
79
|
+
internal.stateOnly = false;
|
|
80
|
+
}
|
|
81
|
+
return name;
|
|
82
|
+
}
|
|
83
|
+
function calls(path, names, internal) {
|
|
84
|
+
const node = path.node;
|
|
65
85
|
const set = new Set(names);
|
|
66
86
|
const callee = t.isCallExpression(node) ? node.callee : null;
|
|
67
87
|
if (callee) {
|
|
68
88
|
if (t.isIdentifier(callee)) {
|
|
69
89
|
const mapped = internal.mapping.get(callee.name);
|
|
70
90
|
if (mapped && set.has(mapped) && internal.stack.get(callee.name) === undefined) {
|
|
71
|
-
|
|
72
|
-
node.arguments.unshift(internal_js_1.ctx);
|
|
73
|
-
}
|
|
74
|
-
if (mapped === "store") {
|
|
75
|
-
internal.stateOnly = true;
|
|
76
|
-
}
|
|
77
|
-
if (mapped === "compose") {
|
|
78
|
-
internal.stateOnly = false;
|
|
79
|
-
}
|
|
80
|
-
return mapped;
|
|
91
|
+
return checkCall(path, mapped, internal);
|
|
81
92
|
}
|
|
82
93
|
return false;
|
|
83
94
|
}
|
|
84
|
-
const global = internal.stack.get(internal.global) === undefined;
|
|
85
95
|
let propName = null;
|
|
86
96
|
if (t.isMemberExpression(callee)) {
|
|
97
|
+
/* istanbul ignore else */
|
|
87
98
|
if (t.isIdentifier(callee.property)) {
|
|
88
99
|
propName = callee.property.name;
|
|
89
100
|
}
|
|
@@ -91,13 +102,13 @@ function calls(node, names, internal) {
|
|
|
91
102
|
propName = callee.property.value;
|
|
92
103
|
}
|
|
93
104
|
}
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
105
|
+
if (propName &&
|
|
106
|
+
set.has(propName) &&
|
|
107
|
+
t.isMemberExpression(callee) &&
|
|
108
|
+
t.isIdentifier(callee.object) &&
|
|
109
|
+
callee.object.name === internal.global &&
|
|
110
|
+
internal.stack.get(internal.global) === undefined) {
|
|
111
|
+
return checkCall(path, propName, internal);
|
|
101
112
|
}
|
|
102
113
|
}
|
|
103
114
|
return false;
|
package/lib/css-transformer.js
CHANGED
|
@@ -47,7 +47,7 @@ function tryProcessProp(path, pseudo, media, internal) {
|
|
|
47
47
|
}
|
|
48
48
|
const mediaDefaults = ["mobile", "tablet", "laptop", "prefersDark", "prefersLight"];
|
|
49
49
|
function processValue(name, path, pseudo, theme, media, mediaDefault, allowFallback, internal) {
|
|
50
|
-
if ((0, call_js_1.calls)(path
|
|
50
|
+
if ((0, call_js_1.calls)(path, ["theme"], internal)) {
|
|
51
51
|
const call = path.node;
|
|
52
52
|
if (theme) {
|
|
53
53
|
throw path.buildCodeFrameError("Vasille: The theme seems the be defined twice");
|
|
@@ -61,14 +61,14 @@ function processValue(name, path, pseudo, theme, media, mediaDefault, allowFallb
|
|
|
61
61
|
.buildCodeFrameError("Vasille: Expected string literal");
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
if ((0, call_js_1.calls)(path
|
|
64
|
+
if ((0, call_js_1.calls)(path, ["dark"], internal)) {
|
|
65
65
|
if (theme) {
|
|
66
66
|
throw path.buildCodeFrameError("Vasille: The theme seem the be defined twice");
|
|
67
67
|
}
|
|
68
68
|
return processValue(name, path.get("arguments")[0], pseudo, `.dark`, media, mediaDefault, false, internal);
|
|
69
69
|
}
|
|
70
70
|
let callee;
|
|
71
|
-
if ((callee = (0, call_js_1.calls)(path
|
|
71
|
+
if ((callee = (0, call_js_1.calls)(path, mediaDefaults, internal))) {
|
|
72
72
|
const index = mediaDefaults.indexOf(callee) + 1;
|
|
73
73
|
if (mediaDefault.includes(index)) {
|
|
74
74
|
return processValue(name, path.get("arguments")[0], pseudo, theme, media, mediaDefault, false, internal);
|
|
@@ -178,7 +178,7 @@ function findStyleInNode(path, internal) {
|
|
|
178
178
|
}
|
|
179
179
|
if (t.isVariableDeclaration(path.node) &&
|
|
180
180
|
path.node.declarations.length === 1 &&
|
|
181
|
-
(0, call_js_1.calls)(path.
|
|
181
|
+
(0, call_js_1.calls)(path.get("declarations")[0].get("init"), ["styleSheet"], internal)) {
|
|
182
182
|
const call = path.node.declarations[0].init;
|
|
183
183
|
const callPath = path
|
|
184
184
|
.get("declarations")[0]
|
package/lib/expression.js
CHANGED
|
@@ -48,42 +48,37 @@ exports.checkStatements = checkStatements;
|
|
|
48
48
|
exports.checkStatement = checkStatement;
|
|
49
49
|
exports.checkFunction = checkFunction;
|
|
50
50
|
const t = __importStar(require("@babel/types"));
|
|
51
|
+
const bridge_1 = require("./bridge");
|
|
51
52
|
const call_js_1 = require("./call.js");
|
|
52
53
|
const internal_js_1 = require("./internal.js");
|
|
54
|
+
const router_1 = require("./router");
|
|
55
|
+
const utils_1 = require("./utils");
|
|
53
56
|
function encodeName(name) {
|
|
54
|
-
return
|
|
57
|
+
return insertName(name);
|
|
58
|
+
}
|
|
59
|
+
function insertName(name, search) {
|
|
60
|
+
const id = t.identifier(`Vasille_${name}`);
|
|
61
|
+
search?.inserted.add(id);
|
|
62
|
+
return id;
|
|
55
63
|
}
|
|
56
64
|
function addIdentifier(path, search) {
|
|
57
65
|
if (!search.found.has(path.node.name)) {
|
|
58
66
|
search.found.set(path.node.name, path.node);
|
|
59
67
|
}
|
|
60
|
-
path.replaceWith(
|
|
61
|
-
}
|
|
62
|
-
function stringify(node) {
|
|
63
|
-
let name = "";
|
|
64
|
-
if (t.isStringLiteral(node)) {
|
|
65
|
-
name = node.value;
|
|
66
|
-
}
|
|
67
|
-
if (t.isPrivateName(node)) {
|
|
68
|
-
name = node.id.name;
|
|
69
|
-
}
|
|
70
|
-
if (t.isIdentifier(node)) {
|
|
71
|
-
name = node.name;
|
|
72
|
-
}
|
|
73
|
-
return name;
|
|
68
|
+
path.replaceWith(insertName(path.node.name, search));
|
|
74
69
|
}
|
|
75
70
|
function extractMemberName(path, search) {
|
|
76
71
|
const names = [];
|
|
77
72
|
let it = path.node;
|
|
78
73
|
while (t.isMemberExpression(it)) {
|
|
79
|
-
const name = stringify(it.property);
|
|
74
|
+
const name = (0, utils_1.stringify)(it.property);
|
|
80
75
|
if (name === "$" && it !== path.node) {
|
|
81
76
|
throw path.buildCodeFrameError("Vasille: The reactive/observable value is nested");
|
|
82
77
|
}
|
|
83
78
|
it = it.object;
|
|
84
79
|
names.push(name);
|
|
85
80
|
}
|
|
86
|
-
names.push(stringify(it));
|
|
81
|
+
names.push((0, utils_1.stringify)(it));
|
|
87
82
|
if (t.isIdentifier(it) &&
|
|
88
83
|
search.stack.get(it.name, internal_js_1.VariableScope.Local) === 1 /* VariableState.Ignored */) {
|
|
89
84
|
throw path.buildCodeFrameError("Vasille: This node cannot be processed, the root of expression is a local variable");
|
|
@@ -92,17 +87,18 @@ function extractMemberName(path, search) {
|
|
|
92
87
|
}
|
|
93
88
|
function addMemberExpr(path, search) {
|
|
94
89
|
const name = extractMemberName(path, search);
|
|
90
|
+
/* istanbul ignore else */
|
|
95
91
|
if (!search.found.has(name)) {
|
|
96
92
|
search.found.set(name, path.node);
|
|
97
93
|
}
|
|
98
|
-
path.replaceWith(
|
|
94
|
+
path.replaceWith(insertName(name, search));
|
|
99
95
|
}
|
|
100
96
|
function addExternalIValue(path, search) {
|
|
101
97
|
const name = extractMemberName(path, search);
|
|
102
98
|
if (!search.found.has(name)) {
|
|
103
99
|
search.found.set(name, path.node.object);
|
|
104
100
|
}
|
|
105
|
-
path.replaceWith(
|
|
101
|
+
path.replaceWith(insertName(name, search));
|
|
106
102
|
}
|
|
107
103
|
function meshIdentifier(path, internal) {
|
|
108
104
|
if (idIsIValue(path, internal)) {
|
|
@@ -149,6 +145,7 @@ function meshMember(path, internal) {
|
|
|
149
145
|
}
|
|
150
146
|
function meshLValue(path, internal) {
|
|
151
147
|
const node = path.node;
|
|
148
|
+
/* istanbul ignore else */
|
|
152
149
|
if (t.isIdentifier(node)) {
|
|
153
150
|
meshIdentifier(path, internal);
|
|
154
151
|
}
|
|
@@ -157,6 +154,7 @@ function meshLValue(path, internal) {
|
|
|
157
154
|
}
|
|
158
155
|
else if (t.isArrayPattern(node)) {
|
|
159
156
|
for (const item of path.get("elements")) {
|
|
157
|
+
/* istanbul ignore else */
|
|
160
158
|
if (t.isOptionalMemberExpression(item.node) || t.isLVal(item.node)) {
|
|
161
159
|
meshLValue(item, internal);
|
|
162
160
|
}
|
|
@@ -171,6 +169,7 @@ function checkNode(path, internal) {
|
|
|
171
169
|
external: internal,
|
|
172
170
|
found: new Map(),
|
|
173
171
|
self: null,
|
|
172
|
+
inserted: new Set(),
|
|
174
173
|
stack: internal.stack,
|
|
175
174
|
};
|
|
176
175
|
if (t.isIdentifier(path.node)) {
|
|
@@ -191,6 +190,7 @@ function checkNode(path, internal) {
|
|
|
191
190
|
}
|
|
192
191
|
internal.stack.fixLocalIndex();
|
|
193
192
|
internal.stack.push();
|
|
193
|
+
/* istanbul ignore else */
|
|
194
194
|
if (t.isExpression(path.node)) {
|
|
195
195
|
checkExpression(path, search);
|
|
196
196
|
}
|
|
@@ -200,6 +200,7 @@ function checkNode(path, internal) {
|
|
|
200
200
|
}
|
|
201
201
|
function checkOrIgnoreAllExpressions(nodePaths, search) {
|
|
202
202
|
for (const path of nodePaths) {
|
|
203
|
+
/* istanbul ignore else */
|
|
203
204
|
if (t.isExpression(path.node)) {
|
|
204
205
|
checkExpression(path, search);
|
|
205
206
|
}
|
|
@@ -212,6 +213,7 @@ function checkAllExpressions(nodePaths, search) {
|
|
|
212
213
|
}
|
|
213
214
|
function checkAllUnknown(paths, internal) {
|
|
214
215
|
for (const path of paths) {
|
|
216
|
+
/* istanbul ignore else */
|
|
215
217
|
if (t.isSpreadElement(path.node)) {
|
|
216
218
|
checkExpression(path.get("argument"), internal);
|
|
217
219
|
}
|
|
@@ -221,6 +223,7 @@ function checkAllUnknown(paths, internal) {
|
|
|
221
223
|
}
|
|
222
224
|
}
|
|
223
225
|
function checkOrIgnoreExpression(path, search) {
|
|
226
|
+
/* istanbul ignore else */
|
|
224
227
|
if (t.isExpression(path.node)) {
|
|
225
228
|
checkExpression(path, search);
|
|
226
229
|
}
|
|
@@ -241,6 +244,7 @@ function checkExpression(nodePath, search) {
|
|
|
241
244
|
break;
|
|
242
245
|
}
|
|
243
246
|
case "Identifier": {
|
|
247
|
+
/* istanbul ignore else */
|
|
244
248
|
if (expr && t.isIdentifier(expr)) {
|
|
245
249
|
if (idIsIValue(nodePath, search.external, internal_js_1.VariableScope.Global) &&
|
|
246
250
|
!idIsLocal(nodePath, search.external)) {
|
|
@@ -256,11 +260,27 @@ function checkExpression(nodePath, search) {
|
|
|
256
260
|
}
|
|
257
261
|
case "CallExpression": {
|
|
258
262
|
const path = nodePath;
|
|
259
|
-
|
|
260
|
-
|
|
263
|
+
const bridge = (0, bridge_1.processBridgeCall)(path, search.external, search);
|
|
264
|
+
if (bridge) {
|
|
265
|
+
if (bridge === "value") {
|
|
266
|
+
addMemberExpr(nodePath, search);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else if ((0, call_js_1.calls)(path, ["router"], search.external)) {
|
|
270
|
+
if (!search.external.stateOnly) {
|
|
271
|
+
(0, router_1.routerReplace)(path);
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
throw path.buildCodeFrameError("Vasille: The router is not available in stores");
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
if ((0, call_js_1.calls)(path, call_js_1.composeOnly, search.external)) {
|
|
279
|
+
throw path.buildCodeFrameError("Vasille: Usage of hints is restricted here");
|
|
280
|
+
}
|
|
281
|
+
checkOrIgnoreExpression(path.get("callee"), search);
|
|
282
|
+
checkAllUnknown(path.get("arguments"), search);
|
|
261
283
|
}
|
|
262
|
-
checkOrIgnoreExpression(path.get("callee"), search);
|
|
263
|
-
checkAllUnknown(path.get("arguments"), search);
|
|
264
284
|
break;
|
|
265
285
|
}
|
|
266
286
|
case "OptionalCallExpression": {
|
|
@@ -329,6 +349,7 @@ function checkExpression(nodePath, search) {
|
|
|
329
349
|
case "UpdateExpression": {
|
|
330
350
|
const path = nodePath;
|
|
331
351
|
const arg = path.node.argument;
|
|
352
|
+
/* istanbul ignore else */
|
|
332
353
|
if (t.isLVal(arg)) {
|
|
333
354
|
meshLValue(path.get("argument"), search.external);
|
|
334
355
|
}
|
|
@@ -407,11 +428,13 @@ function checkStatements(paths, search) {
|
|
|
407
428
|
}
|
|
408
429
|
}
|
|
409
430
|
function ignoreLocals(val, search) {
|
|
431
|
+
/* istanbul ignore else */
|
|
410
432
|
if (t.isIdentifier(val)) {
|
|
411
433
|
search.stack.set(val.name, 1 /* VariableState.Ignored */);
|
|
412
434
|
}
|
|
413
435
|
else if (t.isObjectPattern(val)) {
|
|
414
436
|
for (const prop of val.properties) {
|
|
437
|
+
/* istanbul ignore else */
|
|
415
438
|
if (t.isObjectProperty(prop) && t.isIdentifier(prop.value)) {
|
|
416
439
|
search.stack.set(prop.value.name, 1 /* VariableState.Ignored */);
|
|
417
440
|
}
|
|
@@ -425,6 +448,7 @@ function ignoreLocals(val, search) {
|
|
|
425
448
|
}
|
|
426
449
|
else if (t.isArrayPattern(val)) {
|
|
427
450
|
for (const element of val.elements) {
|
|
451
|
+
/* istanbul ignore else */
|
|
428
452
|
if (element && !t.isVoidPattern(element)) {
|
|
429
453
|
ignoreLocals(element, search);
|
|
430
454
|
}
|
|
@@ -432,6 +456,7 @@ function ignoreLocals(val, search) {
|
|
|
432
456
|
}
|
|
433
457
|
else if (t.isVariableDeclaration(val)) {
|
|
434
458
|
for (const declarator of val.declarations) {
|
|
459
|
+
/* istanbul ignore else */
|
|
435
460
|
if (!t.isVoidPattern(declarator.id)) {
|
|
436
461
|
ignoreLocals(declarator.id, search);
|
|
437
462
|
}
|
|
@@ -478,6 +503,7 @@ function checkStatement(path, search) {
|
|
|
478
503
|
case "ForStatement": {
|
|
479
504
|
const _path = path;
|
|
480
505
|
const node = _path.node;
|
|
506
|
+
/* istanbul ignore else */
|
|
481
507
|
if (node.init) {
|
|
482
508
|
if (t.isExpression(node.init)) {
|
|
483
509
|
checkExpression(_path.get("init"), search);
|
|
@@ -535,6 +561,7 @@ function checkStatement(path, search) {
|
|
|
535
561
|
case "TryStatement":
|
|
536
562
|
const handlerPath = path.get("handler");
|
|
537
563
|
checkStatement(path.get("block"), search);
|
|
564
|
+
/* istanbul ignore else */
|
|
538
565
|
if (handlerPath.node) {
|
|
539
566
|
checkStatement(handlerPath.get("body"), search);
|
|
540
567
|
}
|
package/lib/jsx.js
CHANGED
|
@@ -60,6 +60,7 @@ function transformJsxArray(paths, internal) {
|
|
|
60
60
|
.replace(/\s*\n\s*/gm, "\n");
|
|
61
61
|
const call = t.callExpression(t.memberExpression(internal_js_1.ctx, t.identifier("text")), [t.stringLiteral(fixed)]);
|
|
62
62
|
call.loc = path.node.loc;
|
|
63
|
+
/* istanbul ignore else */
|
|
63
64
|
if (call.loc) {
|
|
64
65
|
for (const char of path.node.value) {
|
|
65
66
|
if (!/\s/.test(char)) {
|
|
@@ -96,7 +97,7 @@ function transformJsxExpressionContainer(path, internal, acceptSlots, isInternal
|
|
|
96
97
|
if (acceptSlots &&
|
|
97
98
|
(t.isFunctionExpression(expression) || t.isArrowFunctionExpression(expression)) &&
|
|
98
99
|
(0, jsx_detect_js_1.bodyHasJsx)(expression.body)) {
|
|
99
|
-
(0, mesh_js_1.compose)(path.get("expression"), internal, isInternalSlot);
|
|
100
|
+
(0, mesh_js_1.compose)(path.get("expression"), internal, isInternalSlot, "slot");
|
|
100
101
|
if (!isInternalSlot) {
|
|
101
102
|
if (expression.params.length < 1) {
|
|
102
103
|
expression.params.push(t.identifier(`_${internal.prefix}`));
|
|
@@ -112,11 +113,12 @@ function transformJsxExpressionContainer(path, internal, acceptSlots, isInternal
|
|
|
112
113
|
else if (isInternalSlot && (t.isFunctionExpression(expression) || t.isArrowFunctionExpression(expression))) {
|
|
113
114
|
expression.params.unshift(internal_js_1.ctx);
|
|
114
115
|
}
|
|
115
|
-
|
|
116
|
+
const exprPath = path.get("expression");
|
|
117
|
+
let call = (0, lib_js_1.exprCall)(exprPath, expression, internal);
|
|
116
118
|
if (!call && t.isIdentifier(expression) && internal.stack.get(expression.name) === 3 /* VariableState.ReactiveObject */) {
|
|
117
119
|
call = t.callExpression(t.memberExpression(internal.id, t.identifier("rop")), [expression]);
|
|
118
120
|
}
|
|
119
|
-
const result = call ??
|
|
121
|
+
const result = call ?? exprPath.node;
|
|
120
122
|
result.loc = loc;
|
|
121
123
|
return result;
|
|
122
124
|
}
|
|
@@ -151,10 +153,12 @@ function transformJsxElement(path, internal) {
|
|
|
151
153
|
const attr = attrPath.node;
|
|
152
154
|
if (t.isJSXAttribute(attr)) {
|
|
153
155
|
const name = attr.name;
|
|
156
|
+
/* istanbul ignore else */
|
|
154
157
|
if (t.isJSXIdentifier(name)) {
|
|
155
158
|
if (name.name.startsWith("on")) {
|
|
156
159
|
if (t.isJSXExpressionContainer(attr.value) && t.isExpression(attr.value.expression)) {
|
|
157
160
|
const path = attrPath.get("value");
|
|
161
|
+
/* istanbul ignore else */
|
|
158
162
|
if (t.isExpression(path.node.expression)) {
|
|
159
163
|
(0, mesh_js_1.meshExpression)(path.get("expression"), internal);
|
|
160
164
|
}
|
|
@@ -168,6 +172,7 @@ function transformJsxElement(path, internal) {
|
|
|
168
172
|
}
|
|
169
173
|
else if (name.name === "class") {
|
|
170
174
|
// class={[..]}
|
|
175
|
+
/* istanbul ignore else */
|
|
171
176
|
if (t.isJSXExpressionContainer(attr.value) && t.isArrayExpression(attr.value.expression)) {
|
|
172
177
|
const valuePath = attrPath.get("value");
|
|
173
178
|
const arrayExprPath = valuePath.get("expression");
|
|
@@ -232,8 +237,9 @@ function transformJsxElement(path, internal) {
|
|
|
232
237
|
}
|
|
233
238
|
}
|
|
234
239
|
// class={name}
|
|
235
|
-
else if (t.isJSXExpressionContainer(attr.value) && t.
|
|
236
|
-
|
|
240
|
+
else if (t.isJSXExpressionContainer(attr.value) && t.isExpression(attr.value.expression)) {
|
|
241
|
+
const expr = (0, lib_js_1.exprCall)(attrPath.get("value"), attr.value.expression, internal) ?? attr.value.expression;
|
|
242
|
+
attrs.push(t.objectProperty(t.identifier("class"), expr));
|
|
237
243
|
}
|
|
238
244
|
// class="a b"
|
|
239
245
|
else if (t.isStringLiteral(attr.value)) {
|
|
@@ -242,6 +248,7 @@ function transformJsxElement(path, internal) {
|
|
|
242
248
|
}
|
|
243
249
|
else if (name.name === "style") {
|
|
244
250
|
// style={{..}}
|
|
251
|
+
/* istanbul ignore else */
|
|
245
252
|
if (t.isJSXExpressionContainer(attr.value) && t.isObjectExpression(attr.value.expression)) {
|
|
246
253
|
const valuePath = attrPath.get("value");
|
|
247
254
|
const objectPath = valuePath.get("expression");
|
|
@@ -308,8 +315,13 @@ function transformJsxElement(path, internal) {
|
|
|
308
315
|
console.warn(attrPath.buildCodeFrameError("Vasille: This will slow down your application"));
|
|
309
316
|
}
|
|
310
317
|
}
|
|
318
|
+
else if (t.isJSXExpressionContainer(attr.value) && t.isExpression(attr.value.expression)) {
|
|
319
|
+
const expr = (0, lib_js_1.exprCall)(attrPath.get("value"), attr.value.expression, internal) ?? attr.value.expression;
|
|
320
|
+
attrs.push(t.objectProperty(t.identifier("style"), expr));
|
|
321
|
+
}
|
|
311
322
|
}
|
|
312
323
|
else {
|
|
324
|
+
/* istanbul ignore else */
|
|
313
325
|
if (!attr.value || t.isJSXExpressionContainer(attr.value)) {
|
|
314
326
|
attrs.push(idToProp(name, t.isExpression(attr.value?.expression) ? attr.value.expression : t.booleanLiteral(true)));
|
|
315
327
|
}
|
|
@@ -320,6 +332,7 @@ function transformJsxElement(path, internal) {
|
|
|
320
332
|
}
|
|
321
333
|
if (t.isJSXNamespacedName(name)) {
|
|
322
334
|
if (name.namespace.name === "bind") {
|
|
335
|
+
/* istanbul ignore else */
|
|
323
336
|
if (t.isJSXExpressionContainer(attr.value) || !attr.value) {
|
|
324
337
|
const value = t.isExpression(attr.value?.expression)
|
|
325
338
|
? (0, lib_js_1.exprCall)(attrPath.get("value").get("expression"), attr.value.expression, internal)
|
|
@@ -384,6 +397,7 @@ function transformJsxElement(path, internal) {
|
|
|
384
397
|
// <A prop=../>
|
|
385
398
|
if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {
|
|
386
399
|
// <A prop=".."/>
|
|
400
|
+
/* istanbul ignore else */
|
|
387
401
|
if (t.isStringLiteral(attr.value)) {
|
|
388
402
|
props.push(idToProp(attr.name, attr.value));
|
|
389
403
|
}
|
|
@@ -430,7 +444,7 @@ function transformJsxElement(path, internal) {
|
|
|
430
444
|
run = t.arrowFunctionExpression(params, t.blockStatement(statements));
|
|
431
445
|
}
|
|
432
446
|
}
|
|
433
|
-
const call = t.callExpression(t.identifier(name.name), [
|
|
447
|
+
const call = t.callExpression(t.identifier(name.name), [t.objectExpression(props), internal_js_1.ctx, ...(run ? [run] : [])]);
|
|
434
448
|
call.loc = path.node.loc;
|
|
435
449
|
return t.expressionStatement(call);
|
|
436
450
|
}
|