|
|
@@ -12,7 +12,6 @@ import {
|
|
|
type IRDynamicInfo,
|
|
|
type IREffect,
|
|
|
IRNodeTypes,
|
|
|
- isBlockOperation,
|
|
|
} from '../ir'
|
|
|
import {
|
|
|
type CodeFragment,
|
|
|
@@ -78,12 +77,8 @@ export function genFor(
|
|
|
idMap[indexVar] = null
|
|
|
}
|
|
|
|
|
|
- const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(
|
|
|
- render,
|
|
|
- keyProp,
|
|
|
- idMap,
|
|
|
- context,
|
|
|
- )
|
|
|
+ const { selectorPatterns, keyOnlyBindingPatterns, skippedEffectIndexes } =
|
|
|
+ matchPatterns(render, keyProp, idMap, context)
|
|
|
const selectorDeclarations: CodeFragment[] = []
|
|
|
const selectorName = (i: number) =>
|
|
|
selectorPatterns.length > 1 ? `_selector${id}_${i}` : `_selector${id}`
|
|
|
@@ -105,32 +100,38 @@ export function genFor(
|
|
|
frag.push('(', ...args, ') => {', INDENT_START)
|
|
|
if (selectorPatterns.length || keyOnlyBindingPatterns.length) {
|
|
|
frag.push(
|
|
|
- ...genBlockContent(render, context, false, () => {
|
|
|
- const patternFrag: CodeFragment[] = []
|
|
|
-
|
|
|
- for (let i = 0; i < selectorPatterns.length; i++) {
|
|
|
- const { effect } = selectorPatterns[i]
|
|
|
- patternFrag.push(
|
|
|
- NEWLINE,
|
|
|
- `${selectorName(i)}(`,
|
|
|
- ...genExpression(keyProp!, context),
|
|
|
- `, () => {`,
|
|
|
- INDENT_START,
|
|
|
- )
|
|
|
- for (const oper of effect.operations) {
|
|
|
- patternFrag.push(...genOperation(oper, context))
|
|
|
+ ...genBlockContent(
|
|
|
+ render,
|
|
|
+ context,
|
|
|
+ false,
|
|
|
+ () => {
|
|
|
+ const patternFrag: CodeFragment[] = []
|
|
|
+
|
|
|
+ for (let i = 0; i < selectorPatterns.length; i++) {
|
|
|
+ const { effect } = selectorPatterns[i]
|
|
|
+ patternFrag.push(
|
|
|
+ NEWLINE,
|
|
|
+ `${selectorName(i)}(`,
|
|
|
+ ...genExpression(keyProp!, context),
|
|
|
+ `, () => {`,
|
|
|
+ INDENT_START,
|
|
|
+ )
|
|
|
+ for (const oper of effect.operations) {
|
|
|
+ patternFrag.push(...genOperation(oper, context))
|
|
|
+ }
|
|
|
+ patternFrag.push(INDENT_END, NEWLINE, `})`)
|
|
|
}
|
|
|
- patternFrag.push(INDENT_END, NEWLINE, `})`)
|
|
|
- }
|
|
|
|
|
|
- for (const { effect } of keyOnlyBindingPatterns) {
|
|
|
- for (const oper of effect.operations) {
|
|
|
- patternFrag.push(...genOperation(oper, context))
|
|
|
+ for (const { effect } of keyOnlyBindingPatterns) {
|
|
|
+ for (const oper of effect.operations) {
|
|
|
+ patternFrag.push(...genOperation(oper, context))
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return patternFrag
|
|
|
- }),
|
|
|
+ return patternFrag
|
|
|
+ },
|
|
|
+ skippedEffectIndexes,
|
|
|
+ ),
|
|
|
)
|
|
|
} else {
|
|
|
frag.push(...genBlockContent(render, context))
|
|
|
@@ -383,65 +384,47 @@ function matchPatterns(
|
|
|
const keyOnlyBindingPatterns: NonNullable<
|
|
|
ReturnType<typeof matchKeyOnlyBindingPattern>
|
|
|
>[] = []
|
|
|
- const removedEffectIndexes: number[] = []
|
|
|
-
|
|
|
- render.effect = render.effect.filter((effect, index) => {
|
|
|
- if (keyProp !== undefined) {
|
|
|
- const selector = matchSelectorPattern(
|
|
|
- effect,
|
|
|
- keyProp.content,
|
|
|
- idMap,
|
|
|
- context,
|
|
|
- )
|
|
|
- if (selector) {
|
|
|
- selectorPatterns.push(selector)
|
|
|
- removedEffectIndexes.push(index)
|
|
|
- return false
|
|
|
- }
|
|
|
- const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content)
|
|
|
- if (keyOnly) {
|
|
|
- keyOnlyBindingPatterns.push(keyOnly)
|
|
|
- removedEffectIndexes.push(index)
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
+ let skippedEffectIndexes: Set<number> | undefined
|
|
|
|
|
|
- return true
|
|
|
- })
|
|
|
+ if (keyProp === undefined) {
|
|
|
+ return {
|
|
|
+ keyOnlyBindingPatterns,
|
|
|
+ selectorPatterns,
|
|
|
+ skippedEffectIndexes,
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (removedEffectIndexes.length) {
|
|
|
- shiftEffectBoundaries(render.dynamic, removedEffectIndexes)
|
|
|
+ for (let index = 0; index < render.effect.length; index++) {
|
|
|
+ const effect = render.effect[index]
|
|
|
+ const selector = matchSelectorPattern(
|
|
|
+ effect,
|
|
|
+ keyProp.content,
|
|
|
+ idMap,
|
|
|
+ context,
|
|
|
+ )
|
|
|
+ if (selector) {
|
|
|
+ selectorPatterns.push(selector)
|
|
|
+ skipEffect(index)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content)
|
|
|
+ if (keyOnly) {
|
|
|
+ keyOnlyBindingPatterns.push(keyOnly)
|
|
|
+ skipEffect(index)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
keyOnlyBindingPatterns,
|
|
|
selectorPatterns,
|
|
|
+ skippedEffectIndexes,
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-function shiftEffectBoundaries(
|
|
|
- dynamic: IRDynamicInfo,
|
|
|
- removedEffectIndexes: number[],
|
|
|
-): void {
|
|
|
- const operation = dynamic.operation
|
|
|
- if (
|
|
|
- operation &&
|
|
|
- isBlockOperation(operation) &&
|
|
|
- operation.effectIndex !== undefined
|
|
|
- ) {
|
|
|
- let offset = 0
|
|
|
- for (const removedIndex of removedEffectIndexes) {
|
|
|
- if (removedIndex < operation.effectIndex) {
|
|
|
- offset++
|
|
|
- } else {
|
|
|
- break
|
|
|
- }
|
|
|
+ function skipEffect(index: number): void {
|
|
|
+ if (!skippedEffectIndexes) {
|
|
|
+ skippedEffectIndexes = new Set()
|
|
|
}
|
|
|
- operation.effectIndex -= offset
|
|
|
- }
|
|
|
-
|
|
|
- for (const child of dynamic.children) {
|
|
|
- shiftEffectBoundaries(child, removedEffectIndexes)
|
|
|
+ skippedEffectIndexes.add(index)
|
|
|
}
|
|
|
}
|
|
|
|