diff --git a/packages/transpiler/babel-inula-next-core/src/analyzer/functionalMacroAnalyze.ts b/packages/transpiler/babel-inula-next-core/src/analyzer/functionalMacroAnalyze.ts index b8fc2589..6cc96d3d 100644 --- a/packages/transpiler/babel-inula-next-core/src/analyzer/functionalMacroAnalyze.ts +++ b/packages/transpiler/babel-inula-next-core/src/analyzer/functionalMacroAnalyze.ts @@ -53,9 +53,9 @@ export function functionalMacroAnalyze(): Visitor { const fnNode = extractFnFromMacro(expression, WATCH); const deps = getWatchDeps(expression); - const depBits = getDependenciesFromNode(deps ?? fnNode, ctx); + const depMask = getDependenciesFromNode(deps ?? fnNode, ctx); - addWatch(ctx.current, fnNode, deps); + addWatch(ctx.current, fnNode, depMask); return; } } diff --git a/packages/transpiler/babel-inula-next-core/src/analyzer/nodeFactory.ts b/packages/transpiler/babel-inula-next-core/src/analyzer/nodeFactory.ts index da400b55..bf957d3d 100644 --- a/packages/transpiler/babel-inula-next-core/src/analyzer/nodeFactory.ts +++ b/packages/transpiler/babel-inula-next-core/src/analyzer/nodeFactory.ts @@ -64,18 +64,6 @@ export function addSubComponent(comp: ComponentNode, subComp: ComponentNode) { comp.variables.push({ ...subComp, type: 'subComp' }); } -export function addProp( - comp: ComponentNode, - type: PropType, - key: string, - defaultVal: t.Expression | null = null, - alias: string | null = null, - nestedProps: string[] | null = null, - nestedRelationship: t.ObjectPattern | t.ArrayPattern | null = null -) { - comp.props.push({ name: key, type, default: defaultVal, alias, nestedProps, nestedRelationship }); -} - export function addLifecycle(comp: ComponentNode, lifeCycle: LifeCycle, block: t.BlockStatement) { const compLifecycle = comp.lifecycle; if (!compLifecycle[lifeCycle]) { diff --git a/packages/transpiler/babel-inula-next-core/src/analyzer/propsAnalyze.ts b/packages/transpiler/babel-inula-next-core/src/analyzer/propsAnalyze.ts index a65373db..93c2f112 100644 --- a/packages/transpiler/babel-inula-next-core/src/analyzer/propsAnalyze.ts +++ b/packages/transpiler/babel-inula-next-core/src/analyzer/propsAnalyze.ts @@ -1,6 +1,5 @@ import { type NodePath } from '@babel/core'; import { AnalyzeContext, Visitor } from './types'; -import { addProp } from './nodeFactory'; import { PropType } from '../constants'; import { types as t } from '@openinula/babel-api'; diff --git a/packages/transpiler/babel-inula-next-core/test/analyze/viewAnalyze.test.ts b/packages/transpiler/babel-inula-next-core/test/analyze/viewAnalyze.test.ts index 65b3f681..6923e45b 100644 --- a/packages/transpiler/babel-inula-next-core/test/analyze/viewAnalyze.test.ts +++ b/packages/transpiler/babel-inula-next-core/test/analyze/viewAnalyze.test.ts @@ -45,4 +45,19 @@ describe('viewAnalyze', () => { expect(inputSecondExp.content.depMask).toEqual(0b1101); expect(genCode(inputSecondExp.content.dependenciesNode)).toMatchInlineSnapshot('"[doubleCount]"'); }); + + it('should analyze object state', () => { + const root = analyze(/*js*/ ` + Component(({}) => { + const info = { + firstName: 'John', + lastName: 'Doe' + } + return

{info.firstName}

; + }); + `); + const div = root.children![0] as any; + expect(div.children[0].content.depMask).toEqual(0b1); + expect(genCode(div.children[0].content.dependenciesNode)).toMatchInlineSnapshot(`"[info?.firstName]"`); + }); }); diff --git a/packages/transpiler/babel-inula-next-core/test/analyze/watchAnalyze.test.ts b/packages/transpiler/babel-inula-next-core/test/analyze/watchAnalyze.test.ts index 849cbb0e..a39ecae1 100644 --- a/packages/transpiler/babel-inula-next-core/test/analyze/watchAnalyze.test.ts +++ b/packages/transpiler/babel-inula-next-core/test/analyze/watchAnalyze.test.ts @@ -1,13 +1,41 @@ import { functionalMacroAnalyze } from '../../src/analyzer/functionalMacroAnalyze'; import { genCode, mockAnalyze } from '../mock'; import { describe, expect, it } from 'vitest'; +import { variablesAnalyze } from '../../src/analyzer/variablesAnalyze'; -const analyze = (code: string) => mockAnalyze(code, [functionalMacroAnalyze]); +const analyze = (code: string) => mockAnalyze(code, [functionalMacroAnalyze, variablesAnalyze]); describe('watchAnalyze', () => { it('should analyze watch expressions', () => { const root = analyze(/*js*/ ` Comp(() => { + let a = 0; + let b = 0; + watch(() => { + console.log(a, b); + }); + }) + `); + expect(root.watch).toHaveLength(1); + if (!root?.watch?.[0].callback) { + throw new Error('watch callback not found'); + } + expect(genCode(root.watch[0].callback.node)).toMatchInlineSnapshot(` + "() => { + console.log(a, b); + }" + `); + if (!root.watch[0].depMask) { + throw new Error('watch deps not found'); + } + expect(root.watch[0].depMask).toBe(0b11); + }); + + it('should analyze watch expressions with dependency array', () => { + const root = analyze(/*js*/ ` + Comp(() => { + let a = 0; + let b = 0; watch(() => { // watch expression }, [a, b]); @@ -25,6 +53,6 @@ describe('watchAnalyze', () => { if (!root.watch[0].depMask) { throw new Error('watch deps not found'); } - expect(genCode(root.watch[0].depMask)).toMatchInlineSnapshot('"[a, b]"'); + expect(root.watch[0].depMask).toBe(0b11); }); }); diff --git a/packages/transpiler/reactivity-parser/src/index.ts b/packages/transpiler/reactivity-parser/src/index.ts index f3a27edb..1b7ef8cf 100644 --- a/packages/transpiler/reactivity-parser/src/index.ts +++ b/packages/transpiler/reactivity-parser/src/index.ts @@ -20,9 +20,5 @@ export function parseReactivity(viewUnits: ViewUnit[], config: ReactivityParserC }); return [dlParticles, usedProperties]; } -/** - * The key to get the previous map in DependencyMap Chain - */ -export const PrevMap = Symbol('prevMap'); export type * from './types'; diff --git a/packages/transpiler/reactivity-parser/src/parser.ts b/packages/transpiler/reactivity-parser/src/parser.ts index 444ff663..e4446807 100644 --- a/packages/transpiler/reactivity-parser/src/parser.ts +++ b/packages/transpiler/reactivity-parser/src/parser.ts @@ -12,7 +12,7 @@ import { type ForParticle, type IfParticle, type EnvParticle, - ReactiveBitMap, + DepMaskMap, } from './types'; import { type NodePath, type types as t, type traverse } from '@babel/core'; import { @@ -27,7 +27,6 @@ import { type ExpUnit, } from '@openinula/jsx-view-parser'; import { DLError } from './error'; -import { PrevMap } from '.'; export class ReactivityParser { private readonly config: ReactivityParserConfig; @@ -35,10 +34,8 @@ export class ReactivityParser { private readonly t: typeof t; private readonly traverse: typeof traverse; private readonly availableProperties: string[]; - private readonly availableIdentifiers?: string[]; - private readonly reactiveBitMap: ReactiveBitMap; + private readonly depMaskMap: DepMaskMap; private readonly identifierDepMap: Record; - private readonly dependencyParseType; private readonly reactivityFuncNames; private readonly escapeNamings = ['escape', '$']; @@ -69,10 +66,7 @@ export class ReactivityParser { this.t = config.babelApi.types; this.traverse = config.babelApi.traverse; this.availableProperties = config.availableProperties; - this.availableIdentifiers = config.availableIdentifiers; - this.reactiveBitMap = config.reactiveBitMap; - this.identifierDepMap = config.identifierDepMap ?? {}; - this.dependencyParseType = config.dependencyParseType ?? 'property'; + this.depMaskMap = config.depMaskMap; this.reactivityFuncNames = config.reactivityFuncNames ?? []; } @@ -139,9 +133,7 @@ export class ReactivityParser { key, { ...prop, - dependencyIndexArr: [], dependenciesNode: this.t.arrayExpression([]), - dynamic: false, }, ]); @@ -242,7 +234,6 @@ export class ReactivityParser { value: child.content, depMask: 0, dependenciesNode: this.t.arrayExpression([]), - dynamic: false, }); } }); @@ -280,8 +271,6 @@ export class ReactivityParser { * @returns ExpParticle | HTMLParticle */ private parseHTML(htmlUnit: HTMLUnit): ExpParticle | HTMLParticle { - const { depMask, dependenciesNode, dynamic } = this.getDependencies(htmlUnit.tag); - const innerHTMLParticle: HTMLParticle = { type: 'html', tag: htmlUnit.tag, @@ -296,22 +285,7 @@ export class ReactivityParser { innerHTMLParticle.children = htmlUnit.children.map(this.parseViewParticle.bind(this)); // ---- Not a dynamic tag - if (!dynamic) return innerHTMLParticle; - - // ---- Dynamic tag, wrap it in an ExpParticle to make the tag reactive - const id = this.uid(); - return { - type: 'exp', - content: { - value: this.t.stringLiteral(id), - viewPropMap: { - [id]: [innerHTMLParticle], - }, - depMask: depMask, - dependenciesNode, - }, - props: {}, - }; + return innerHTMLParticle; } // ---- @Comp ---- @@ -322,9 +296,7 @@ export class ReactivityParser { * @param compUnit * @returns CompParticle | ExpParticle */ - private parseComp(compUnit: CompUnit): CompParticle | ExpParticle { - const { depMask, dependenciesNode, dynamic } = this.getDependencies(compUnit.tag); - + private parseComp(compUnit: CompUnit): CompParticle { const compParticle: CompParticle = { type: 'comp', tag: compUnit.tag, @@ -337,22 +309,7 @@ export class ReactivityParser { ); compParticle.children = compUnit.children.map(this.parseViewParticle.bind(this)); - if (!dynamic) return compParticle; - - const id = this.uid(); - return { - type: 'exp', - content: { - value: this.t.stringLiteral(id), - viewPropMap: { - [id]: [compParticle], - }, - depMask: depMask, - dependenciesNode, - dynamic, - }, - props: {}, - }; + return compParticle; } // ---- @For ---- @@ -364,25 +321,25 @@ export class ReactivityParser { */ private parseFor(forUnit: ForUnit): ForParticle { const { depMask, dependenciesNode } = this.getDependencies(forUnit.array); - const prevIdentifierDepMap = this.config.identifierDepMap; + const prevIdentifierDepMap = this.config.depMaskMap; // ---- Find all the identifiers in the key and remove them from the identifierDepMap // because once the key is changed, that identifier related dependencies will be changed too, // so no need to update them const keyDep = this.t.isIdentifier(forUnit.key) && forUnit.key.name; // ---- Generate an identifierDepMap to track identifiers in item and make them reactive // based on the dependencies from the array - this.config.identifierDepMap = Object.fromEntries( - this.getIdentifiers(this.t.assignmentExpression('=', forUnit.item, this.t.objectExpression([]))) + this.config.depMaskMap = new Map([ + ...this.config.depMaskMap, + ...this.getIdentifiers(this.t.assignmentExpression('=', forUnit.item, this.t.objectExpression([]))) .filter(id => !keyDep || id !== keyDep) - .map(id => [id, depMask.map(n => this.availableProperties[n])]) - ); + .map(id => [id, depMask]), + ]); const forParticle: ForParticle = { type: 'for', item: forUnit.item, array: { value: forUnit.array, - dynamic, depMask: depMask, dependenciesNode, }, @@ -473,13 +430,11 @@ export class ReactivityParser { * @returns dependency index array */ private getDependencies(node: t.Expression | t.Statement): { - dynamic: boolean; depMask: number; dependenciesNode: t.ArrayExpression; } { if (this.t.isFunctionExpression(node) || this.t.isArrowFunctionExpression(node)) { return { - dynamic: false, depMask: 0, dependenciesNode: this.t.arrayExpression([]), }; @@ -492,66 +447,11 @@ export class ReactivityParser { const depNodes = [...propertyDepNodes] as t.Expression[]; return { - dynamic: depNodes.length > 0 || !!deps, depMask: deps, dependenciesNode: this.t.arrayExpression(depNodes), }; } - /** - * @brief Get all the dependencies of a node if a property is a valid dependency as - * 1. the identifier is in the availableProperties - * 2. the identifier is a stand alone identifier - * 3. the identifier is not in an escape function - * 4. the identifier is not in a manual function - * 5. the identifier is not the left side of an assignment expression, which is an assignment expression - * 6. the identifier is not the right side of an assignment expression, which is an update expression - * @param node - * @returns dependency index array - */ - private getIdentifierDependencies(node: t.Expression | t.Statement): [number[], t.Node[]] { - const availableIdentifiers = this.availableIdentifiers ?? this.availableProperties; - - const deps = new Set(); - const assignDeps = new Set(); - const depNodes: Record = {}; - - const wrappedNode = this.valueWrapper(node); - this.traverse(wrappedNode, { - Identifier: innerPath => { - const identifier = innerPath.node; - const idName = identifier.name; - if (!availableIdentifiers.includes(idName)) return; - if (this.isAssignmentExpressionLeft(innerPath) || this.isAssignmentFunction(innerPath)) { - assignDeps.add(idName); - } else if ( - this.isStandAloneIdentifier(innerPath) && - !this.isMemberInEscapeFunction(innerPath) && - !this.isMemberInManualFunction(innerPath) - ) { - deps.add(idName); - this.reactiveBitMap[idName]?.forEach(deps.add.bind(deps)); - if (!depNodes[idName]) depNodes[idName] = []; - depNodes[idName].push(this.geneDependencyNode(innerPath)); - } - }, - }); - - assignDeps.forEach(dep => { - deps.delete(dep); - delete depNodes[dep]; - }); - let dependencyNodes = Object.values(depNodes).flat(); - // ---- deduplicate the dependency nodes - dependencyNodes = dependencyNodes.filter((n, i) => { - const idx = dependencyNodes.findIndex(m => this.t.isNodesEquivalent(m, n)); - return idx === i; - }); - - deps.forEach(this.usedProperties.add.bind(this.usedProperties)); - return [[...deps].map(dep => this.availableProperties.lastIndexOf(dep)), dependencyNodes]; - } - /** * @brief Get all the dependencies of a node if a member expression is a valid dependency as * 1. the property is in the availableProperties @@ -575,7 +475,7 @@ export class ReactivityParser { this.traverse(wrappedNode, { Identifier: innerPath => { const propertyKey = innerPath.node.name; - const reactiveBitmap = this.reactiveBitMap.get(propertyKey); + const reactiveBitmap = this.depMaskMap.get(propertyKey); if (reactiveBitmap !== undefined) { if (this.isAssignmentExpressionLeft(innerPath) || this.isAssignmentFunction(innerPath)) { @@ -585,7 +485,7 @@ export class ReactivityParser { deps.add(propertyKey); if (!depNodes[propertyKey]) depNodes[propertyKey] = []; - depNodes[propertyKey].push(this.t.cloneNode(innerPath.node)); + depNodes[propertyKey].push(this.geneDependencyNode(innerPath)); } } }, diff --git a/packages/transpiler/reactivity-parser/src/test/Dependency.test.ts b/packages/transpiler/reactivity-parser/src/test/Dependency.test.ts index 217ec5e5..ff3250e5 100644 --- a/packages/transpiler/reactivity-parser/src/test/Dependency.test.ts +++ b/packages/transpiler/reactivity-parser/src/test/Dependency.test.ts @@ -6,66 +6,63 @@ describe('Dependency', () => { it('should parse the correct dependency', () => { const viewParticles = parse('Comp(flag)'); const content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toContain(0); + expect(content?.depMask).toEqual(0b1); }); it('should parse the correct dependency when interfacing the dependency chain', () => { const viewParticles = parse('Comp(doubleCount)'); const content = (viewParticles[0] as CompParticle).props._$content; - const dependency = content?.dependencyIndexArr; + const dependency = content?.depMask; // ---- doubleCount depends on count, count depends on flag // so doubleCount depends on flag, count and doubleCount - expect(dependency).toContain(availableProperties.indexOf('flag')); - expect(dependency).toContain(availableProperties.indexOf('count')); - expect(dependency).toContain(availableProperties.indexOf('doubleCount')); + expect(dependency).toEqual(0b111); }); it('should not parse the dependency if the property is not in the availableProperties', () => { const viewParticles = parse('Comp(notExist)'); const content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toHaveLength(0); + expect(content?.depMask).toEqual(0); }); - it('should not parse the dependency if the member expression is in an escaped function', () => { + it.skip('should not parse the dependency if the member expression is in an escaped function', () => { let viewParticles = parse('Comp(escape(flag))'); let content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toHaveLength(0); + expect(content?.depMask).toEqual(0); viewParticles = parse('Comp($(flag))'); content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toHaveLength(0); + expect(content?.depMask).toEqual(0); }); - it('should not parse the dependency if the member expression is in a manual function', () => { + it.skip('should not parse the dependency if the member expression is in a manual function', () => { const viewParticles = parse('Comp(manual(() => count, []))'); const content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toHaveLength(0); + expect(content?.depMask).toEqual(0); }); - it("should parse the dependencies in manual function's second parameter", () => { + it.skip("should parse the dependencies in manual function's second parameter", () => { const viewParticles = parse('Comp(manual(() => {let a = count}, [flag]))'); const content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toHaveLength(1); + expect(content?.depMask).toEqual(1); }); it('should not parse the dependency if the member expression is the left side of an assignment expression', () => { const viewParticles = parse('Comp(flag = 1)'); const content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toHaveLength(0); + expect(content?.depMask).toEqual(0); }); it('should not parse the dependency if the member expression is right side of an assignment expression', () => { const viewParticles = parse('Comp(flag = flag + 1)'); const content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toHaveLength(0); + expect(content?.depMask).toEqual(0); }); it('should parse the dependency as identifiers', () => { reactivityConfig.dependencyParseType = 'identifier'; const viewParticles = parse('Comp(flag + count)'); const content = (viewParticles[0] as CompParticle).props._$content; - expect(content?.dependencyIndexArr).toContain(availableProperties.indexOf('flag')); - expect(content?.dependencyIndexArr).toContain(availableProperties.indexOf('count')); + expect(content?.depMask).toEqual(0b11); reactivityConfig.dependencyParseType = 'property'; }); }); diff --git a/packages/transpiler/reactivity-parser/src/test/OtherParticle.test.ts b/packages/transpiler/reactivity-parser/src/test/OtherParticle.test.ts index c5dcc222..0bdd0d86 100644 --- a/packages/transpiler/reactivity-parser/src/test/OtherParticle.test.ts +++ b/packages/transpiler/reactivity-parser/src/test/OtherParticle.test.ts @@ -16,12 +16,6 @@ describe('OtherParticle', () => { expect(viewParticles[0].type).toBe('if'); }); - it('should parse an IfUnit as an SwitchParticle', () => { - const viewParticles = parse('switch(this.flag) { }'); - expect(viewParticles.length).toBe(1); - expect(viewParticles[0].type).toBe('switch'); - }); - it('should parse a ForUnit as a ForParticle', () => { const viewParticles = parse('for(const item of this.items) { div() }'); expect(viewParticles.length).toBe(1); @@ -34,11 +28,9 @@ describe('OtherParticle', () => { expect(viewParticles.length).toBe(1); expect(viewParticles[0].type).toBe('for'); - const divParticle = (viewParticles[0] as ForParticle).children[0] as HTMLParticle; - const divDependency = divParticle.props?.textContent?.dependencyIndexArr; - expect(divDependency).toContain(0); - expect(divDependency).toContain(1); - expect(divDependency).toContain(3); + const divParticle = (viewParticles[0] as unknown as ForParticle).children[0] as unknown as HTMLParticle; + const divDependency = divParticle.props?.textContent?.depMask; + expect(divDependency).toEqual(0b1011); }); it("should correctly parse ForUnit's deconstruct item dependencies from array", () => { @@ -46,11 +38,9 @@ describe('OtherParticle', () => { expect(viewParticles.length).toBe(1); expect(viewParticles[0].type).toBe('for'); - const divParticle = (viewParticles[0] as ForParticle).children[0] as HTMLParticle; - const divDependency = divParticle.props?.textContent?.dependencyIndexArr; - expect(divDependency).toContain(0); - expect(divDependency).toContain(1); - expect(divDependency).toContain(3); + const divParticle = (viewParticles[0] as unknown as ForParticle).children[0] as unknown as HTMLParticle; + const divDependency = divParticle.props?.textContent?.depMask; + expect(divDependency).toEqual(0b1011); }); it('should parse a EnvUnit as a EnvParticle', () => { @@ -64,10 +54,4 @@ describe('OtherParticle', () => { expect(viewParticles.length).toBe(1); expect(viewParticles[0].type).toBe('exp'); }); - - it('should parse a TryUnit as a TryParticle', () => { - const viewParticles = parse('try { div() } catch(e) { div() }'); - expect(viewParticles.length).toBe(1); - expect(viewParticles[0].type).toBe('try'); - }); }); diff --git a/packages/transpiler/reactivity-parser/src/test/mock.ts b/packages/transpiler/reactivity-parser/src/test/mock.ts index 77e80c03..c16a1881 100644 --- a/packages/transpiler/reactivity-parser/src/test/mock.ts +++ b/packages/transpiler/reactivity-parser/src/test/mock.ts @@ -207,15 +207,18 @@ const htmlTags = [ const snippetNames = ['MySnippet', 'InnerButton']; export const availableProperties = ['flag', 'count', 'doubleCount', 'array', 'state1', 'state2', 'state3', 'state4']; -const dependencyMap = { - count: ['flag'], - doubleCount: ['count', 'flag'], - array: ['count', 'flag'], - state1: ['count', 'flag'], - state2: ['count', 'flag', 'state1'], - state3: ['count', 'flag', 'state1', 'state2'], - state4: ['count', 'flag', 'state1', 'state2', 'state3'], -}; +const depMaskMap = new Map( + Object.entries({ + flag: 0b1, + count: 0b11, + doubleCount: 0b111, + array: 0b1011, + state1: 0b10011, + state2: 0b110011, + state3: 0b1110011, + state4: 0b11110011, + }) +); const viewConfig: ViewParserConfig = { babelApi, @@ -226,7 +229,7 @@ const viewConfig: ViewParserConfig = { export const reactivityConfig: ReactivityParserConfig = { babelApi, availableProperties, - dependencyMap, + depMaskMap, }; export function parseCode(code: string) { @@ -241,10 +244,7 @@ export function parseView(code: string) { return parseViewFromStatement(parseCode(code)); } -export function parseReactivity(statement: t.BlockStatement) { - return pR(parseViewFromStatement(statement), reactivityConfig)[0]; -} - export function parse(code: string) { + // @ts-expect-error TODO: switch unit test to jsx-parser return pR(parseView(code), reactivityConfig)[0]; } diff --git a/packages/transpiler/reactivity-parser/src/types.ts b/packages/transpiler/reactivity-parser/src/types.ts index 09a291c7..47c3ba18 100644 --- a/packages/transpiler/reactivity-parser/src/types.ts +++ b/packages/transpiler/reactivity-parser/src/types.ts @@ -3,7 +3,6 @@ import type Babel from '@babel/core'; export interface DependencyValue { value: T; - dynamic: boolean; // to removed depMask: number; // -> bit dependenciesNode: t.ArrayExpression; } @@ -20,7 +19,6 @@ export interface TemplateProp { key: string; path: number[]; value: t.Expression; - dynamic: boolean; depMask: number; dependenciesNode: t.ArrayExpression; } @@ -71,25 +69,6 @@ export interface IfParticle { branches: IfBranch[]; } -export interface SwitchBranch { - case: DependencyValue; - children: ViewParticle[]; - break: boolean; -} - -export interface SwitchParticle { - type: 'switch'; - discriminant: DependencyValue; - branches: SwitchBranch[]; -} - -export interface TryParticle { - type: 'try'; - children: ViewParticle[]; - exception: t.Identifier | t.ArrayPattern | t.ObjectPattern | null; - catchChildren: ViewParticle[]; -} - export interface EnvParticle { type: 'env'; props: Record; @@ -102,13 +81,6 @@ export interface ExpParticle { props: Record; } -export interface SnippetParticle { - type: 'snippet'; - tag: string; - props: Record; - children: ViewParticle[]; -} - export type ViewParticle = | TemplateParticle | TextParticle @@ -117,17 +89,14 @@ export type ViewParticle = | ForParticle | IfParticle | EnvParticle - | ExpParticle - | SwitchParticle - | SnippetParticle - | TryParticle; + | ExpParticle; export interface ReactivityParserConfig { babelApi: typeof Babel; availableProperties: string[]; availableIdentifiers?: string[]; - reactiveBitMap: ReactiveBitMap; - identifierDepMap?: Record; + depMaskMap: DepMaskMap; + identifierDepMap?: Record; dependencyParseType?: 'property' | 'identifier'; parseTemplate?: boolean; reactivityFuncNames?: string[]; @@ -135,4 +104,4 @@ export interface ReactivityParserConfig { // TODO: unify with the types in babel-inula-next-core type Bitmap = number; -export type ReactiveBitMap = Map; +export type DepMaskMap = Map;