fix(props): rename the prop without alias and deconstruction
This commit is contained in:
parent
c7de85630e
commit
b15d746697
|
@ -23,5 +23,5 @@ graph TD
|
|||
see `types.ts` in `packages/transpiler/babel-inula-next-core/src/analyze/types.ts`
|
||||
|
||||
## TODO LIST
|
||||
- [ ] for analyze the local variable, we need to consider the scope of the variable
|
||||
- [x] for analyze the local variable, we need to consider the scope of the variable
|
||||
- [ ] hook analyze
|
||||
|
|
|
@ -4,6 +4,7 @@ import { register } from '@openinula/babel-api';
|
|||
import { COMPONENT } from '../constants';
|
||||
import { ArrowFunctionWithBlock, extractFnFromMacro, isCompPath, wrapArrowFunctionWithBlock } from '../utils';
|
||||
import { types as t } from '@openinula/babel-api';
|
||||
import { type Scope } from '@babel/traverse';
|
||||
|
||||
export enum PropType {
|
||||
REST = 'rest',
|
||||
|
@ -27,10 +28,9 @@ interface Prop {
|
|||
// let p20
|
||||
// let p21
|
||||
// }
|
||||
function createPropAssignment(prop: Prop) {
|
||||
const decalrations = [
|
||||
t.variableDeclaration('let', [t.variableDeclarator(t.identifier(`${prop.name}_$$prop`), prop.defaultVal)]),
|
||||
];
|
||||
function createPropAssignment(prop: Prop, scope: Scope) {
|
||||
const newName = `${prop.name}_$$prop`;
|
||||
const decalrations = [t.variableDeclaration('let', [t.variableDeclarator(t.identifier(newName), prop.defaultVal)])];
|
||||
if (prop.alias) {
|
||||
decalrations.push(
|
||||
t.variableDeclaration('let', [
|
||||
|
@ -44,10 +44,22 @@ function createPropAssignment(prop: Prop) {
|
|||
);
|
||||
}
|
||||
|
||||
if (!prop.nestedRelationship || !prop.alias) {
|
||||
// this means the prop can be used directly in the function body
|
||||
// need rename the prop
|
||||
scope.rename(prop.name, newName);
|
||||
}
|
||||
return decalrations;
|
||||
}
|
||||
|
||||
function extractPropsDestructing(
|
||||
/**
|
||||
* Find the props destructuring in the function body, like:
|
||||
* const { prop1, prop2 } = props;
|
||||
* To extract the props
|
||||
* @param fnPath
|
||||
* @param propsName
|
||||
*/
|
||||
function extractPropsDestructingInFnBody(
|
||||
fnPath: NodePath<t.FunctionExpression> | NodePath<ArrowFunctionWithBlock>,
|
||||
propsName: string
|
||||
) {
|
||||
|
@ -62,9 +74,9 @@ function extractPropsDestructing(
|
|||
const id = declaration.get('id');
|
||||
if (init.isIdentifier() && init.node.name === propsName) {
|
||||
if (id.isObjectPattern()) {
|
||||
props = id.get('properties').map(prop => parseSingleProp(prop));
|
||||
props = id.get('properties').map(prop => parseProperty(prop));
|
||||
} else if (id.isIdentifier()) {
|
||||
props = extractPropsDestructing(fnPath, id.node.name);
|
||||
props = extractPropsDestructingInFnBody(fnPath, id.node.name);
|
||||
}
|
||||
// delete the declaration
|
||||
if (props.length > 0) {
|
||||
|
@ -113,13 +125,14 @@ export default function (api: typeof babel, options: DLightOption): PluginObj {
|
|||
if (propsPath) {
|
||||
if (propsPath.isObjectPattern()) {
|
||||
// --- object destructuring ---
|
||||
props = propsPath.get('properties').map(prop => parseSingleProp(prop));
|
||||
props = propsPath.get('properties').map(prop => parseProperty(prop));
|
||||
} else if (propsPath.isIdentifier()) {
|
||||
props = extractPropsDestructing(fnPath, propsPath.node.name);
|
||||
// --- identifier destructuring ---
|
||||
props = extractPropsDestructingInFnBody(fnPath, propsPath.node.name);
|
||||
}
|
||||
}
|
||||
|
||||
fnPath.node.body.body.unshift(...props.flatMap(prop => createPropAssignment(prop)));
|
||||
fnPath.node.body.body.unshift(...props.flatMap(prop => createPropAssignment(prop, fnPath.scope)));
|
||||
|
||||
// --- clear the props ---
|
||||
fnPath.node.params = [];
|
||||
|
@ -129,14 +142,14 @@ export default function (api: typeof babel, options: DLightOption): PluginObj {
|
|||
};
|
||||
}
|
||||
|
||||
function parseSingleProp(path: NodePath<t.ObjectProperty | t.RestElement>): Prop {
|
||||
function parseProperty(path: NodePath<t.ObjectProperty | t.RestElement>): Prop {
|
||||
if (path.isObjectProperty()) {
|
||||
// --- normal property ---
|
||||
const key = path.node.key;
|
||||
const value = path.node.value;
|
||||
if (t.isIdentifier(key) || t.isStringLiteral(key)) {
|
||||
const name = t.isIdentifier(key) ? key.name : key.value;
|
||||
return analyzeNestedProp(value, name, path);
|
||||
return analyzeNestedProp(value, name);
|
||||
}
|
||||
|
||||
throw Error(`Unsupported key type in object destructuring: ${key.type}`);
|
||||
|
@ -153,7 +166,7 @@ function parseSingleProp(path: NodePath<t.ObjectProperty | t.RestElement>): Prop
|
|||
}
|
||||
}
|
||||
|
||||
function analyzeNestedProp(value: t.ObjectProperty['value'], name: string, path: NodePath<t.ObjectProperty>): Prop {
|
||||
function analyzeNestedProp(value: t.ObjectProperty['value'], name: string): Prop {
|
||||
let defaultVal: t.Expression | null = null;
|
||||
let alias: string | null = null;
|
||||
const nestedProps: string[] | null = [];
|
||||
|
|
|
@ -24,14 +24,17 @@ describe('analyze props', () => {
|
|||
it('should work', () => {
|
||||
expect(
|
||||
mock(`
|
||||
Component(({foo, bar}) => {})
|
||||
Component(({foo, bar}) => {
|
||||
const v = foo + bar;
|
||||
})
|
||||
`)
|
||||
).toMatchInlineSnapshot(`
|
||||
"Component(() => {
|
||||
let foo_$$prop;
|
||||
let bar_$$prop;
|
||||
});"
|
||||
`);
|
||||
"Component(() => {
|
||||
let foo_$$prop;
|
||||
let bar_$$prop;
|
||||
const v = foo_$$prop + bar_$$prop;
|
||||
});"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should support default value', () => {
|
||||
|
|
Loading…
Reference in New Issue