@litsx/babel-preset-litsx 0.3.0 → 0.4.0
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/dist/index.cjs +7 -1
- package/dist/index.cjs.map +1 -1
- package/dist/internal/transform-litsx-components.cjs +529 -586
- package/dist/internal/transform-litsx-components.cjs.map +1 -1
- package/dist/internal/transform-litsx-renderer-props.cjs +21 -5
- package/dist/internal/transform-litsx-renderer-props.cjs.map +1 -1
- package/dist/pipeline.cjs +8 -1
- package/dist/pipeline.cjs.map +1 -1
- package/dist/shared/transform-litsx-element-candidates-JMFlPFXK.cjs +1170 -0
- package/dist/shared/transform-litsx-element-candidates-JMFlPFXK.cjs.map +1 -0
- package/package.json +4 -2
- package/src/internal/transform-litsx-components.js +46 -231
- package/src/internal/transform-litsx-element-candidates.js +1173 -0
- package/src/internal/transform-litsx-param-rewrites.js +0 -71
- package/src/internal/transform-litsx-render-body.js +113 -0
- package/src/internal/transform-litsx-renderer-calls.js +92 -0
- package/src/internal/transform-litsx-renderer-props.js +13 -5
- package/src/pipeline.js +1 -0
|
@@ -8,82 +8,11 @@ function createThisMemberExpression(propName) {
|
|
|
8
8
|
return t.memberExpression(t.thisExpression(), t.identifier(propName));
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
function getBoundPropName(bindingInfo) {
|
|
12
|
-
if (typeof bindingInfo === "string") {
|
|
13
|
-
return bindingInfo;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (bindingInfo && typeof bindingInfo === "object") {
|
|
17
|
-
return bindingInfo.bindKey ?? null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function isPropBackedCallee(node, localNames) {
|
|
24
|
-
if (t.isIdentifier(node)) {
|
|
25
|
-
return localNames.includes(node.name);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (
|
|
29
|
-
t.isMemberExpression(node) &&
|
|
30
|
-
!node.computed &&
|
|
31
|
-
t.isIdentifier(node.object)
|
|
32
|
-
) {
|
|
33
|
-
return localNames.includes(node.object.name) && node.object.name === "props";
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function getPropBackedCalleeReplacement(node, bindings) {
|
|
40
|
-
if (t.isIdentifier(node)) {
|
|
41
|
-
const propName = getBoundPropName(bindings.get(node.name));
|
|
42
|
-
return propName ? createThisMemberExpression(propName) : node;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
t.isMemberExpression(node) &&
|
|
47
|
-
!node.computed &&
|
|
48
|
-
t.isIdentifier(node.object)
|
|
49
|
-
) {
|
|
50
|
-
const propName = getBoundPropName(bindings.get(node.object.name));
|
|
51
|
-
if (!propName) {
|
|
52
|
-
return node;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return t.memberExpression(
|
|
56
|
-
createThisMemberExpression(propName),
|
|
57
|
-
t.cloneNode(node.property),
|
|
58
|
-
false
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return node;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
11
|
export function transformJSXExpressions(jsxPath, bindings, state = null) {
|
|
66
12
|
const localNames = Array.from(bindings.keys());
|
|
67
13
|
|
|
68
14
|
jsxPath.traverse({
|
|
69
15
|
JSXExpressionContainer(expressionPath) {
|
|
70
|
-
if (t.isCallExpression(expressionPath.node.expression)) {
|
|
71
|
-
const { callee, arguments: args } = expressionPath.node.expression;
|
|
72
|
-
if (isPropBackedCallee(callee, localNames)) {
|
|
73
|
-
if (state) {
|
|
74
|
-
state.__litsxNeedsRendererCallImport = true;
|
|
75
|
-
}
|
|
76
|
-
expressionPath.node.expression = t.callExpression(
|
|
77
|
-
t.identifier("renderRendererCall"),
|
|
78
|
-
[
|
|
79
|
-
getPropBackedCalleeReplacement(callee, bindings),
|
|
80
|
-
...args,
|
|
81
|
-
]
|
|
82
|
-
);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
16
|
if (t.isIdentifier(expressionPath.node.expression)) {
|
|
88
17
|
const name = expressionPath.node.expression.name;
|
|
89
18
|
if (localNames.includes(name)) {
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createComponentInstanceRefSyncStatement,
|
|
3
|
+
hasRefProp,
|
|
4
|
+
lowerForwardedElementRefs,
|
|
5
|
+
} from "./transform-litsx-refs.js";
|
|
6
|
+
import {
|
|
7
|
+
replaceParamReferences,
|
|
8
|
+
transformJSXExpressions,
|
|
9
|
+
} from "./transform-litsx-param-rewrites.js";
|
|
10
|
+
import { transformJSXRendererCalls } from "./transform-litsx-renderer-calls.js";
|
|
11
|
+
|
|
12
|
+
let t;
|
|
13
|
+
|
|
14
|
+
export function setRenderBodyBabelTypes(nextTypes) {
|
|
15
|
+
t = nextTypes;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function createThisMemberExpression(propName) {
|
|
19
|
+
return t.memberExpression(t.thisExpression(), t.identifier(propName));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function createNestedInitializerStatement(pattern, root, defaultValue) {
|
|
23
|
+
const rootAccess = createThisMemberExpression(root);
|
|
24
|
+
let sourceExpression = rootAccess;
|
|
25
|
+
|
|
26
|
+
if (defaultValue) {
|
|
27
|
+
sourceExpression = t.logicalExpression(
|
|
28
|
+
"??",
|
|
29
|
+
t.cloneNode(rootAccess),
|
|
30
|
+
t.cloneNode(defaultValue)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return t.variableDeclaration("const", [
|
|
35
|
+
t.variableDeclarator(t.cloneNode(pattern), sourceExpression),
|
|
36
|
+
]);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function collectReturnStatement(functionPath, bindings, state) {
|
|
40
|
+
let returnStatement = null;
|
|
41
|
+
|
|
42
|
+
functionPath.traverse({
|
|
43
|
+
ReturnStatement(returnPath) {
|
|
44
|
+
if (t.isJSXElement(returnPath.node.argument)) {
|
|
45
|
+
returnStatement = returnPath.node;
|
|
46
|
+
transformJSXRendererCalls(returnPath, bindings, state);
|
|
47
|
+
transformJSXExpressions(returnPath, bindings, state);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return returnStatement;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function prepareComponentRender(functionPath, node, propertyNames, bindings, nestedInitializers, options = {}) {
|
|
56
|
+
const returnStatement = collectReturnStatement(
|
|
57
|
+
functionPath,
|
|
58
|
+
bindings,
|
|
59
|
+
options.state ?? null
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (!returnStatement) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const capturedPropAliasStatements = replaceParamReferences(
|
|
67
|
+
functionPath,
|
|
68
|
+
bindings,
|
|
69
|
+
propertyNames
|
|
70
|
+
);
|
|
71
|
+
const prefixStatements = [];
|
|
72
|
+
|
|
73
|
+
const forwardRefOptions = options.forwardRef || null;
|
|
74
|
+
const resolvedRefPropName =
|
|
75
|
+
forwardRefOptions?.propName ||
|
|
76
|
+
(propertyNames.has("ref") || hasRefProp(functionPath) ? "ref" : null);
|
|
77
|
+
let needsCallbackRef = false;
|
|
78
|
+
|
|
79
|
+
if (resolvedRefPropName) {
|
|
80
|
+
prefixStatements.push(
|
|
81
|
+
...lowerForwardedElementRefs(functionPath, resolvedRefPropName)
|
|
82
|
+
);
|
|
83
|
+
needsCallbackRef =
|
|
84
|
+
prefixStatements.some(
|
|
85
|
+
(statement) =>
|
|
86
|
+
t.isExpressionStatement(statement) &&
|
|
87
|
+
t.isCallExpression(statement.expression) &&
|
|
88
|
+
t.isIdentifier(statement.expression.callee, { name: "useCallbackRef" })
|
|
89
|
+
) || needsCallbackRef;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (resolvedRefPropName && !forwardRefOptions) {
|
|
93
|
+
prefixStatements.push(createComponentInstanceRefSyncStatement());
|
|
94
|
+
needsCallbackRef = true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (capturedPropAliasStatements.length > 0) {
|
|
98
|
+
prefixStatements.push(...capturedPropAliasStatements);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (nestedInitializers.length > 0) {
|
|
102
|
+
const initializerStatements = nestedInitializers.map(({ pattern, root, defaultValue }) =>
|
|
103
|
+
createNestedInitializerStatement(pattern, root, defaultValue)
|
|
104
|
+
);
|
|
105
|
+
prefixStatements.push(...initializerStatements);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
needsCallbackRef,
|
|
110
|
+
prefixStatements,
|
|
111
|
+
returnStatement,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
let t;
|
|
2
|
+
|
|
3
|
+
export function setRendererCallsBabelTypes(nextTypes) {
|
|
4
|
+
t = nextTypes;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function createThisMemberExpression(propName) {
|
|
8
|
+
return t.memberExpression(t.thisExpression(), t.identifier(propName));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function getBoundPropName(bindingInfo) {
|
|
12
|
+
if (typeof bindingInfo === "string") {
|
|
13
|
+
return bindingInfo;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (bindingInfo && typeof bindingInfo === "object") {
|
|
17
|
+
return bindingInfo.bindKey ?? null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isPropBackedCallee(node, localNames) {
|
|
24
|
+
if (t.isIdentifier(node)) {
|
|
25
|
+
return localNames.includes(node.name);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (
|
|
29
|
+
t.isMemberExpression(node) &&
|
|
30
|
+
!node.computed &&
|
|
31
|
+
t.isIdentifier(node.object)
|
|
32
|
+
) {
|
|
33
|
+
return localNames.includes(node.object.name) && node.object.name === "props";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getPropBackedCalleeReplacement(node, bindings) {
|
|
40
|
+
if (t.isIdentifier(node)) {
|
|
41
|
+
const propName = getBoundPropName(bindings.get(node.name));
|
|
42
|
+
return propName ? createThisMemberExpression(propName) : node;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (
|
|
46
|
+
t.isMemberExpression(node) &&
|
|
47
|
+
!node.computed &&
|
|
48
|
+
t.isIdentifier(node.object)
|
|
49
|
+
) {
|
|
50
|
+
const propName = getBoundPropName(bindings.get(node.object.name));
|
|
51
|
+
if (!propName) {
|
|
52
|
+
return node;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return t.memberExpression(
|
|
56
|
+
createThisMemberExpression(propName),
|
|
57
|
+
t.cloneNode(node.property),
|
|
58
|
+
false
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return node;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function transformJSXRendererCalls(jsxPath, bindings, state = null) {
|
|
66
|
+
const localNames = Array.from(bindings.keys());
|
|
67
|
+
|
|
68
|
+
jsxPath.traverse({
|
|
69
|
+
JSXExpressionContainer(expressionPath) {
|
|
70
|
+
if (!t.isCallExpression(expressionPath.node.expression)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const { callee, arguments: args } = expressionPath.node.expression;
|
|
75
|
+
if (!isPropBackedCallee(callee, localNames)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (state) {
|
|
80
|
+
state.__litsxNeedsRendererCallImport = true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
expressionPath.node.expression = t.callExpression(
|
|
84
|
+
t.identifier("renderRendererCall"),
|
|
85
|
+
[
|
|
86
|
+
getPropBackedCalleeReplacement(callee, bindings),
|
|
87
|
+
...args,
|
|
88
|
+
]
|
|
89
|
+
);
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import jsxSyntaxPlugin from "@babel/plugin-syntax-jsx";
|
|
2
2
|
import { decodeVirtualAttributeName } from "@litsx/jsx-authoring";
|
|
3
|
+
import { importedBindingNeedsRendererContext } from "./transform-litsx-element-candidates.js";
|
|
3
4
|
|
|
4
5
|
let t;
|
|
5
6
|
|
|
@@ -238,7 +239,7 @@ function expressionNeedsRendererContext(node, scope, seenBindings = new Set()) {
|
|
|
238
239
|
return false;
|
|
239
240
|
}
|
|
240
241
|
|
|
241
|
-
function isBindableFunctionReference(expressionPath) {
|
|
242
|
+
function isBindableFunctionReference(expressionPath, options = {}) {
|
|
242
243
|
const expression = unwrapExpression(expressionPath.node);
|
|
243
244
|
if (
|
|
244
245
|
t.isArrowFunctionExpression(expression) ||
|
|
@@ -251,7 +252,12 @@ function isBindableFunctionReference(expressionPath) {
|
|
|
251
252
|
const binding = expressionPath.scope.getBinding(expression.name);
|
|
252
253
|
const functionNode = getFunctionNodeFromBinding(binding);
|
|
253
254
|
if (!functionNode) {
|
|
254
|
-
|
|
255
|
+
const programPath = expressionPath.findParent((entry) => entry.isProgram?.());
|
|
256
|
+
return importedBindingNeedsRendererContext(
|
|
257
|
+
programPath,
|
|
258
|
+
expression.name,
|
|
259
|
+
options
|
|
260
|
+
);
|
|
255
261
|
}
|
|
256
262
|
return functionBodyNeedsRendererContext(functionNode.body, binding.path.scope, new Set([binding]));
|
|
257
263
|
}
|
|
@@ -259,7 +265,7 @@ function isBindableFunctionReference(expressionPath) {
|
|
|
259
265
|
return false;
|
|
260
266
|
}
|
|
261
267
|
|
|
262
|
-
function shouldBindRendererContext(attributePath, rawName, expressionPath) {
|
|
268
|
+
function shouldBindRendererContext(attributePath, rawName, expressionPath, options = {}) {
|
|
263
269
|
if (typeof rawName !== "string" || rawName[0] !== ".") {
|
|
264
270
|
return false;
|
|
265
271
|
}
|
|
@@ -274,7 +280,7 @@ function shouldBindRendererContext(attributePath, rawName, expressionPath) {
|
|
|
274
280
|
return false;
|
|
275
281
|
}
|
|
276
282
|
|
|
277
|
-
return isBindableFunctionReference(expressionPath);
|
|
283
|
+
return isBindableFunctionReference(expressionPath, options);
|
|
278
284
|
}
|
|
279
285
|
|
|
280
286
|
function ensureRendererBindingImport(programPath) {
|
|
@@ -342,7 +348,9 @@ export default function transformLitsxRendererProps(api) {
|
|
|
342
348
|
return;
|
|
343
349
|
}
|
|
344
350
|
|
|
345
|
-
if (!shouldBindRendererContext(path, rawName, expressionPath
|
|
351
|
+
if (!shouldBindRendererContext(path, rawName, expressionPath, {
|
|
352
|
+
filename: state.file?.opts?.filename || "",
|
|
353
|
+
})) {
|
|
346
354
|
return;
|
|
347
355
|
}
|
|
348
356
|
|
package/src/pipeline.js
CHANGED
|
@@ -11,6 +11,7 @@ const NATIVE_TRANSFORM_OPTION_KEYS = [
|
|
|
11
11
|
"inMemoryFiles",
|
|
12
12
|
"typescriptSession",
|
|
13
13
|
"suppressNativeClassNameWarning",
|
|
14
|
+
"__litsxCompilationSession",
|
|
14
15
|
];
|
|
15
16
|
|
|
16
17
|
const HOOK_FEATURE_PATTERN = /\b(?:useOnConnect|useAfterUpdate|useOnCommit|useMemoValue|useStableCallback|useEvent|useEmit|usePrevious|useReducedState|useState|useControlledState|useAsyncState|useOptimistic|useExpose|useExternalStore|useHost|useHostContent|useSlot|useTextContent|useTransition|useDeferredValue|useStyle|useRef|useCallbackRef)\b/;
|