From b15d746697df844d65518982802e5d4d0c2f6858 Mon Sep 17 00:00:00 2001 From: Hoikan <30694822+HoikanChan@users.noreply.github.com> Date: Fri, 24 May 2024 17:56:42 +0800 Subject: [PATCH] fix(props): rename the prop without alias and deconstruction --- docs/inula-next/OpenInula 2.0 Parser.md | 2 +- .../src/sugarPlugins/propsFormatPlugin.ts | 39 ++++++++++++------- .../test/sugarPlugins/props.test.ts | 15 ++++--- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/docs/inula-next/OpenInula 2.0 Parser.md b/docs/inula-next/OpenInula 2.0 Parser.md index 566138da..8465bdf3 100644 --- a/docs/inula-next/OpenInula 2.0 Parser.md +++ b/docs/inula-next/OpenInula 2.0 Parser.md @@ -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 diff --git a/packages/transpiler/babel-inula-next-core/src/sugarPlugins/propsFormatPlugin.ts b/packages/transpiler/babel-inula-next-core/src/sugarPlugins/propsFormatPlugin.ts index f77284e1..9970bfb4 100644 --- a/packages/transpiler/babel-inula-next-core/src/sugarPlugins/propsFormatPlugin.ts +++ b/packages/transpiler/babel-inula-next-core/src/sugarPlugins/propsFormatPlugin.ts @@ -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 | NodePath, 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): Prop { +function parseProperty(path: NodePath): 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): Prop } } -function analyzeNestedProp(value: t.ObjectProperty['value'], name: string, path: NodePath): 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 = []; diff --git a/packages/transpiler/babel-inula-next-core/test/sugarPlugins/props.test.ts b/packages/transpiler/babel-inula-next-core/test/sugarPlugins/props.test.ts index 83c75b08..39f5c184 100644 --- a/packages/transpiler/babel-inula-next-core/test/sugarPlugins/props.test.ts +++ b/packages/transpiler/babel-inula-next-core/test/sugarPlugins/props.test.ts @@ -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', () => {