From: 三咲智子 Kevin Deng Date: Tue, 5 Dec 2023 09:13:25 +0000 (+0800) Subject: fix: exclude compund expression type X-Git-Tag: v3.6.0-alpha.1~16^2~747 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3474e06542be5cacb478218ddca30c6b6f614507;p=thirdparty%2Fvuejs%2Fcore.git fix: exclude compund expression type --- diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index 4cd284e84a..2718801d1d 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -6,7 +6,6 @@ import { NewlineType, advancePositionWithMutation, locStub, - NodeTypes, BindingTypes, isSimpleIdentifier, createSimpleExpression, @@ -14,12 +13,19 @@ import { import { type IRDynamicChildren, type RootIRNode, + type SetPropIRNode, + type IRExpression, + type OperationNode, + type VaporHelper, + type SetEventIRNode, + type WithDirectiveIRNode, + type SetTextIRNode, IRNodeTypes, - OperationNode, - VaporHelper, - IRExpression, - SetEventIRNode, - WithDirectiveIRNode, + SetHtmlIRNode, + CreateTextNodeIRNode, + InsertNodeIRNode, + PrependNodeIRNode, + AppendNodeIRNode, } from './ir' import { SourceMapGenerator } from 'source-map-js' import { camelize, isString } from '@vue/shared' @@ -307,80 +313,6 @@ export function generate( } } -function genOperation(oper: OperationNode, context: CodegenContext) { - const { vaporHelper, push, pushWithNewline } = context - // TODO: cache old value - switch (oper.type) { - case IRNodeTypes.SET_PROP: { - pushWithNewline(`${vaporHelper('setAttr')}(n${oper.element}, `) - genExpression(oper.name, context) - push(`, undefined, `) - genExpression(oper.value, context) - push(')') - return - } - - case IRNodeTypes.SET_TEXT: { - pushWithNewline(`${vaporHelper('setText')}(n${oper.element}, undefined, `) - genExpression(oper.value, context) - push(')') - return - } - - case IRNodeTypes.SET_EVENT: { - return genSetEvent(oper, context) - } - - case IRNodeTypes.SET_HTML: { - pushWithNewline(`${vaporHelper('setHtml')}(n${oper.element}, undefined, `) - genExpression(oper.value, context) - push(')') - return - } - - case IRNodeTypes.CREATE_TEXT_NODE: { - pushWithNewline(`const n${oper.id} = ${vaporHelper('createTextNode')}(`) - genExpression(oper.value, context) - push(')') - return - } - - case IRNodeTypes.INSERT_NODE: { - const elements = ([] as number[]).concat(oper.element) - let element = elements.map((el) => `n${el}`).join(', ') - if (elements.length > 1) element = `[${element}]` - pushWithNewline( - `${vaporHelper('insert')}(${element}, n${ - oper.parent - }${`, n${oper.anchor}`})`, - ) - return - } - case IRNodeTypes.PREPEND_NODE: { - pushWithNewline( - `${vaporHelper('prepend')}(n${oper.parent}, ${oper.elements - .map((el) => `n${el}`) - .join(', ')})`, - ) - return - } - case IRNodeTypes.APPEND_NODE: { - pushWithNewline( - `${vaporHelper('append')}(n${oper.parent}, ${oper.elements - .map((el) => `n${el}`) - .join(', ')})`, - ) - return - } - case IRNodeTypes.WITH_DIRECTIVE: { - // generated, skip - return - } - default: - return checkNever(oper) - } -} - function genChildren(children: IRDynamicChildren) { let code = '' // TODO @@ -407,49 +339,94 @@ function genChildren(children: IRDynamicChildren) { return `{${code}}` } -// TODO: other types (not only string) -function genArrayExpression(elements: string[]) { - return `[${elements.map((it) => JSON.stringify(it)).join(', ')}]` +function genOperation(oper: OperationNode, context: CodegenContext) { + // TODO: cache old value + switch (oper.type) { + case IRNodeTypes.SET_PROP: + return genSetProp(oper, context) + case IRNodeTypes.SET_TEXT: + return genSetText(oper, context) + case IRNodeTypes.SET_EVENT: + return genSetEvent(oper, context) + case IRNodeTypes.SET_HTML: + return genSetHtml(oper, context) + case IRNodeTypes.CREATE_TEXT_NODE: + return genCreateTextNode(oper, context) + case IRNodeTypes.INSERT_NODE: + return genInsertNode(oper, context) + case IRNodeTypes.PREPEND_NODE: + return genPrependNode(oper, context) + case IRNodeTypes.APPEND_NODE: + return genAppendNode(oper, context) + case IRNodeTypes.WITH_DIRECTIVE: + // generated, skip + return + default: + return checkNever(oper) + } } -function genExpression( - exp: IRExpression, - { - inline, - prefixIdentifiers, - bindingMetadata, - vaporHelper, - push, - }: CodegenContext, - { unref = true }: { unref?: boolean } = {}, -) { - if (isString(exp)) return push(exp) +function genSetProp(oper: SetPropIRNode, context: CodegenContext) { + const { push, pushWithNewline, vaporHelper } = context + pushWithNewline(`${vaporHelper('setAttr')}(n${oper.element}, `) + genExpression(oper.name, context) + push(`, undefined, `) + genExpression(oper.value, context) + push(')') +} - // TODO NodeTypes.COMPOUND_EXPRESSION - if (exp.type === NodeTypes.COMPOUND_EXPRESSION) return +function genSetText(oper: SetTextIRNode, context: CodegenContext) { + const { push, pushWithNewline, vaporHelper } = context + pushWithNewline(`${vaporHelper('setText')}(n${oper.element}, undefined, `) + genExpression(oper.value, context) + push(')') +} - let { content } = exp - let name: string | undefined +function genSetHtml(oper: SetHtmlIRNode, context: CodegenContext) { + const { push, pushWithNewline, vaporHelper } = context + pushWithNewline(`${vaporHelper('setHtml')}(n${oper.element}, undefined, `) + genExpression(oper.value, context) + push(')') +} - if (exp.isStatic) { - content = JSON.stringify(content) - } else { - if (unref) - switch (bindingMetadata[content]) { - case BindingTypes.SETUP_REF: - content += '.value' - break - case BindingTypes.SETUP_MAYBE_REF: - content = `${vaporHelper('unref')}(${content})` - break - } - if (prefixIdentifiers && !inline) { - if (isSimpleIdentifier(content)) name = content - content = `_ctx.${content}` - } - } +function genCreateTextNode( + oper: CreateTextNodeIRNode, + context: CodegenContext, +) { + const { push, pushWithNewline, vaporHelper } = context + pushWithNewline(`const n${oper.id} = ${vaporHelper('createTextNode')}(`) + genExpression(oper.value, context) + push(')') +} - push(content, NewlineType.None, exp.loc, name) +function genInsertNode(oper: InsertNodeIRNode, context: CodegenContext) { + const { pushWithNewline, vaporHelper } = context + const elements = ([] as number[]).concat(oper.element) + let element = elements.map((el) => `n${el}`).join(', ') + if (elements.length > 1) element = `[${element}]` + pushWithNewline( + `${vaporHelper('insert')}(${element}, n${ + oper.parent + }${`, n${oper.anchor}`})`, + ) +} + +function genPrependNode(oper: PrependNodeIRNode, context: CodegenContext) { + const { pushWithNewline, vaporHelper } = context + pushWithNewline( + `${vaporHelper('prepend')}(n${oper.parent}, ${oper.elements + .map((el) => `n${el}`) + .join(', ')})`, + ) +} + +function genAppendNode(oper: AppendNodeIRNode, context: CodegenContext) { + const { pushWithNewline, vaporHelper } = context + pushWithNewline( + `${vaporHelper('append')}(n${oper.parent}, ${oper.elements + .map((el) => `n${el}`) + .join(', ')})`, + ) } function genSetEvent(oper: SetEventIRNode, context: CodegenContext) { @@ -500,3 +477,43 @@ function genWithDirective(oper: WithDirectiveIRNode, context: CodegenContext) { push(']])') return } + +// TODO: other types (not only string) +function genArrayExpression(elements: string[]) { + return `[${elements.map((it) => JSON.stringify(it)).join(', ')}]` +} + +function genExpression( + exp: IRExpression, + { + inline, + prefixIdentifiers, + bindingMetadata, + vaporHelper, + push, + }: CodegenContext, +) { + if (isString(exp)) return push(exp) + + let { content } = exp + let name: string | undefined + + if (exp.isStatic) { + content = JSON.stringify(content) + } else { + switch (bindingMetadata[content]) { + case BindingTypes.SETUP_REF: + content += '.value' + break + case BindingTypes.SETUP_MAYBE_REF: + content = `${vaporHelper('unref')}(${content})` + break + } + if (prefixIdentifiers && !inline) { + if (isSimpleIdentifier(content)) name = content + content = `_ctx.${content}` + } + } + + push(content, NewlineType.None, exp.loc, name) +} diff --git a/packages/compiler-vapor/src/ir.ts b/packages/compiler-vapor/src/ir.ts index 0ed0ebfb3f..78ddc6ec88 100644 --- a/packages/compiler-vapor/src/ir.ts +++ b/packages/compiler-vapor/src/ir.ts @@ -1,6 +1,7 @@ import type { - ExpressionNode, + DirectiveNode, RootNode, + SimpleExpressionNode, SourceLocation, } from '@vue/compiler-dom' import type { Prettify } from '@vue/shared' @@ -145,7 +146,7 @@ export interface IRDynamicInfo { } export type IRDynamicChildren = Record -export type IRExpression = ExpressionNode | string +export type IRExpression = SimpleExpressionNode | string export interface IREffect { // TODO multi-expression effect expressions: IRExpression[] @@ -164,3 +165,11 @@ export type HackOptions = Prettify< } > > + +export type HackDirectiveNode = Overwrite< + DirectiveNode, + { + exp: SimpleExpressionNode | undefined + arg: SimpleExpressionNode | undefined + } +> diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 2132fcf43c..ce0b373c2a 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -9,7 +9,6 @@ import { NodeTypes, defaultOnError, defaultOnWarn, - DirectiveNode, } from '@vue/compiler-dom' import { EMPTY_OBJ, NOOP, isArray } from '@vue/shared' import { @@ -19,7 +18,7 @@ import { type IRExpression, IRNodeTypes, } from './ir' -import type { HackOptions } from './ir' +import type { HackDirectiveNode, HackOptions } from './ir' export type NodeTransform = ( node: RootNode | TemplateChildNode, @@ -27,7 +26,7 @@ export type NodeTransform = ( ) => void | (() => void) | (() => void)[] export type DirectiveTransform = ( - dir: DirectiveNode, + dir: HackDirectiveNode, node: ElementNode, context: TransformContext, // a platform specific compiler can import the base transform and augment diff --git a/packages/compiler-vapor/src/transforms/transformElement.ts b/packages/compiler-vapor/src/transforms/transformElement.ts index 9ac60cd9ba..6a3615b73e 100644 --- a/packages/compiler-vapor/src/transforms/transformElement.ts +++ b/packages/compiler-vapor/src/transforms/transformElement.ts @@ -1,7 +1,6 @@ import { type ElementNode, type AttributeNode, - type DirectiveNode, NodeTypes, ErrorCodes, createCompilerError, @@ -9,7 +8,7 @@ import { } from '@vue/compiler-dom' import { isBuiltInDirective, isVoidTag } from '@vue/shared' import { NodeTransform, TransformContext } from '../transform' -import { IRNodeTypes } from '../ir' +import { HackDirectiveNode, IRNodeTypes } from '../ir' export const transformElement: NodeTransform = (node, ctx) => { return function postTransformElement() { @@ -53,17 +52,16 @@ function buildProps( isComponent: boolean, ) { for (const prop of props) { - transformProp(prop, node, context) + transformProp(prop as HackDirectiveNode | AttributeNode, node, context) } } function transformProp( - prop: DirectiveNode | AttributeNode, + prop: HackDirectiveNode | AttributeNode, node: ElementNode, context: TransformContext, ): void { const { name } = prop - if (prop.type === NodeTypes.ATTRIBUTE) { context.template += ` ${name}` if (prop.value) context.template += `="${prop.value.content}"` @@ -79,17 +77,14 @@ function transformProp( type: IRNodeTypes.WITH_DIRECTIVE, element: context.reference(), name, - binding: prop.exp, + binding: exp, loc: prop.loc, }) } switch (name) { case 'bind': { - if ( - !exp || - (exp.type === NodeTypes.SIMPLE_EXPRESSION && !exp.content.trim()) - ) { + if (!exp || !exp.content.trim()) { context.options.onError( createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc), ) diff --git a/packages/compiler-vapor/src/transforms/transformInterpolation.ts b/packages/compiler-vapor/src/transforms/transformInterpolation.ts index 4bd51a5717..dd7537aecc 100644 --- a/packages/compiler-vapor/src/transforms/transformInterpolation.ts +++ b/packages/compiler-vapor/src/transforms/transformInterpolation.ts @@ -1,11 +1,11 @@ -import { NodeTypes } from '@vue/compiler-dom' +import { NodeTypes, SimpleExpressionNode } 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 expr = node.content as SimpleExpressionNode const parentChildren = ctx.parent ? ctx.parent.node.children : [] const isFirst = ctx.index === 0 const isLast = ctx.index === parentChildren.length - 1 diff --git a/packages/compiler-vapor/src/transforms/vOn.ts b/packages/compiler-vapor/src/transforms/vOn.ts index a8ed5fd7d5..0183138ef1 100644 --- a/packages/compiler-vapor/src/transforms/vOn.ts +++ b/packages/compiler-vapor/src/transforms/vOn.ts @@ -25,9 +25,6 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => { } else if (exp === undefined) { // TODO X_V_ON_NO_EXPRESSION error return - } else if (arg.type === NodeTypes.COMPOUND_EXPRESSION) { - // TODO - return } const handlerKey = `on${arg.content}`