提交 34efd782 编写于 作者: fxy060608's avatar fxy060608

chore: merge

上级 1263e73d
......@@ -49,6 +49,12 @@ describe('compiler: v-bind', () => {
`createElementVNode("view", utsMapOf({ id: _ctx.id }), null, 8 /* PROPS */, ["id"])`
)
})
test('object expression', () => {
assert(
`<view v-bind="{id}"/>`,
`createElementVNode("view", normalizeProps(guardReactiveProps(utsMapOf({id: _ctx.id}))), null, 16 /* FULL_PROPS */)`
)
})
test('dynamic arg', () => {
assert(
`<view v-bind:[id]="id"/>`,
......
......@@ -175,7 +175,7 @@ _ctx.bar()
test('empty object syntax', () => {
assert(
`<text v-on="{ }"/>`,
`createElementVNode("text", toHandlers(utsMapOf({ }), true), null, 16 /* FULL_PROPS */)`
`createElementVNode("text", toHandlers(utsMapOf<string, any | null>({ }), true), null, 16 /* FULL_PROPS */)`
)
})
test('simple object syntax', () => {
......
......@@ -42,12 +42,7 @@ import {
RESOLVE_COMPONENT,
RESOLVE_DIRECTIVE,
RESOLVE_EASY_COMPONENT,
TO_HANDLERS,
} from './runtimeHelpers'
import {
isCompoundExpressionNode,
isSimpleExpressionNode,
} from '@dcloudio/uni-cli-shared'
type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode
......@@ -539,9 +534,6 @@ function genCallExpression(node: CallExpression, context: CodegenContext) {
if (callee === helper(RENDER_LIST)) {
genRenderList(node)
}
if (callee === helper(TO_HANDLERS)) {
genToHandlers(node, context)
}
genNodeList(node.arguments, context)
push(`)`)
......@@ -555,18 +547,6 @@ function genRenderList(node: CallExpression) {
})
}
function genToHandlers(node: CallExpression, context: CodegenContext) {
const args = node.arguments[0]
if (isString(args) || isSymbol(args) || isArray(args)) {
// skip
} else if (isSimpleExpressionNode(args)) {
args.content = `utsMapOf(${args.content})`
} else if (isCompoundExpressionNode(args)) {
args.children.unshift(`utsMapOf(`)
args.children.push(')')
}
}
function genObjectExpression(node: ObjectExpression, context: CodegenContext) {
const { push, indent, deindent, newline } = context
const { properties } = node
......
......@@ -4,7 +4,6 @@ import {
trackSlotScopes,
trackVForSlotScopes,
transformElement,
transformExpression,
} from '@vue/compiler-core'
import { isAppUVueNativeTag } from '@dcloudio/uni-shared'
......@@ -24,7 +23,8 @@ import { transformText } from './transforms/transformText'
import { transformOn } from './transforms/vOn'
import { transformBind } from './transforms/vBind'
import { transformSlotOutlet } from './transforms/transformSlotOutlet'
// import { transformExpression } from './transforms/transformExpression'
import { transformObjectExpression } from './transforms/transformObjectExpression'
import { transformExpression } from './transforms/transformExpression'
export type TransformPreset = [
NodeTransform[],
......@@ -47,6 +47,7 @@ export function getBaseTransformPreset(
transformText,
transformTapToClick,
transformInterpolation,
transformObjectExpression,
] as any,
{
on: transformOn,
......
......@@ -31,9 +31,11 @@ import {
import { createCompilerError, ErrorCodes } from '../errors'
const GLOBALS_WHITE_LISTED = `Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,
decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,
Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console`
const GLOBALS_WHITE_LISTED =
`Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI` +
`,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array` +
`,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt` +
`,console`
const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED)
const isLiteralWhitelisted = /*#__PURE__*/ makeMap('true,false,null,this')
......
import { isDirectiveNode, isElementNode } from '@dcloudio/uni-cli-shared'
import { NodeTransform } from '../transform'
import { rewriteObjectExpression } from '../utils'
export const transformObjectExpression: NodeTransform = (node, context) => {
// 因为 v-bind without arg 是被 transformElements.ts 直接处理的,没办法在 vBind 中解析处理objectExpression
// 所以 统一在这里拦截处理
return function postTransformObjectExpression() {
node = context.currentNode!
if (!isElementNode(node)) {
return
}
node.props.forEach((p) => {
if (!isDirectiveNode(p) || !p.exp) {
return
}
if (p.name === 'bind' || p.name === 'on') {
const newExp = rewriteObjectExpression(p.exp, context)
if (newExp) {
p.exp = newExp
}
}
})
}
}
import { camelize } from '@vue/shared'
import { parseExpression } from '@babel/parser'
import type { Node } from '@babel/types'
import { CAMELIZE } from '@vue/compiler-core'
import {
createObjectProperty,
......@@ -12,9 +10,6 @@ import {
import type { DirectiveTransform } from '../transform'
import { createCompilerError, ErrorCodes } from '../errors'
import { stringifyExpression } from './transformExpression'
import { MagicString, walk } from '@vue/compiler-sfc'
// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
// codegen for the entire props object. This transform here is only for v-bind
// *with* args.
......@@ -61,35 +56,6 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
props: [createObjectProperty(arg, createSimpleExpression('', true, loc))],
}
}
// 简易处理,理论上rust中也可以处理,但为了单元测试一致性,还是在该阶段中处理
const source = stringifyExpression(exp)
if (source.includes('{')) {
const s = new MagicString(source)
const ast = parseExpression(source, {
plugins: context.expressionPlugins,
})
walk(ast, {
enter(node: Node) {
if (node.type === 'ObjectExpression') {
const type = s.original
.substring(1, s.original.length - 1)
.replaceAll(/\s+/g, '')
? ''
: '<string, any | null>'
s.prependLeft(node.start!, `utsMapOf${type}(`)
s.prependRight(node.end!, ')')
}
},
})
return {
props: [
createObjectProperty(
arg,
createSimpleExpression(s.toString(), false, exp.loc)
),
],
}
}
return {
props: [createObjectProperty(arg, exp)],
}
......
import { makeMap } from '@vue/shared'
import type { Node } from '@babel/types'
import { ExpressionNode, createSimpleExpression } from '@vue/compiler-core'
import { MagicString, walk } from '@vue/compiler-sfc'
import { parseExpression } from '@babel/parser'
import { CompilerOptions } from './options'
import { stringifyExpression } from './transforms/transformExpression'
import { TransformContext } from './transform'
export function genRenderFunctionDecl({
targetLanguage,
filename,
......@@ -10,10 +17,29 @@ export function genRenderFunctionDecl({
}function ${filename}Render(): VNode | null`
}
const GLOBALS_WHITE_LISTED =
'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt' +
'console'
export const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED)
export function rewriteObjectExpression(
exp: ExpressionNode,
context: TransformContext
) {
const source = stringifyExpression(exp)
if (source.includes('{')) {
const s = new MagicString(source)
const ast = parseExpression(source, {
plugins: context.expressionPlugins,
})
walk(ast, {
enter(node: Node) {
if (node.type === 'ObjectExpression') {
s.prependLeft(
node.start!,
node.properties.length > 0
? 'utsMapOf('
: 'utsMapOf<string, any | null>('
)
s.prependRight(node.end!, ')')
}
},
})
return createSimpleExpression(s.toString(), false, exp.loc)
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册