refactor: extract transformInterpolation

This commit is contained in:
三咲智子 Kevin Deng 2023-12-03 14:52:11 +08:00
parent 3dfe3854ee
commit 21e7a37865
No known key found for this signature in database
GPG Key ID: 69992F2250DFD93E
5 changed files with 73 additions and 90 deletions

View File

@ -8,14 +8,19 @@ import {
ErrorCodes,
} from '@vue/compiler-dom'
import { extend, isString } from '@vue/shared'
import { DirectiveTransform, NodeTransform, transform } from './transform'
import {
type DirectiveTransform,
type NodeTransform,
transform,
} from './transform'
import { generate } from './generate'
import { HackOptions } from './hack'
import { transformOnce } from './transforms/vOnce'
import { transformElement } from './transforms/transformElement'
import { transformVHtml } from './transforms/vHtml'
import { transformVText } from './transforms/vText'
import { transformVOn } from './transforms/vOn'
import { transformInterpolation } from './transforms/transformInterpolation'
import type { HackOptions } from './ir'
export type CompilerOptions = HackOptions<BaseCompilerOptions>
@ -88,7 +93,7 @@ export function getBaseTransformPreset(
prefixIdentifiers?: boolean,
): TransformPreset {
return [
[transformOnce, transformElement],
[transformOnce, transformInterpolation, transformElement],
{
on: transformVOn,
html: transformVHtml,

View File

@ -1,15 +0,0 @@
import type { Prettify } from '@vue/shared'
import type { DirectiveTransform, NodeTransform } from './transform'
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> &
Pick<U, Extract<keyof U, keyof T>>
export type HackOptions<T> = Prettify<
Overwrite<
T,
{
nodeTransforms?: NodeTransform[]
directiveTransforms?: Record<string, DirectiveTransform | undefined>
}
>
>

View File

@ -3,6 +3,8 @@ import type {
RootNode,
SourceLocation,
} from '@vue/compiler-dom'
import type { Prettify } from '@vue/shared'
import type { DirectiveTransform, NodeTransform } from './transform'
export enum IRNodeTypes {
ROOT,
@ -139,3 +141,16 @@ export interface IREffect {
expressions: IRExpression[]
operations: OperationNode[]
}
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> &
Pick<U, Extract<keyof U, keyof T>>
export type HackOptions<T> = Prettify<
Overwrite<
T,
{
nodeTransforms?: NodeTransform[]
directiveTransforms?: Record<string, DirectiveTransform | undefined>
}
>
>

View File

@ -2,7 +2,6 @@ import {
type RootNode,
type TemplateChildNode,
type ElementNode,
type InterpolationNode,
type TransformOptions as BaseTransformOptions,
type ParentNode,
type AllNode,
@ -20,7 +19,7 @@ import {
type IRExpression,
IRNodeTypes,
} from './ir'
import type { HackOptions } from './hack'
import type { HackOptions } from './ir'
export type NodeTransform = (
node: RootNode | TemplateChildNode,
@ -225,7 +224,7 @@ export function transform(
function transformNode(
context: TransformContext<RootNode | TemplateChildNode>,
) {
let { node, index } = context
let { node } = context
// apply transform plugins
const { nodeTransforms } = context.options
@ -248,10 +247,6 @@ function transformNode(
}
}
const parentChildren = context.parent ? context.parent.node.children : []
const isFirst = index === 0
const isLast = index === parentChildren.length - 1
switch (node.type) {
case NodeTypes.ROOT:
case NodeTypes.ELEMENT: {
@ -266,25 +261,6 @@ function transformNode(
context.template += `<!--${node.content}-->`
break
}
case NodeTypes.INTERPOLATION: {
transformInterpolation(
context as TransformContext<InterpolationNode>,
isFirst,
isLast,
)
break
}
case NodeTypes.TEXT_CALL:
// never
break
default: {
// TODO handle other types
// CompoundExpressionNode
// IfNode
// IfBranchNode
// ForNode
context.template += `[type: ${node.type}]`
}
}
// exit transforms
@ -370,49 +346,3 @@ function processDynamicChildren(ctx: TransformContext<RootNode | ElementNode>) {
}
}
}
function transformInterpolation(
ctx: TransformContext<InterpolationNode>,
isFirst: boolean,
isLast: boolean,
) {
const { node } = ctx
const expr = node.content
if (isFirst && isLast) {
const parent = ctx.parent!
const parentId = parent.reference()
ctx.registerEffect(
[expr],
[
{
type: IRNodeTypes.SET_TEXT,
loc: node.loc,
element: parentId,
value: expr,
},
],
)
} else {
const id = ctx.reference()
ctx.dynamic.ghost = true
ctx.registerOperation({
type: IRNodeTypes.CREATE_TEXT_NODE,
loc: node.loc,
id,
value: expr,
})
ctx.registerEffect(
[expr],
[
{
type: IRNodeTypes.SET_TEXT,
loc: node.loc,
element: id,
value: expr,
},
],
)
}
}

View File

@ -0,0 +1,48 @@
import { NodeTypes } from '@vue/compiler-dom'
import { NodeTransform } from '../transform'
import { IRNodeTypes } from '../ir'
export const transformInterpolation: NodeTransform = (node, ctx) => {
if (node.type !== NodeTypes.INTERPOLATION) return
const expr = node.content
const parentChildren = ctx.parent ? ctx.parent.node.children : []
const isFirst = ctx.index === 0
const isLast = ctx.index === parentChildren.length - 1
if (isFirst && isLast) {
const parent = ctx.parent!
const parentId = parent.reference()
ctx.registerEffect(
[expr],
[
{
type: IRNodeTypes.SET_TEXT,
loc: node.loc,
element: parentId,
value: expr,
},
],
)
} else {
const id = ctx.reference()
ctx.dynamic.ghost = true
ctx.registerOperation({
type: IRNodeTypes.CREATE_TEXT_NODE,
loc: node.loc,
id,
value: expr,
})
ctx.registerEffect(
[expr],
[
{
type: IRNodeTypes.SET_TEXT,
loc: node.loc,
element: id,
value: expr,
},
],
)
}
}