diff --git a/packages/transpiler/jsx-parser/src/parser.ts b/packages/transpiler/jsx-parser/src/parser.ts index 83f5c158..da1f5517 100644 --- a/packages/transpiler/jsx-parser/src/parser.ts +++ b/packages/transpiler/jsx-parser/src/parser.ts @@ -536,6 +536,49 @@ export class ViewParser { } private pareFor(node: t.JSXElement) { - // TODO + // ---- Get array + const arrayContainer = this.findProp(node, "array") + if (!arrayContainer) throw new Error("Missing [array] prop in for loop") + if (!this.t.isJSXExpressionContainer(arrayContainer.value)) throw new Error("Expected expression container for [array] prop") + const array = arrayContainer.value.expression + if (this.t.isJSXEmptyExpression(array)) throw new Error("Expected [array] expression not empty") + + // ---- Get key + const keyProp = this.findProp(node, "key") + let key: t.Expression = this.t.nullLiteral() + if (keyProp) { + if (!( + this.t.isJSXExpressionContainer(keyProp.value) && + this.t.isFunction(keyProp.value.expression) + )) throw new Error("Expected expression container") + key = keyProp.value.expression + } + + // ---- Get Item + const itemProp = this.findProp(node, "item") + if (!itemProp) throw new Error("Missing [item] prop in for loop") + if (!this.t.isJSXExpressionContainer(itemProp.value)) throw new Error("Expected expression container for [item] prop") + const item = itemProp.value.expression + if (this.t.isJSXEmptyExpression(item)) throw new Error("Expected [item] expression not empty") + // ---- ObjectExpression to ObjectPattern / ArrayExpression to ArrayPattern + this.traverse(this.wrapWithFile(item), { + ObjectExpression: (path) => { + path.type = "ObjectPattern" as any + }, + ArrayExpression: (path) => { + path.type = "ArrayPattern" as any + } + }) + + // ---- Get children + const children = this.t.jsxFragment(this.t.jsxOpeningFragment(), this.t.jsxClosingFragment(), node.children) + + this.viewUnits.push({ + type: "for", + key, + item: item as t.LVal, + array, + children: this.parseView(children) + }) } } diff --git a/packages/transpiler/jsx-parser/src/test/ElementUnit.test.ts b/packages/transpiler/jsx-parser/src/test/ElementUnit.test.ts index 1e015ffe..09f082db 100644 --- a/packages/transpiler/jsx-parser/src/test/ElementUnit.test.ts +++ b/packages/transpiler/jsx-parser/src/test/ElementUnit.test.ts @@ -186,13 +186,4 @@ describe('ElementUnit', () => { const htmlUnit = viewUnits[0] as HTMLUnit; expect(htmlUnit.children!.length).toBe(4); }); - - it('should correctly parse the children', () => { - const viewUnits = parse('
ok
'); - const htmlUnit = viewUnits[0] as HTMLUnit; - const firstChild = htmlUnit.children![0]; - expect(firstChild.type).toBe('html'); - expect(t.isStringLiteral((firstChild as HTMLUnit).tag, { value: 'div' })).toBeTruthy(); - expect((firstChild as HTMLUnit).children![0].type).toBe('text'); - }); }); diff --git a/packages/transpiler/jsx-parser/src/test/ForUnit.test.ts b/packages/transpiler/jsx-parser/src/test/ForUnit.test.ts new file mode 100644 index 00000000..3fea384e --- /dev/null +++ b/packages/transpiler/jsx-parser/src/test/ForUnit.test.ts @@ -0,0 +1,11 @@ +import { describe, expect, it } from 'vitest'; +import { parse } from './mock'; + + +describe('ForUnit', () => { + it('should identify for unit', () => { + const viewUnits = parse('
{item}
'); + expect(viewUnits.length).toBe(1); + expect(viewUnits[0].type).toBe('for'); + }); +}); \ No newline at end of file diff --git a/packages/transpiler/jsx-parser/src/test/TemplateUnit.test.ts b/packages/transpiler/jsx-parser/src/test/TemplateUnit.test.ts index 671def94..ca8c79f0 100644 --- a/packages/transpiler/jsx-parser/src/test/TemplateUnit.test.ts +++ b/packages/transpiler/jsx-parser/src/test/TemplateUnit.test.ts @@ -17,7 +17,7 @@ describe('TemplateUnit', () => { expect(viewUnits[0].type).toBe('template'); }); - it("should correctly parse a nested HTMLUnit's structure into a template", () => { + it('should correctly parse a nested HTMLUnit\'s structure into a template', () => { const viewUnits = parse('
'); const template = (viewUnits[0] as TemplateUnit).template; @@ -28,7 +28,7 @@ describe('TemplateUnit', () => { }); // ---- Props - it("should correctly parse the path of TemplateUnit's dynamic props in root element", () => { + it('should correctly parse the path of TemplateUnit\'s dynamic props in root element', () => { const viewUnits = parse('
'); const dynamicProps = (viewUnits[0] as TemplateUnit).props; @@ -37,7 +37,7 @@ describe('TemplateUnit', () => { expect(prop.path).toHaveLength(0); }); - it("should correctly parse the path of TemplateUnit's dynamic props in nested element", () => { + it('should correctly parse the path of TemplateUnit\'s dynamic props in nested element', () => { const viewUnits = parse('
'); const dynamicProps = (viewUnits[0] as TemplateUnit).props!; @@ -47,17 +47,17 @@ describe('TemplateUnit', () => { expect(prop.path[0]).toBe(0); }); - it("should correctly parse the path of TemplateUnit's dynamic props with mutable particles ahead", () => { + it('should correctly parse the path of TemplateUnit\'s dynamic props with mutable particles ahead', () => { const viewUnits = parse('
'); const dynamicProps = (viewUnits[0] as TemplateUnit).props!; expect(dynamicProps).toHaveLength(1); const prop = dynamicProps[0]!; expect(prop.path).toHaveLength(1); - expect(prop.path[0]).toBe(1); + expect(prop.path[0]).toBe(0); }); - it("should correctly parse the path of TemplateUnit's mutableUnits", () => { + it('should correctly parse the path of TemplateUnit\'s mutableUnits', () => { const viewUnits = parse('
'); const mutableParticles = (viewUnits[0] as TemplateUnit).mutableUnits!; @@ -67,7 +67,7 @@ describe('TemplateUnit', () => { expect(particle.path[0]).toBe(0); }); - it("should correctly parse the path of multiple TemplateUnit's mutableUnits", () => { + it('should correctly parse the path of multiple TemplateUnit\'s mutableUnits', () => { const viewUnits = parse('
'); const mutableParticles = (viewUnits[0] as TemplateUnit).mutableUnits!; @@ -77,6 +77,6 @@ describe('TemplateUnit', () => { expect(firstParticle.path[0]).toBe(0); const secondParticle = mutableParticles[1]!; expect(secondParticle.path).toHaveLength(1); - expect(secondParticle.path[0]).toBe(2); + expect(secondParticle.path[0]).toBe(-1); }); }); diff --git a/packages/transpiler/jsx-parser/src/types.ts b/packages/transpiler/jsx-parser/src/types.ts index e860ad92..238335ea 100644 --- a/packages/transpiler/jsx-parser/src/types.ts +++ b/packages/transpiler/jsx-parser/src/types.ts @@ -59,6 +59,7 @@ export interface IfUnit { export interface ExpUnit { type: 'exp'; content: UnitProp; + props: Record; } export interface EnvUnit {