Skip to content

Commit 09c5710

Browse files
committed
v-0.0.7
1 parent a856406 commit 09c5710

8 files changed

Lines changed: 1482 additions & 227 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

index.cjs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
const { babel } = require("@rollup/plugin-babel")
2+
3+
4+
const functionVisitor = types => (path, { opts }) => {
5+
{
6+
const { mode = 'ts' } = opts
7+
8+
if (mode !== 'ts' && mode !== 'vanilla-js')
9+
throw new Error("Invalid configuration: mode must be 'ts' or 'vanilla-js'.")
10+
11+
const type = path?.type
12+
13+
if (mode === 'ts') {
14+
if (type !== "ArrowFunctionExpression") return
15+
if (path.parent?.type !== "VariableDeclarator") return
16+
const bindings = path.context?.scope?.bindings
17+
if (!path.parent?.id?.typeAnnotation) return
18+
const typeAnnotation = path.parent.id.typeAnnotation.typeAnnotation
19+
if (typeAnnotation?.type !== "TSTypeReference") return
20+
if (typeAnnotation?.typeName?.type === "Identifier") {
21+
const typeName = typeAnnotation.typeName.name
22+
const typeBinding = bindings?.[typeName]
23+
if (!typeBinding) return
24+
const importSpecifier = typeBinding.path?.node
25+
if (importSpecifier?.type !== "ImportSpecifier") return
26+
if (importSpecifier?.imported?.name !== "Component") return
27+
if (typeBinding?.path?.parent?.source?.value !== "solid-js") return
28+
}
29+
else if (typeAnnotation?.typeName?.type === "TSQualifiedName") {
30+
if (typeAnnotation.typeName?.right?.name !== "Component") return
31+
const typeQualification = typeAnnotation.typeName?.left
32+
if (typeQualification?.type !== "Identifier") return
33+
const typeQualificationName = typeQualification?.name
34+
const typeQualificationBinding = bindings?.[typeQualificationName]
35+
if (!typeQualificationBinding) return
36+
const importSpecifier = typeQualificationBinding?.path?.node
37+
if (importSpecifier?.type !== "ImportDefaultSpecifier") return
38+
if (typeQualificationBinding?.path?.parent?.source?.value !== "solid-js") return
39+
}
40+
else return
41+
}
42+
43+
if (mode === 'vanilla-js') {
44+
if (path.parent?.type !== "CallExpression") return
45+
const wrappingFunctionName = path.parent.callee?.name
46+
const bindings = path.context?.scope?.bindings
47+
const wrappingFunctionBinding = bindings?.[wrappingFunctionName]
48+
if (!wrappingFunctionBinding) return
49+
const importSpecifier = wrappingFunctionBinding.path?.node
50+
if (importSpecifier?.type !== "ImportSpecifier") return
51+
if (importSpecifier?.imported?.name !== "component") return
52+
53+
if (wrappingFunctionBinding.path.parent?.source?.value !== 'babel-plugin-solid-undestructure') return
54+
wrappingFunctionBinding.path.parentPath.remove()
55+
path.parentPath.replaceWith(path)
56+
}
57+
}
58+
59+
const firstParam = path.node?.params?.[0]
60+
if (!firstParam || firstParam.type !== "ObjectPattern") return
61+
62+
const program = path?.findParent(path => path.isProgram())
63+
const newPropsIdentifier =
64+
program?.scope?.generateUidIdentifier("props")
65+
66+
const propsDestructredProperties = firstParam?.properties
67+
const componentScopeBindings = path.scope?.bindings
68+
69+
for (const DestructredProperty of propsDestructredProperties)
70+
if (!DestructredProperty?.value?.name) return
71+
72+
for (const DestructredProperty of propsDestructredProperties) {
73+
const DestructredKeyIdentifier = DestructredProperty.key
74+
const undestructuredPropExpression =
75+
types.memberExpression(newPropsIdentifier, DestructredKeyIdentifier)
76+
77+
const DestructredName = DestructredProperty.value?.name
78+
79+
const { referencePaths, constantViolations } = componentScopeBindings?.[DestructredName]
80+
81+
for (const referencePath of referencePaths)
82+
referencePath?.replaceWith(undestructuredPropExpression)
83+
84+
for (const constantViolation of constantViolations)
85+
constantViolation.node && (constantViolation.node.left = undestructuredPropExpression)
86+
}
87+
88+
path.node.params[0] = newPropsIdentifier
89+
}
90+
91+
92+
module.exports = function babelPluginUndestructure ({ types }) {
93+
const visitor = {
94+
FunctionDeclaration: functionVisitor(types),
95+
FunctionExpression: functionVisitor(types),
96+
ArrowFunctionExpression: functionVisitor(types)
97+
}
98+
99+
return {
100+
name: "babel-plugin-solid-undestructure",
101+
visitor
102+
}
103+
}
104+
105+
106+
module.exports.undestructurePlugin = mode => {
107+
if (!mode || mode === 'ts') return [
108+
{
109+
...babel({
110+
plugins: [
111+
["@babel/plugin-syntax-typescript", { isTSX: true }],
112+
"babel-plugin-solid-undestructure",
113+
],
114+
extensions: [".tsx"]
115+
}),
116+
enforce: 'pre'
117+
},
118+
{
119+
...babel({
120+
plugins: [
121+
"@babel/plugin-syntax-typescript",
122+
"babel-plugin-solid-undestructure",
123+
],
124+
extensions: [".ts"]
125+
}),
126+
enforce: 'pre'
127+
}
128+
]
129+
130+
else if (mode === "vanilla-js")
131+
return ["babel-plugin-solid-undestructure", { mode: "vanilla-js" }]
132+
133+
else throw new Error("babel-plugin-solid-undestructure error: Invalid mode. Mode must be either 'ts' or 'vanilla-js'")
134+
}

index.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Component } from "solid-js"
2+
3+
4+
export const undestructurePlugin: (mode?: "ts" | "vanilla-js") => any
5+
6+
export const component: <
7+
Props extends Record<string, any>
8+
>(component: Component<Props>) => Component<Props>

index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const component = () => console.warn(
2+
'The "component" function is a compile time function. It was called at runtime, which means that babel-plugin-solid-undestructure wasn\'nt applied at build time. Please make sure to configure babel-plugin-solid undestructure correctly or remove the "component" function.'
3+
)

0 commit comments

Comments
 (0)