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 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 SIMPLE is Vasille](#how-simple-is-vasille)
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 & result).
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 SIMPLE is Vasille
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
- * [ ] Add router.
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 calls(node, names, internal) {
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
- if (requiresContextSet.has(callee.name) && t.isCallExpression(node)) {
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 (t.isMemberExpression(callee) && t.isIdentifier(callee.object) && propName) {
95
- if (global && callee.object.name === internal.global && set.has(propName)) {
96
- if (requiresContextSet.has(propName) && t.isCallExpression(node)) {
97
- node.arguments.unshift(internal_js_1.ctx);
98
- }
99
- return callee.object.name;
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;
@@ -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.node, ["theme"], internal)) {
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.node, ["dark"], internal)) {
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.node, mediaDefaults, internal))) {
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.node.declarations[0].init, ["styleSheet"], internal)) {
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 t.identifier(`Vasille_${name}`);
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(encodeName(path.node.name));
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(encodeName(name));
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(encodeName(name));
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
- if ((0, call_js_1.calls)(path.node, call_js_1.composeOnly, search.external)) {
260
- throw path.buildCodeFrameError("Vasille: Usage of hints is restricted here");
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
- let call = (0, lib_js_1.exprCall)(path.get("expression"), expression, internal);
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 ?? expression;
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.isIdentifier(attr.value.expression)) {
236
- attrs.push(t.objectProperty(t.identifier("class"), attr.value.expression));
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), [internal_js_1.ctx, t.objectExpression(props), ...(run ? [run] : [])]);
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
  }