refactor(compiler-vapor): remove ir expression
This commit is contained in:
parent
55a956e87d
commit
8fb01504da
|
@ -1,2 +0,0 @@
|
||||||
// TODO: add tests for this transform
|
|
||||||
test('baisc', () => {})
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
// TODO: add tests for this transform
|
||||||
|
describe('compiler: template ref transform', () => {
|
||||||
|
test.todo('basic')
|
||||||
|
})
|
|
@ -0,0 +1,4 @@
|
||||||
|
// TODO: add tests for this transform
|
||||||
|
describe('compiler: text transform', () => {
|
||||||
|
test.todo('basic')
|
||||||
|
})
|
|
@ -0,0 +1,4 @@
|
||||||
|
// TODO: add tests for this transform
|
||||||
|
describe('compiler: vModel transform', () => {
|
||||||
|
test.todo('basic')
|
||||||
|
})
|
|
@ -1,15 +1,15 @@
|
||||||
import {
|
import {
|
||||||
BindingTypes,
|
BindingTypes,
|
||||||
NewlineType,
|
NewlineType,
|
||||||
|
type SimpleExpressionNode,
|
||||||
type SourceLocation,
|
type SourceLocation,
|
||||||
advancePositionWithClone,
|
advancePositionWithClone,
|
||||||
isInDestructureAssignment,
|
isInDestructureAssignment,
|
||||||
isStaticProperty,
|
isStaticProperty,
|
||||||
walkIdentifiers,
|
walkIdentifiers,
|
||||||
} from '@vue/compiler-dom'
|
} from '@vue/compiler-dom'
|
||||||
import { isGloballyAllowed, isString, makeMap } from '@vue/shared'
|
import { isGloballyAllowed, makeMap } from '@vue/shared'
|
||||||
import type { Identifier } from '@babel/types'
|
import type { Identifier } from '@babel/types'
|
||||||
import type { IRExpression } from '../ir'
|
|
||||||
import {
|
import {
|
||||||
type CodeFragment,
|
type CodeFragment,
|
||||||
type CodegenContext,
|
type CodegenContext,
|
||||||
|
@ -18,13 +18,12 @@ import {
|
||||||
import type { Node } from '@babel/types'
|
import type { Node } from '@babel/types'
|
||||||
|
|
||||||
export function genExpression(
|
export function genExpression(
|
||||||
node: IRExpression,
|
node: SimpleExpressionNode,
|
||||||
context: CodegenContext,
|
context: CodegenContext,
|
||||||
): CodeFragment[] {
|
): CodeFragment[] {
|
||||||
const {
|
const {
|
||||||
options: { prefixIdentifiers },
|
options: { prefixIdentifiers },
|
||||||
} = context
|
} = context
|
||||||
if (isString(node)) return [node]
|
|
||||||
|
|
||||||
const { content: rawExpr, ast, isStatic, loc } = node
|
const { content: rawExpr, ast, isStatic, loc } = node
|
||||||
if (isStatic) {
|
if (isStatic) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { camelize, isString } from '@vue/shared'
|
import { camelize } from '@vue/shared'
|
||||||
import { genExpression } from './expression'
|
import { genExpression } from './expression'
|
||||||
import type { SetModelValueIRNode } from '../ir'
|
import type { SetModelValueIRNode } from '../ir'
|
||||||
import { type CodeFragment, type CodegenContext, NEWLINE } from '../generate'
|
import { type CodeFragment, type CodegenContext, NEWLINE } from '../generate'
|
||||||
|
@ -13,8 +13,8 @@ export function genSetModelValue(
|
||||||
options: { isTS },
|
options: { isTS },
|
||||||
} = context
|
} = context
|
||||||
|
|
||||||
const name = isString(oper.key)
|
const name = oper.key.isStatic
|
||||||
? [JSON.stringify(`update:${camelize(oper.key)}`)]
|
? [JSON.stringify(`update:${camelize(oper.key.content)}`)]
|
||||||
: ['`update:${', ...genExpression(oper.key, context), '}`']
|
: ['`update:${', ...genExpression(oper.key, context), '}`']
|
||||||
const handler = [
|
const handler = [
|
||||||
(isTS ? `($event: any)` : `$event`) + ' => ((',
|
(isTS ? `($event: any)` : `$event`) + ' => ((',
|
||||||
|
|
|
@ -64,7 +64,7 @@ export interface RootIRNode extends Omit<BlockFunctionIRNode, 'type'> {
|
||||||
export interface IfIRNode extends BaseIRNode {
|
export interface IfIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.IF
|
type: IRNodeTypes.IF
|
||||||
id: number
|
id: number
|
||||||
condition: IRExpression
|
condition: SimpleExpressionNode
|
||||||
positive: BlockFunctionIRNode
|
positive: BlockFunctionIRNode
|
||||||
negative?: BlockFunctionIRNode | IfIRNode
|
negative?: BlockFunctionIRNode | IfIRNode
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ export interface IfIRNode extends BaseIRNode {
|
||||||
export interface ForIRNode extends BaseIRNode {
|
export interface ForIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.FOR
|
type: IRNodeTypes.FOR
|
||||||
id: number
|
id: number
|
||||||
source: IRExpression
|
source: SimpleExpressionNode
|
||||||
value?: SimpleExpressionNode
|
value?: SimpleExpressionNode
|
||||||
key?: SimpleExpressionNode
|
key?: SimpleExpressionNode
|
||||||
index?: SimpleExpressionNode
|
index?: SimpleExpressionNode
|
||||||
|
@ -111,7 +111,7 @@ export type KeyOverride = [find: string, replacement: string]
|
||||||
export interface SetEventIRNode extends BaseIRNode {
|
export interface SetEventIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.SET_EVENT
|
type: IRNodeTypes.SET_EVENT
|
||||||
element: number
|
element: number
|
||||||
key: IRExpression
|
key: SimpleExpressionNode
|
||||||
value?: SimpleExpressionNode
|
value?: SimpleExpressionNode
|
||||||
modifiers: {
|
modifiers: {
|
||||||
// modifiers for addEventListener() options, e.g. .passive & .capture
|
// modifiers for addEventListener() options, e.g. .passive & .capture
|
||||||
|
@ -127,20 +127,20 @@ export interface SetEventIRNode extends BaseIRNode {
|
||||||
export interface SetHtmlIRNode extends BaseIRNode {
|
export interface SetHtmlIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.SET_HTML
|
type: IRNodeTypes.SET_HTML
|
||||||
element: number
|
element: number
|
||||||
value: IRExpression
|
value: SimpleExpressionNode
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetRefIRNode extends BaseIRNode {
|
export interface SetRefIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.SET_REF
|
type: IRNodeTypes.SET_REF
|
||||||
element: number
|
element: number
|
||||||
value: IRExpression
|
value: SimpleExpressionNode
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetModelValueIRNode extends BaseIRNode {
|
export interface SetModelValueIRNode extends BaseIRNode {
|
||||||
type: IRNodeTypes.SET_MODEL_VALUE
|
type: IRNodeTypes.SET_MODEL_VALUE
|
||||||
element: number
|
element: number
|
||||||
key: IRExpression
|
key: SimpleExpressionNode
|
||||||
value: IRExpression
|
value: SimpleExpressionNode
|
||||||
bindingType?: BindingTypes
|
bindingType?: BindingTypes
|
||||||
isComponent: boolean
|
isComponent: boolean
|
||||||
}
|
}
|
||||||
|
@ -218,9 +218,8 @@ export interface IRDynamicInfo {
|
||||||
children: IRDynamicInfo[]
|
children: IRDynamicInfo[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IRExpression = SimpleExpressionNode | string
|
|
||||||
export interface IREffect {
|
export interface IREffect {
|
||||||
expressions: IRExpression[]
|
expressions: SimpleExpressionNode[]
|
||||||
operations: OperationNode[]
|
operations: OperationNode[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
type SimpleExpressionNode,
|
type SimpleExpressionNode,
|
||||||
type TemplateChildNode,
|
type TemplateChildNode,
|
||||||
type TemplateNode,
|
type TemplateNode,
|
||||||
|
createSimpleExpression,
|
||||||
defaultOnError,
|
defaultOnError,
|
||||||
defaultOnWarn,
|
defaultOnWarn,
|
||||||
isVSlot,
|
isVSlot,
|
||||||
|
@ -21,7 +22,6 @@ import {
|
||||||
DynamicFlag,
|
DynamicFlag,
|
||||||
type HackOptions,
|
type HackOptions,
|
||||||
type IRDynamicInfo,
|
type IRDynamicInfo,
|
||||||
type IRExpression,
|
|
||||||
IRNodeTypes,
|
IRNodeTypes,
|
||||||
type OperationNode,
|
type OperationNode,
|
||||||
type RootIRNode,
|
type RootIRNode,
|
||||||
|
@ -77,7 +77,7 @@ export interface TransformContext<T extends AllNode = AllNode> {
|
||||||
increaseId(): number
|
increaseId(): number
|
||||||
registerTemplate(): number
|
registerTemplate(): number
|
||||||
registerEffect(
|
registerEffect(
|
||||||
expressions: Array<IRExpression | null | undefined>,
|
expressions: SimpleExpressionNode[],
|
||||||
operation: OperationNode[],
|
operation: OperationNode[],
|
||||||
): void
|
): void
|
||||||
registerOperation(...operations: OperationNode[]): void
|
registerOperation(...operations: OperationNode[]): void
|
||||||
|
@ -153,35 +153,28 @@ function createRootContext(
|
||||||
return (this.dynamic.id = this.increaseId())
|
return (this.dynamic.id = this.increaseId())
|
||||||
},
|
},
|
||||||
registerEffect(expressions, operations) {
|
registerEffect(expressions, operations) {
|
||||||
if (
|
expressions = expressions.filter(exp => !exp.isStatic)
|
||||||
this.inVOnce ||
|
if (this.inVOnce || expressions.length === 0) {
|
||||||
(expressions = expressions.filter(Boolean)).length === 0
|
|
||||||
) {
|
|
||||||
return this.registerOperation(...operations)
|
return this.registerOperation(...operations)
|
||||||
}
|
}
|
||||||
const existing = this.block.effect.find(e =>
|
const existing = this.block.effect.find(e =>
|
||||||
isSameExpression(e.expressions, expressions as IRExpression[]),
|
isSameExpression(e.expressions, expressions),
|
||||||
)
|
)
|
||||||
if (existing) {
|
if (existing) {
|
||||||
existing.operations.push(...operations)
|
existing.operations.push(...operations)
|
||||||
} else {
|
} else {
|
||||||
this.block.effect.push({
|
this.block.effect.push({
|
||||||
expressions: expressions as IRExpression[],
|
expressions,
|
||||||
operations,
|
operations,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSameExpression(a: IRExpression[], b: IRExpression[]) {
|
function isSameExpression(
|
||||||
a = a.filter(filterStatic)
|
a: SimpleExpressionNode[],
|
||||||
b = b.filter(filterStatic)
|
b: SimpleExpressionNode[],
|
||||||
|
) {
|
||||||
if (a.length !== b.length) return false
|
if (a.length !== b.length) return false
|
||||||
return (a as SimpleExpressionNode[]).every(
|
return a.every((exp, i) => exp.content === b[i].content)
|
||||||
(exp, i) => exp.content === (b as SimpleExpressionNode[])[i].content,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterStatic(exp: IRExpression): exp is SimpleExpressionNode {
|
|
||||||
return !isString(exp) && !exp.isStatic
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -434,3 +427,5 @@ export function wrapTemplate(node: ElementNode, dirs: string[]): TemplateNode {
|
||||||
children: [extend({}, node, { props: pass } as TemplateChildNode)],
|
children: [extend({}, node, { props: pass } as TemplateChildNode)],
|
||||||
} as Partial<TemplateNode>)
|
} as Partial<TemplateNode>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const EMPTY_EXPRESSION = createSimpleExpression('', true)
|
||||||
|
|
|
@ -14,10 +14,11 @@ import {
|
||||||
isReservedProp,
|
isReservedProp,
|
||||||
isVoidTag,
|
isVoidTag,
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import type {
|
import {
|
||||||
DirectiveTransformResult,
|
type DirectiveTransformResult,
|
||||||
NodeTransform,
|
EMPTY_EXPRESSION,
|
||||||
TransformContext,
|
type NodeTransform,
|
||||||
|
type TransformContext,
|
||||||
} from '../transform'
|
} from '../transform'
|
||||||
import {
|
import {
|
||||||
IRNodeTypes,
|
IRNodeTypes,
|
||||||
|
@ -154,11 +155,9 @@ function transformProp(
|
||||||
if (prop.type === NodeTypes.ATTRIBUTE) {
|
if (prop.type === NodeTypes.ATTRIBUTE) {
|
||||||
return {
|
return {
|
||||||
key: createSimpleExpression(prop.name, true, prop.nameLoc),
|
key: createSimpleExpression(prop.name, true, prop.nameLoc),
|
||||||
value: createSimpleExpression(
|
value: prop.value
|
||||||
prop.value ? prop.value.content : '',
|
? createSimpleExpression(prop.value.content, true, prop.value.loc)
|
||||||
true,
|
: EMPTY_EXPRESSION,
|
||||||
prop.value && prop.value.loc,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,29 @@
|
||||||
import {
|
import {
|
||||||
|
type AttributeNode,
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
type SimpleExpressionNode,
|
type SimpleExpressionNode,
|
||||||
|
createSimpleExpression,
|
||||||
findProp,
|
findProp,
|
||||||
} from '@vue/compiler-dom'
|
} from '@vue/compiler-dom'
|
||||||
import type { NodeTransform } from '../transform'
|
import { EMPTY_EXPRESSION, type NodeTransform } from '../transform'
|
||||||
import { type IRExpression, IRNodeTypes } from '../ir'
|
import { IRNodeTypes, type VaporDirectiveNode } from '../ir'
|
||||||
import { normalizeBindShorthand } from './vBind'
|
import { normalizeBindShorthand } from './vBind'
|
||||||
|
|
||||||
export const transformRef: NodeTransform = (node, context) => {
|
export const transformRef: NodeTransform = (node, context) => {
|
||||||
if (node.type !== NodeTypes.ELEMENT) return
|
if (node.type !== NodeTypes.ELEMENT) return
|
||||||
const dir = findProp(node, 'ref', false, true)
|
const dir = findProp(node, 'ref', false, true) as
|
||||||
|
| VaporDirectiveNode
|
||||||
|
| AttributeNode
|
||||||
|
|
||||||
if (!dir) return
|
if (!dir) return
|
||||||
|
|
||||||
let value: IRExpression
|
let value: SimpleExpressionNode
|
||||||
if (dir.type === NodeTypes.DIRECTIVE) {
|
if (dir.type === NodeTypes.DIRECTIVE) {
|
||||||
value =
|
value = dir.exp || normalizeBindShorthand(dir.arg!, context)
|
||||||
(dir.exp as SimpleExpressionNode | undefined) ||
|
|
||||||
normalizeBindShorthand(dir.arg as SimpleExpressionNode, context)
|
|
||||||
} else {
|
} else {
|
||||||
value = dir.value ? JSON.stringify(dir.value.content) : '""'
|
value = dir.value
|
||||||
|
? createSimpleExpression(dir.value.content, true, dir.value.loc)
|
||||||
|
: EMPTY_EXPRESSION
|
||||||
}
|
}
|
||||||
|
|
||||||
context.registerOperation({
|
context.registerOperation({
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import { IRNodeTypes } from '../ir'
|
import { IRNodeTypes } from '../ir'
|
||||||
import type { DirectiveTransform } from '../transform'
|
import { type DirectiveTransform, EMPTY_EXPRESSION } from '../transform'
|
||||||
import { DOMErrorCodes, createDOMCompilerError } from '@vue/compiler-dom'
|
import { DOMErrorCodes, createDOMCompilerError } from '@vue/compiler-dom'
|
||||||
|
|
||||||
export const transformVHtml: DirectiveTransform = (dir, node, context) => {
|
export const transformVHtml: DirectiveTransform = (dir, node, context) => {
|
||||||
const { exp, loc } = dir
|
let { exp, loc } = dir
|
||||||
if (!exp) {
|
if (!exp) {
|
||||||
context.options.onError(
|
context.options.onError(
|
||||||
createDOMCompilerError(DOMErrorCodes.X_V_HTML_NO_EXPRESSION, loc),
|
createDOMCompilerError(DOMErrorCodes.X_V_HTML_NO_EXPRESSION, loc),
|
||||||
)
|
)
|
||||||
|
exp = EMPTY_EXPRESSION
|
||||||
}
|
}
|
||||||
if (node.children.length) {
|
if (node.children.length) {
|
||||||
context.options.onError(
|
context.options.onError(
|
||||||
|
@ -22,7 +23,7 @@ export const transformVHtml: DirectiveTransform = (dir, node, context) => {
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_HTML,
|
type: IRNodeTypes.SET_HTML,
|
||||||
element: context.reference(),
|
element: context.reference(),
|
||||||
value: exp || '""',
|
value: exp,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
createCompilerError,
|
createCompilerError,
|
||||||
createDOMCompilerError,
|
createDOMCompilerError,
|
||||||
|
createSimpleExpression,
|
||||||
findDir,
|
findDir,
|
||||||
findProp,
|
findProp,
|
||||||
hasDynamicKeyVBind,
|
hasDynamicKeyVBind,
|
||||||
|
@ -137,7 +138,7 @@ export const transformVModel: DirectiveTransform = (dir, node, context) => {
|
||||||
context.registerOperation({
|
context.registerOperation({
|
||||||
type: IRNodeTypes.SET_MODEL_VALUE,
|
type: IRNodeTypes.SET_MODEL_VALUE,
|
||||||
element: context.reference(),
|
element: context.reference(),
|
||||||
key: (arg && arg.isStatic ? arg.content : arg) || 'modelValue',
|
key: arg || createSimpleExpression('modelValue', true),
|
||||||
value: exp,
|
value: exp,
|
||||||
isComponent,
|
isComponent,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
import {
|
import { DOMErrorCodes, createDOMCompilerError } from '@vue/compiler-dom'
|
||||||
DOMErrorCodes,
|
import { type DirectiveTransform, EMPTY_EXPRESSION } from '../transform'
|
||||||
createDOMCompilerError,
|
|
||||||
createSimpleExpression,
|
|
||||||
} from '@vue/compiler-dom'
|
|
||||||
import type { DirectiveTransform } from '../transform'
|
|
||||||
import { IRNodeTypes } from '../ir'
|
import { IRNodeTypes } from '../ir'
|
||||||
|
|
||||||
export const transformVText: DirectiveTransform = (dir, node, context) => {
|
export const transformVText: DirectiveTransform = (dir, node, context) => {
|
||||||
const { exp, loc } = dir
|
let { exp, loc } = dir
|
||||||
if (!exp) {
|
if (!exp) {
|
||||||
context.options.onError(
|
context.options.onError(
|
||||||
createDOMCompilerError(DOMErrorCodes.X_V_TEXT_NO_EXPRESSION, loc),
|
createDOMCompilerError(DOMErrorCodes.X_V_TEXT_NO_EXPRESSION, loc),
|
||||||
)
|
)
|
||||||
|
exp = EMPTY_EXPRESSION
|
||||||
}
|
}
|
||||||
if (node.children.length) {
|
if (node.children.length) {
|
||||||
context.options.onError(
|
context.options.onError(
|
||||||
|
@ -26,7 +23,7 @@ export const transformVText: DirectiveTransform = (dir, node, context) => {
|
||||||
{
|
{
|
||||||
type: IRNodeTypes.SET_TEXT,
|
type: IRNodeTypes.SET_TEXT,
|
||||||
element: context.reference(),
|
element: context.reference(),
|
||||||
values: [exp || createSimpleExpression('', true)],
|
values: [exp],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue