提交 5e3b2d97 编写于 作者: fxy060608's avatar fxy060608

wip(uts): compiler

上级 66327d75
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`stringifyMap basic 1`] = `"new Map<string, any>([["color","#7A7E83"],["selectedColor","#3cc51f"],["borderStyle","black"],["backgroundColor","#ffffff"],["list",[new Map<string, any>([["pagePath","pages/component/index"],["iconPath","static/image/icon_component.png"],["selectedIconPath","static/image/icon_component_HL.png"],["text","组件"]]),new Map<string, any>([["pagePath","pages/API/index"],["iconPath","static/image/icon_API.png"],["selectedIconPath","static/image/icon_API_HL.png"],["text","接口"]])]]])"`; exports[`stringifyMap basic 1`] = `"utsMapOf([["color","#7A7E83"],["selectedColor","#3cc51f"],["borderStyle","black"],["backgroundColor","#ffffff"],["list",[utsMapOf([["pagePath","pages/component/index"],["iconPath","static/image/icon_component.png"],["selectedIconPath","static/image/icon_component_HL.png"],["text","组件"]]),utsMapOf([["pagePath","pages/API/index"],["iconPath","static/image/icon_API.png"],["selectedIconPath","static/image/icon_API_HL.png"],["text","接口"]])]]])"`;
...@@ -5,7 +5,7 @@ describe('compiler:codegen', () => { ...@@ -5,7 +5,7 @@ describe('compiler:codegen', () => {
assert(`<view/>`, `createElementVNode("view")`) assert(`<view/>`, `createElementVNode("view")`)
assert( assert(
`<view style="width:100px;height:100px;"/>`, `<view style="width:100px;height:100px;"/>`,
`createElementVNode("view", new Map<string, any | null>([["style", "width:100px;height:100px;"]]))` `createElementVNode("view", utsMapOf({ style: "width:100px;height:100px;" }))`
) )
assert( assert(
`<text>{{msg}}</text>`, `<text>{{msg}}</text>`,
......
import { assert } from './testUtils' import { assert } from './testUtils'
console.log( console.log(assert(`<Foo v-model="model as string" />`, ``))
assert(`<view style="width:100px;height:100px;"><text>aaa</text></view>`, ``)
)
...@@ -8,7 +8,7 @@ exports[`compiler: v-for codegen basic v-for 1`] = ` ...@@ -8,7 +8,7 @@ exports[`compiler: v-for codegen basic v-for 1`] = `
exports[`compiler: v-for codegen keyed template v-for 1`] = ` exports[`compiler: v-for codegen keyed template v-for 1`] = `
"createElementVNode(Fragment, null, RenderHelpers.renderList(items, (item, _, _):VNode => { "createElementVNode(Fragment, null, RenderHelpers.renderList(items, (item, _, _):VNode => {
return createElementVNode(Fragment, new Map<string, any | null>([["key", item]]), [ return createElementVNode(Fragment, utsMapOf({ key: item }), [
"hello", "hello",
createElementVNode("text") createElementVNode("text")
], 64 /* STABLE_FRAGMENT */) ], 64 /* STABLE_FRAGMENT */)
...@@ -17,7 +17,7 @@ exports[`compiler: v-for codegen keyed template v-for 1`] = ` ...@@ -17,7 +17,7 @@ exports[`compiler: v-for codegen keyed template v-for 1`] = `
exports[`compiler: v-for codegen keyed v-for 1`] = ` exports[`compiler: v-for codegen keyed v-for 1`] = `
"createElementVNode(Fragment, null, RenderHelpers.renderList(items, (item, _, _):VNode => { "createElementVNode(Fragment, null, RenderHelpers.renderList(items, (item, _, _):VNode => {
return createElementVNode("text", new Map<string, any | null>([["key", item]])) return createElementVNode("text", utsMapOf({ key: item }))
}), 128 /* KEYED_FRAGMENT */)" }), 128 /* KEYED_FRAGMENT */)"
`; `;
...@@ -50,10 +50,10 @@ exports[`compiler: v-for codegen template v-for 1`] = ` ...@@ -50,10 +50,10 @@ exports[`compiler: v-for codegen template v-for 1`] = `
exports[`compiler: v-for codegen template v-for key injection with single child 1`] = ` exports[`compiler: v-for codegen template v-for key injection with single child 1`] = `
"createElementVNode(Fragment, null, RenderHelpers.renderList(items, (item, _, _):VNode => { "createElementVNode(Fragment, null, RenderHelpers.renderList(items, (item, _, _):VNode => {
return createElementVNode("text", new Map<string, any | null>([ return createElementVNode("text", utsMapOf({
["key", item.id], key: item.id,
["id", item.id] id: item.id
]), null, 8 /* PROPS */, ["id"]) }), null, 8 /* PROPS */, ["id"])
}), 128 /* KEYED_FRAGMENT */)" }), 128 /* KEYED_FRAGMENT */)"
`; `;
...@@ -85,7 +85,7 @@ exports[`compiler: v-for codegen v-for with constant expression 1`] = ` ...@@ -85,7 +85,7 @@ exports[`compiler: v-for codegen v-for with constant expression 1`] = `
exports[`compiler: v-for codegen v-if + v-for 1`] = ` exports[`compiler: v-for codegen v-if + v-for 1`] = `
"isTrue(ok) "isTrue(ok)
? createElementVNode(Fragment, new Map<string, any | null>([["key", 0]]), RenderHelpers.renderList(list, (i, _, _):VNode => { ? createElementVNode(Fragment, utsMapOf({ key: 0 }), RenderHelpers.renderList(list, (i, _, _):VNode => {
return createElementVNode("view") return createElementVNode("view")
}), 256 /* UNKEYED_FRAGMENT */) }), 256 /* UNKEYED_FRAGMENT */)
: createCommentVNode("v-if", true)" : createCommentVNode("v-if", true)"
...@@ -93,7 +93,7 @@ exports[`compiler: v-for codegen v-if + v-for 1`] = ` ...@@ -93,7 +93,7 @@ exports[`compiler: v-for codegen v-if + v-for 1`] = `
exports[`compiler: v-for codegen v-if + v-for on <template> 1`] = ` exports[`compiler: v-for codegen v-if + v-for on <template> 1`] = `
"isTrue(ok) "isTrue(ok)
? createElementVNode(Fragment, new Map<string, any | null>([["key", 0]]), RenderHelpers.renderList(list, (i, _, _):VNode => { ? createElementVNode(Fragment, utsMapOf({ key: 0 }), RenderHelpers.renderList(list, (i, _, _):VNode => {
return createElementVNode(Fragment, null, [], 64 /* STABLE_FRAGMENT */) return createElementVNode(Fragment, null, [], 64 /* STABLE_FRAGMENT */)
}), 256 /* UNKEYED_FRAGMENT */) }), 256 /* UNKEYED_FRAGMENT */)
: createCommentVNode("v-if", true)" : createCommentVNode("v-if", true)"
......
...@@ -2,37 +2,37 @@ ...@@ -2,37 +2,37 @@
exports[`compiler: v-if codegen basic v-if 1`] = ` exports[`compiler: v-if codegen basic v-if 1`] = `
"isTrue(ok) "isTrue(ok)
? createElementVNode("view", new Map<string, any | null>([["key", 0]])) ? createElementVNode("view", utsMapOf({ key: 0 }))
: createCommentVNode("v-if", true)" : createCommentVNode("v-if", true)"
`; `;
exports[`compiler: v-if codegen increasing key: v-if + v-else-if + v-else 1`] = ` exports[`compiler: v-if codegen increasing key: v-if + v-else-if + v-else 1`] = `
"createElementVNode(Fragment, null, [ "createElementVNode(Fragment, null, [
isTrue(ok) isTrue(ok)
? createElementVNode("view", new Map<string, any | null>([["key", 0]])) ? createElementVNode("view", utsMapOf({ key: 0 }))
: createElementVNode("p", new Map<string, any | null>([["key", 1]])), : createElementVNode("p", utsMapOf({ key: 1 })),
isTrue(another) isTrue(another)
? createElementVNode("view", new Map<string, any | null>([["key", 2]])) ? createElementVNode("view", utsMapOf({ key: 2 }))
: isTrue(orNot) : isTrue(orNot)
? createElementVNode("p", new Map<string, any | null>([["key", 3]])) ? createElementVNode("p", utsMapOf({ key: 3 }))
: createElementVNode("p", new Map<string, any | null>([["key", 4]])) : createElementVNode("p", utsMapOf({ key: 4 }))
], 64 /* STABLE_FRAGMENT */)" ], 64 /* STABLE_FRAGMENT */)"
`; `;
exports[`compiler: v-if codegen multiple v-if that are sibling nodes should have different keys 1`] = ` exports[`compiler: v-if codegen multiple v-if that are sibling nodes should have different keys 1`] = `
"createElementVNode(Fragment, null, [ "createElementVNode(Fragment, null, [
isTrue(ok) isTrue(ok)
? createElementVNode("view", new Map<string, any | null>([["key", 0]])) ? createElementVNode("view", utsMapOf({ key: 0 }))
: createCommentVNode("v-if", true), : createCommentVNode("v-if", true),
isTrue(orNot) isTrue(orNot)
? createElementVNode("p", new Map<string, any | null>([["key", 1]])) ? createElementVNode("p", utsMapOf({ key: 1 }))
: createCommentVNode("v-if", true) : createCommentVNode("v-if", true)
], 64 /* STABLE_FRAGMENT */)" ], 64 /* STABLE_FRAGMENT */)"
`; `;
exports[`compiler: v-if codegen template v-if 1`] = ` exports[`compiler: v-if codegen template v-if 1`] = `
"isTrue(ok) "isTrue(ok)
? createElementVNode(Fragment, new Map<string, any | null>([["key", 0]]), [ ? createElementVNode(Fragment, utsMapOf({ key: 0 }), [
createElementVNode("view"), createElementVNode("view"),
"hello", "hello",
createElementVNode("p") createElementVNode("p")
...@@ -42,28 +42,28 @@ exports[`compiler: v-if codegen template v-if 1`] = ` ...@@ -42,28 +42,28 @@ exports[`compiler: v-if codegen template v-if 1`] = `
exports[`compiler: v-if codegen v-if + v-else 1`] = ` exports[`compiler: v-if codegen v-if + v-else 1`] = `
"isTrue(ok) "isTrue(ok)
? createElementVNode("view", new Map<string, any | null>([["key", 0]])) ? createElementVNode("view", utsMapOf({ key: 0 }))
: createElementVNode("p", new Map<string, any | null>([["key", 1]]))" : createElementVNode("p", utsMapOf({ key: 1 }))"
`; `;
exports[`compiler: v-if codegen v-if + v-else-if + v-else 1`] = ` exports[`compiler: v-if codegen v-if + v-else-if + v-else 1`] = `
"isTrue(ok) "isTrue(ok)
? createElementVNode("view", new Map<string, any | null>([["key", 0]])) ? createElementVNode("view", utsMapOf({ key: 0 }))
: isTrue(orNot) : isTrue(orNot)
? createElementVNode("p", new Map<string, any | null>([["key", 1]])) ? createElementVNode("p", utsMapOf({ key: 1 }))
: createElementVNode(Fragment, new Map<string, any | null>([["key", 2]]), ["fine"], 64 /* STABLE_FRAGMENT */)" : createElementVNode(Fragment, utsMapOf({ key: 2 }), ["fine"], 64 /* STABLE_FRAGMENT */)"
`; `;
exports[`compiler: v-if codegen v-if + v-else-if 1`] = ` exports[`compiler: v-if codegen v-if + v-else-if 1`] = `
"isTrue(ok) "isTrue(ok)
? createElementVNode("view", new Map<string, any | null>([["key", 0]])) ? createElementVNode("view", utsMapOf({ key: 0 }))
: isTrue(orNot) : isTrue(orNot)
? createElementVNode("p", new Map<string, any | null>([["key", 1]])) ? createElementVNode("p", utsMapOf({ key: 1 }))
: createCommentVNode("v-if", true)" : createCommentVNode("v-if", true)"
`; `;
exports[`compiler: v-if codegen v-if on <slot/> 1`] = ` exports[`compiler: v-if codegen v-if on <slot/> 1`] = `
"isTrue(ok) "isTrue(ok)
? renderSlot($slots, "default", new Map<string, any | null>([["key", 0]])) ? renderSlot($slots, "default", utsMapOf({ key: 0 }))
: createCommentVNode("v-if", true)" : createCommentVNode("v-if", true)"
`; `;
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform v-model compound expression (with prefixIdentifiers) 1`] = ` exports[`compiler: transform v-model compound expression (with prefixIdentifiers) 1`] = `
"createElementVNode("input", new Map<string, any | null>([ "createElementVNode("input", utsMapOf({
["modelValue", _ctx.model[_ctx.index]], modelValue: _ctx.model[_ctx.index],
["onInput", ($event: InputEvent): any => {_ctx.model[_ctx.index] = $event.detail.value; onInput: ($event: InputEvent): any => {_ctx.model[_ctx.index] = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])" }), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])"
`; `;
exports[`compiler: transform v-model compound expression 1`] = ` exports[`compiler: transform v-model compound expression 1`] = `
"createElementVNode("input", new Map<string, any | null>([ "createElementVNode("input", utsMapOf({
["modelValue", model[index]], modelValue: model[index],
["onInput", ($event: InputEvent): any => {model[index] = $event.detail.value; onInput: ($event: InputEvent): any => {model[index] = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])" }), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])"
`; `;
exports[`compiler: transform v-model simple expression (with multilines) 1`] = ` exports[`compiler: transform v-model simple expression (with multilines) 1`] = `
"createElementVNode("input", new Map<string, any | null>([ "createElementVNode("input", utsMapOf({
["modelValue", modelValue:
model model
. .
foo foo
], ,
["onInput", ($event: InputEvent): any => { onInput: ($event: InputEvent): any => {
model model
. .
foo foo
= $event.detail.value; = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])" }), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])"
`; `;
exports[`compiler: transform v-model simple expression (with prefixIdentifiers) 1`] = ` exports[`compiler: transform v-model simple expression (with prefixIdentifiers) 1`] = `
"createElementVNode("input", new Map<string, any | null>([ "createElementVNode("input", utsMapOf({
["modelValue", _ctx.model], modelValue: _ctx.model,
["onInput", ($event: InputEvent): any => {_ctx.model = $event.detail.value; onInput: ($event: InputEvent): any => {_ctx.model = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])" }), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])"
`; `;
exports[`compiler: transform v-model simple expression 1`] = ` exports[`compiler: transform v-model simple expression 1`] = `
"createElementVNode("input", new Map<string, any | null>([ "createElementVNode("input", utsMapOf({
["modelValue", model], modelValue: model,
["onInput", ($event: InputEvent): any => {model = $event.detail.value; onInput: ($event: InputEvent): any => {model = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])" }), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])"
`; `;
exports[`compiler: transform v-model with argument 1`] = ` exports[`compiler: transform v-model with argument 1`] = `
"createElementVNode("input", new Map<string, any | null>([ "createElementVNode("input", utsMapOf({
["foo-value", model], "foo-value": model,
["onUpdate:fooValue", $event => {(model) = $event}] "onUpdate:fooValue": $event => {(model) = $event}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, ["foo-value", "onUpdate:fooValue"])" }), null, 40 /* PROPS, HYDRATE_EVENTS */, ["foo-value", "onUpdate:fooValue"])"
`; `;
exports[`compiler: transform v-model with dynamic argument (with prefixIdentifiers) 1`] = ` exports[`compiler: transform v-model with dynamic argument (with prefixIdentifiers) 1`] = `
"createElementVNode("input", normalizeProps(new Map<string, any | null>([ "createElementVNode("input", normalizeProps(utsMapOf({
[_ctx.value, _ctx.model], [_ctx.value]: _ctx.model,
["onUpdate:" + _ctx.value, $event => {(_ctx.model) = $event}] ["onUpdate:" + _ctx.value]: $event => {(_ctx.model) = $event}
])), null, 16 /* FULL_PROPS */)" })), null, 16 /* FULL_PROPS */)"
`; `;
exports[`compiler: transform v-model with dynamic argument 1`] = ` exports[`compiler: transform v-model with dynamic argument 1`] = `
"createVNode(_component_Foo, normalizeProps(new Map<string, any | null>([ "createVNode(_component_Foo, normalizeProps(utsMapOf({
[value, model], [value]: model,
["onUpdate:" + value, $event => {(model) = $event}] ["onUpdate:" + value]: $event => {(model) = $event}
])), null, 16 /* FULL_PROPS */)" })), null, 16 /* FULL_PROPS */)"
`; `;
...@@ -4,24 +4,24 @@ describe('compiler: transform tap to click', () => { ...@@ -4,24 +4,24 @@ describe('compiler: transform tap to click', () => {
test('transform tap to click', () => { test('transform tap to click', () => {
assert( assert(
`<text @click="click">hello</text>`, `<text @click="click">hello</text>`,
`createElementVNode("text", new Map<string, any | null>([["onClick", _ctx.click]]), "hello", 8 /* PROPS */, ["onClick"])` `createElementVNode("text", utsMapOf({ onClick: _ctx.click }), "hello", 8 /* PROPS */, ["onClick"])`
) )
assert( assert(
`<text @tap="click">hello</text>`, `<text @tap="click">hello</text>`,
`createElementVNode("text", new Map<string, any | null>([["onClick", _ctx.click]]), "hello", 8 /* PROPS */, ["onClick"])` `createElementVNode("text", utsMapOf({ onClick: _ctx.click }), "hello", 8 /* PROPS */, ["onClick"])`
) )
assert( assert(
`<view @tap="click">hello</view>`, `<view @tap="click">hello</view>`,
`createElementVNode("view", new Map<string, any | null>([["onClick", _ctx.click]]), [ `createElementVNode("view", utsMapOf({ onClick: _ctx.click }), [
createElementVNode("text", null, "hello") createElementVNode("text", null, "hello")
], 8 /* PROPS */, ["onClick"])` ], 8 /* PROPS */, ["onClick"])`
) )
assert( assert(
`<button @tap="click">hello</button>`, `<button @tap="click">hello</button>`,
`createVNode(_component_button, new Map<string, any | null>([["onClick", _ctx.click]]), new Map<string, any | null>([ `createVNode(_component_button, utsMapOf({ onClick: _ctx.click }), utsMapOf({
["default", ((): any[] => ["hello"])], default: ((): any[] => ["hello"]),
["_", 1 /* STABLE */] _: 1 /* STABLE */
]), 8 /* PROPS */, ["onClick"])` }), 8 /* PROPS */, ["onClick"])`
) )
}) })
}) })
...@@ -46,77 +46,79 @@ describe('compiler: v-bind', () => { ...@@ -46,77 +46,79 @@ describe('compiler: v-bind', () => {
test('basic', () => { test('basic', () => {
assert( assert(
`<view v-bind:id="id"/>`, `<view v-bind:id="id"/>`,
`createElementVNode("view", new Map<string, any | null>([["id", _ctx.id]]), null, 8 /* PROPS */, ["id"])` `createElementVNode("view", utsMapOf({ id: _ctx.id }), null, 8 /* PROPS */, ["id"])`
) )
}) })
test('dynamic arg', () => { test('dynamic arg', () => {
assert( assert(
`<view v-bind:[id]="id"/>`, `<view v-bind:[id]="id"/>`,
`createElementVNode("view", normalizeProps(new Map<string, any | null>([[_ctx.id !== null ? _ctx.id : \"\", _ctx.id]])), null, 16 /* FULL_PROPS */)` `createElementVNode("view", normalizeProps(utsMapOf({ [_ctx.id !== null ? _ctx.id : ""]: _ctx.id })), null, 16 /* FULL_PROPS */)`
) )
}) })
test('.camel modifier', () => { test('.camel modifier', () => {
assert( assert(
`<view v-bind:foo-bar.camel="id"/>`, `<view v-bind:foo-bar.camel="id"/>`,
`createElementVNode(\"view\", new Map<string, any | null>([[\"fooBar\", _ctx.id]]), null, 8 /* PROPS */, [\"fooBar\"])` `createElementVNode("view", utsMapOf({ fooBar: _ctx.id }), null, 8 /* PROPS */, ["fooBar"])`
) )
}) })
test('.camel modifier w/ dynamic arg', () => { test('.camel modifier w/ dynamic arg', () => {
assert( assert(
`<view v-bind:[foo].camel="id"/>`, `<view v-bind:[foo].camel="id"/>`,
`createElementVNode(\"view\", normalizeProps(new Map<string, any | null>([[camelize(_ctx.foo !== null ? _ctx.foo : \"\"), _ctx.id]])), null, 16 /* FULL_PROPS */)` `createElementVNode("view", normalizeProps(utsMapOf({ [camelize(_ctx.foo !== null ? _ctx.foo : "")]: _ctx.id })), null, 16 /* FULL_PROPS */)`
) )
}) })
test('.prop modifier', () => { test('.prop modifier', () => {
assert( assert(
`<view v-bind:className.prop="className"/>`, `<view v-bind:className.prop="className"/>`,
`createElementVNode(\"view\", new Map<string, any | null>([[\".className\", _ctx.className]]), null, 8 /* PROPS */, [\".className\"])` `createElementVNode("view", utsMapOf({ ".className": _ctx.className }), null, 8 /* PROPS */, [".className"])`
) )
}) })
test('.prop modifier w/ dynamic arg', () => { test('.prop modifier w/ dynamic arg', () => {
assert( assert(
`<view v-bind:[fooBar].prop="className"/>`, `<view v-bind:[fooBar].prop="className"/>`,
'createElementVNode("view", normalizeProps(new Map<string, any | null>([[`.${_ctx.fooBar !== null ? _ctx.fooBar : ""}`, _ctx.className]])), null, 16 /* FULL_PROPS */)' 'createElementVNode("view", normalizeProps(utsMapOf({ [`.${_ctx.fooBar !== null ? _ctx.fooBar : ""}`]: _ctx.className })), null, 16 /* FULL_PROPS */)'
) )
}) })
test('.prop modifier (shorthand)', () => { test('.prop modifier (shorthand)', () => {
assert( assert(
`<view .className="className"/>`, `<view .className="className"/>`,
'createElementVNode("view", new Map<string, any | null>([[".className", _ctx.className]]), null, 8 /* PROPS */, [".className"])' 'createElementVNode("view", utsMapOf({ ".className": _ctx.className }), null, 8 /* PROPS */, [".className"])'
) )
}) })
test('.attr modifier', () => { test('.attr modifier', () => {
assert( assert(
`<view v-bind:foo-bar.attr="id"/>`, `<view v-bind:foo-bar.attr="id"/>`,
'createElementVNode("view", new Map<string, any | null>([["^foo-bar", _ctx.id]]), null, 8 /* PROPS */, ["^foo-bar"])' 'createElementVNode("view", utsMapOf({ "^foo-bar": _ctx.id }), null, 8 /* PROPS */, ["^foo-bar"])'
) )
}) })
test('simple expression', () => { test('simple expression', () => {
assert( assert(
`<view v-bind:class="{'box': true}"></view>`, `<view v-bind:class="{'box': true}"></view>`,
`createElementVNode("view", new Map<string, any | null>([ `createElementVNode("view", utsMapOf({
["class", normalizeClass(new Map<string, any | null>([['box', true]]))] class: normalizeClass(utsMapOf({'box': true}))
]))` }), null, 2 /* CLASS */)`
) )
}) })
test('simple expression with array', () => { test('simple expression with array', () => {
assert( assert(
`<view v-bind:class="[classA, {classB: true, classC: false}]"></view>`, `<view v-bind:class="[classA, {classB: true, classC: false}]"></view>`,
`createElementVNode("view", new Map<string, any | null>([ `createElementVNode("view", utsMapOf({
["class", normalizeClass([_ctx.classA, new Map<string, any | null>([[classB, true], [classC, false]])])] class: normalizeClass([_ctx.classA, utsMapOf({classB: true, classC: false})])
]), null, 2 /* CLASS */)` }), null, 2 /* CLASS */)`
) )
}) })
test('simple expression with object', () => { test('simple expression with object', () => {
assert( assert(
`<view :style="{color: true ? 'blue' : 'red'}"></view>`, `<view :style="{color: true ? 'blue' : 'red'}"></view>`,
"createElementVNode(\"view\", new Map<string, any | null>([[\"style\", new Map<string, any | null>([['color', true ? 'blue' : 'red']])]]))" `createElementVNode("view", utsMapOf({
style: normalizeStyle(utsMapOf({color: true ? 'blue' : 'red'}))
}), null, 4 /* STYLE */)`
) )
}) })
test('complex expression', () => { test('complex expression', () => {
assert( assert(
`<rich-text :nodes="[{'name':'div','attrs':{'class':'div-class','style':'line-height: 60px; color: red; text-align:center;'},'children':[{'type':'text','text':'this is text'}]}]" />`, `<rich-text :nodes="[{'name':'div','attrs':{'class':'div-class','style':'line-height: 60px; color: red; text-align:center;'},'children':[{'type':'text','text':'this is text'}]}]" />`,
`createElementVNode(\"rich-text\", new Map<string, any | null>([[\"nodes\", [new Map<string, any | null>([['name', 'div'], ['attrs', new Map<string, any | null>([['class', 'div-class'], ['style', 'line-height: 60px; color: red; text-align:center;']])], ['children', [new Map<string, any | null>([['type', 'text'], ['text', 'this is text']])]]])]]]))` `createElementVNode("rich-text", utsMapOf({ nodes: [utsMapOf({'name':'div','attrs':utsMapOf({'class':'div-class','style':'line-height: 60px; color: red; text-align:center;'}),'children':[utsMapOf({'type':'text','text':'this is text'})]})] }), null, 8 /* PROPS */, ["nodes"])`
) )
}) })
test('empty object syntax with \n', () => { test('empty object syntax with \n', () => {
...@@ -136,43 +138,59 @@ describe('compiler: v-bind', () => { ...@@ -136,43 +138,59 @@ describe('compiler: v-bind', () => {
} }
]" ]"
/>`, />`,
"createElementVNode(\"rich-text\", new Map<string, any | null>([[\"nodes\", [ new Map<string, any | null>([['name', 'div'], ['attrs', new Map<string, any | null>([['class', 'div-class'], ['style', 'line-height: 60px; color: red; text-align:center;']])], ['children', [new Map<string, any | null>([['type', 'text'], ['text', 'this is text']]), new Map<string, any | null>([['type', 'text'], ['text', 'this is text']])]]]) ]]]))" `createElementVNode("rich-text", utsMapOf({ nodes: [
utsMapOf({
'name': 'div',
'attrs': utsMapOf({
'class': 'div-class',
'style': 'line-height: 60px; color: red; text-align:center;'
}),
'children': [
utsMapOf({ 'type': 'text', 'text': 'this is text' }),
utsMapOf({ 'type': 'text', 'text': 'this is text' }),
]
})
] }), null, 8 /* PROPS */, ["nodes"])`
) )
}) })
test('style with empty {\n }', () => { test('style with empty {\n }', () => {
assert( assert(
`<text :style="{ `<text :style="{
}" />`, }" />`,
`createElementVNode(\"text\", new Map<string, any | null>([[\"style\", new Map<string, any | null>()]]))` `createElementVNode("text", utsMapOf({
style: normalizeStyle(utsMapOf({
}))
}), null, 4 /* STYLE */)`
) )
}) })
test('object value width expression', () => { test('object value width expression', () => {
assert( assert(
`<view class="search" @click="toSearchPage" :style="{'width':700 +'rpx', `<view class="search" @click="toSearchPage" :style="{'width':700 +'rpx',
'top':0 +'px'}" />`, 'top':0 +'px'}" />`,
`createElementVNode(\"view\", new Map<string, any | null>([ `createElementVNode("view", utsMapOf({
[\"class\", \"search\"], class: "search",
[\"onClick\", _ctx.toSearchPage], onClick: _ctx.toSearchPage,
[\"style\", new Map<string, any | null>([['width', 700 +'rpx'], ['top', 0 +'px']])] style: normalizeStyle(utsMapOf({'width':700 +'rpx',
]), null, 8 /* PROPS */, [\"onClick\"])` 'top':0 +'px'}))
}), null, 12 /* STYLE, PROPS */, ["onClick"])`
) )
}) })
test('object value width all number expression', () => { test('object value width all number expression', () => {
assert( assert(
`<view class="search" @click="toSearchPage" :style="{'opacity': 1 + 1}" />`, `<view class="search" @click="toSearchPage" :style="{'opacity': 1 + 1}" />`,
`createElementVNode(\"view\", new Map<string, any | null>([ `createElementVNode("view", utsMapOf({
[\"class\", \"search\"], class: "search",
[\"onClick\", _ctx.toSearchPage], onClick: _ctx.toSearchPage,
[\"style\", new Map<string, any | null>([['opacity', 1 + 1]])] style: normalizeStyle(utsMapOf({'opacity': 1 + 1}))
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 12 /* STYLE, PROPS */, ["onClick"])`
) )
}) })
test('object value width expression (with data)', () => { test('object value width expression (with data)', () => {
assert( assert(
`<view :style="{'opacity': count > 0.3 ? 1 : count * 3, 'color': 'red'}" />`, `<view :style="{'opacity': count > 0.3 ? 1 : count * 3, 'color': 'red'}" />`,
`createElementVNode(\"view\", new Map<string, any | null>([ `createElementVNode("view", utsMapOf({
[\"style\", new Map<string, any | null>([['opacity', _ctx.count > 0.3 ? 1 : _ctx.count * 3], ['color', 'red']])] style: normalizeStyle(utsMapOf({'opacity': _ctx.count > 0.3 ? 1 : _ctx.count * 3, 'color': 'red'}))
]))` }), null, 4 /* STYLE */)`
) )
}) })
......
...@@ -61,7 +61,7 @@ describe('compiler: v-for', () => { ...@@ -61,7 +61,7 @@ describe('compiler: v-for', () => {
assert( assert(
`<text v-for="item in 10" :key="item" />`, `<text v-for="item in 10" :key="item" />`,
`createElementVNode(Fragment, null, RenderHelpers.renderList(10, (item, _, _):VNode => { `createElementVNode(Fragment, null, RenderHelpers.renderList(10, (item, _, _):VNode => {
return createElementVNode("text", new Map<string, any | null>([["key", item]])) return createElementVNode("text", utsMapOf({ key: item }))
}), 64 /* STABLE_FRAGMENT */)` }), 64 /* STABLE_FRAGMENT */)`
) )
}) })
...@@ -77,7 +77,7 @@ describe('compiler: v-for', () => { ...@@ -77,7 +77,7 @@ describe('compiler: v-for', () => {
assert( assert(
`<text v-for="(item, index) in [1,2,3]" :key="index" />`, `<text v-for="(item, index) in [1,2,3]" :key="index" />`,
`createElementVNode(Fragment, null, RenderHelpers.renderList([1,2,3], (item, index, _):VNode => { `createElementVNode(Fragment, null, RenderHelpers.renderList([1,2,3], (item, index, _):VNode => {
return createElementVNode("text", new Map<string, any | null>([["key", index]])) return createElementVNode("text", utsMapOf({ key: index }))
}), 64 /* STABLE_FRAGMENT */)` }), 64 /* STABLE_FRAGMENT */)`
) )
}) })
...@@ -85,7 +85,7 @@ describe('compiler: v-for', () => { ...@@ -85,7 +85,7 @@ describe('compiler: v-for', () => {
assert( assert(
`<text v-for="(item, key, index) in {a:'a',b:'b'}" :key="index" />`, `<text v-for="(item, key, index) in {a:'a',b:'b'}" :key="index" />`,
`createElementVNode(Fragment, null, RenderHelpers.renderList({a:'a',b:'b'}, (item, key, index):VNode => { `createElementVNode(Fragment, null, RenderHelpers.renderList({a:'a',b:'b'}, (item, key, index):VNode => {
return createElementVNode("text", new Map<string, any | null>([["key", index]])) return createElementVNode("text", utsMapOf({ key: index }))
}), 64 /* STABLE_FRAGMENT */)` }), 64 /* STABLE_FRAGMENT */)`
) )
}) })
...@@ -241,9 +241,9 @@ describe('compiler: v-for', () => { ...@@ -241,9 +241,9 @@ describe('compiler: v-for', () => {
assert( assert(
`<text v-for="item in items" :key="itemKey(item)">test</text>`, `<text v-for="item in items" :key="itemKey(item)">test</text>`,
`createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => { `createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => {
return createElementVNode(\"text\", new Map<string, any | null>([ return createElementVNode(\"text\", utsMapOf({
[\"key\", _ctx.itemKey(item)] key: _ctx.itemKey(item)
]), \"test\") }), \"test\")
}), 128 /* KEYED_FRAGMENT */)` }), 128 /* KEYED_FRAGMENT */)`
) )
}) })
...@@ -251,7 +251,7 @@ describe('compiler: v-for', () => { ...@@ -251,7 +251,7 @@ describe('compiler: v-for', () => {
assert( assert(
`<template v-for="item in items" key="key">test</template>`, `<template v-for="item in items" key="key">test</template>`,
`createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => { `createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => {
return createElementVNode(Fragment, new Map<string, any | null>([[\"key\", \"key\"]]), [\"test\"], 64 /* STABLE_FRAGMENT */) return createElementVNode(Fragment, utsMapOf({ key: "key" }), [\"test\"], 64 /* STABLE_FRAGMENT */)
}), 128 /* KEYED_FRAGMENT */)` }), 128 /* KEYED_FRAGMENT */)`
) )
}) })
...@@ -259,10 +259,10 @@ describe('compiler: v-for', () => { ...@@ -259,10 +259,10 @@ describe('compiler: v-for', () => {
assert( assert(
`<template v-for="item in items" :key="item.id"><text :id="item.id" /></template>`, `<template v-for="item in items" :key="item.id"><text :id="item.id" /></template>`,
`createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => { `createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => {
return createElementVNode(\"text\", new Map<string, any | null>([ return createElementVNode(\"text\", utsMapOf({
[\"key\", item.id], key: item.id,
[\"id\", item.id] id: item.id
]), null, 8 /* PROPS */, [\"id\"]) }), null, 8 /* PROPS */, [\"id\"])
}), 128 /* KEYED_FRAGMENT */)` }), 128 /* KEYED_FRAGMENT */)`
) )
}) })
...@@ -278,7 +278,7 @@ describe('compiler: v-for', () => { ...@@ -278,7 +278,7 @@ describe('compiler: v-for', () => {
assert( assert(
`<text v-for="(item) in items" :key="item" />`, `<text v-for="(item) in items" :key="item" />`,
`createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => { `createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => {
return createElementVNode(\"text\", new Map<string, any | null>([[\"key\", item]])) return createElementVNode(\"text\", utsMapOf({ key: item }))
}), 128 /* KEYED_FRAGMENT */)` }), 128 /* KEYED_FRAGMENT */)`
) )
}) })
...@@ -286,7 +286,7 @@ describe('compiler: v-for', () => { ...@@ -286,7 +286,7 @@ describe('compiler: v-for', () => {
assert( assert(
`<template v-for="(item) in items" :key="item"><text/></template>`, `<template v-for="(item) in items" :key="item"><text/></template>`,
`createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => { `createElementVNode(Fragment, null, RenderHelpers.renderList(_ctx.items, (item, _, _):VNode => {
return createElementVNode(\"text\", new Map<string, any | null>([[\"key\", item]])) return createElementVNode(\"text\", utsMapOf({ key: item }))
}), 128 /* KEYED_FRAGMENT */)` }), 128 /* KEYED_FRAGMENT */)`
) )
}) })
...@@ -294,7 +294,7 @@ describe('compiler: v-for', () => { ...@@ -294,7 +294,7 @@ describe('compiler: v-for', () => {
assert( assert(
`<view v-if="ok" v-for="i in list"/>`, `<view v-if="ok" v-for="i in list"/>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createElementVNode(Fragment, new Map<string, any | null>([[\"key\", 0]]), RenderHelpers.renderList(_ctx.list, (i, _, _):VNode => { ? createElementVNode(Fragment, utsMapOf({ key: 0 }), RenderHelpers.renderList(_ctx.list, (i, _, _):VNode => {
return createElementVNode(\"view\") return createElementVNode(\"view\")
}), 256 /* UNKEYED_FRAGMENT */) }), 256 /* UNKEYED_FRAGMENT */)
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
...@@ -304,7 +304,7 @@ describe('compiler: v-for', () => { ...@@ -304,7 +304,7 @@ describe('compiler: v-for', () => {
assert( assert(
`<template v-if="ok" v-for="i in list"/>`, `<template v-if="ok" v-for="i in list"/>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createElementVNode(Fragment, new Map<string, any | null>([[\"key\", 0]]), RenderHelpers.renderList(_ctx.list, (i, _, _):VNode => { ? createElementVNode(Fragment, utsMapOf({ key: 0 }), RenderHelpers.renderList(_ctx.list, (i, _, _):VNode => {
return createElementVNode(Fragment, null, [], 64 /* STABLE_FRAGMENT */) return createElementVNode(Fragment, null, [], 64 /* STABLE_FRAGMENT */)
}), 256 /* UNKEYED_FRAGMENT */) }), 256 /* UNKEYED_FRAGMENT */)
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
......
...@@ -65,14 +65,14 @@ describe('compiler: v-if', () => { ...@@ -65,14 +65,14 @@ describe('compiler: v-if', () => {
test('basic v-if', () => { test('basic v-if', () => {
assert( assert(
`<view v-if="ok"/>`, `<view v-if="ok"/>`,
`isTrue(_ctx.ok)\n ? createElementVNode("view", new Map<string, any | null>([["key", 0]]))\n : createCommentVNode("v-if", true)` `isTrue(_ctx.ok)\n ? createElementVNode("view", utsMapOf({ key: 0 }))\n : createCommentVNode("v-if", true)`
) )
}) })
test('template v-if', () => { test('template v-if', () => {
assert( assert(
`<template v-if="ok"><view/>hello<text/></template>`, `<template v-if="ok"><view/>hello<text/></template>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createElementVNode(Fragment, new Map<string, any | null>([[\"key\", 0]]), [ ? createElementVNode(Fragment, utsMapOf({ key: 0 }), [
createElementVNode(\"view\"), createElementVNode(\"view\"),
\"hello\", \"hello\",
createElementVNode(\"text\") createElementVNode(\"text\")
...@@ -84,7 +84,7 @@ describe('compiler: v-if', () => { ...@@ -84,7 +84,7 @@ describe('compiler: v-if', () => {
assert( assert(
`<Component v-if="ok"></Component>`, `<Component v-if="ok"></Component>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createVNode(_component_Component, new Map<string, any | null>([[\"key\", 0]])) ? createVNode(_component_Component, utsMapOf({ key: 0 }))
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
) )
}) })
...@@ -98,8 +98,8 @@ describe('compiler: v-if', () => { ...@@ -98,8 +98,8 @@ describe('compiler: v-if', () => {
`, `,
`createElementVNode("view", null, [ `createElementVNode("view", null, [
isTrue(_ctx.ok) isTrue(_ctx.ok)
? createElementVNode("text", new Map<string, any | null>([["key", 0]])) ? createElementVNode("text", utsMapOf({ key: 0 }))
: createElementVNode("text", new Map<string, any | null>([["key", 1]])) : createElementVNode("text", utsMapOf({ key: 1 }))
])` ])`
) )
}) })
...@@ -114,10 +114,10 @@ describe('compiler: v-if', () => { ...@@ -114,10 +114,10 @@ describe('compiler: v-if', () => {
`, `,
`createElementVNode("view", null, [ `createElementVNode("view", null, [
isTrue(_ctx.ok) isTrue(_ctx.ok)
? createElementVNode("text", new Map<string, any | null>([["key", 0]])) ? createElementVNode("text", utsMapOf({ key: 0 }))
: isTrue(_ctx.orNot) : isTrue(_ctx.orNot)
? createElementVNode("text", new Map<string, any | null>([["key", 1]])) ? createElementVNode("text", utsMapOf({ key: 1 }))
: createElementVNode("text", new Map<string, any | null>([["key", 2]])) : createElementVNode("text", utsMapOf({ key: 2 }))
])` ])`
) )
}) })
...@@ -132,10 +132,10 @@ describe('compiler: v-if', () => { ...@@ -132,10 +132,10 @@ describe('compiler: v-if', () => {
`, `,
`createElementVNode("view", null, [ `createElementVNode("view", null, [
isTrue(_ctx.ok) isTrue(_ctx.ok)
? createElementVNode("text", new Map<string, any | null>([["key", 0]])) ? createElementVNode("text", utsMapOf({ key: 0 }))
: isTrue(_ctx.orNot) : isTrue(_ctx.orNot)
? createElementVNode("text", new Map<string, any | null>([["key", 1]]), "v-else-if") ? createElementVNode("text", utsMapOf({ key: 1 }), "v-else-if")
: createElementVNode("text", new Map<string, any | null>([["key", 2]]), "v-else") : createElementVNode("text", utsMapOf({ key: 2 }), "v-else")
])` ])`
) )
}) })
...@@ -149,17 +149,17 @@ describe('compiler: v-if', () => { ...@@ -149,17 +149,17 @@ describe('compiler: v-if', () => {
<text v-else>v-else</text> <text v-else>v-else</text>
`, `,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createElementVNode(\"view\", new Map<string, any | null>([[\"key\", 0]])) ? createElementVNode(\"view\", utsMapOf({ key: 0 }))
: isTrue(_ctx.orNot) : isTrue(_ctx.orNot)
? createElementVNode(\"view\", new Map<string, any | null>([[\"key\", 1]])) ? createElementVNode(\"view\", utsMapOf({ key: 1 }))
: createElementVNode(\"text\", new Map<string, any | null>([[\"key\", 2]]), \"v-else\")` : createElementVNode(\"text\", utsMapOf({ key: 2 }), \"v-else\")`
) )
}) })
test('template v-if w/ single <slot/> child', () => { test('template v-if w/ single <slot/> child', () => {
assert( assert(
`<template v-if="ok"><slot/></template>`, `<template v-if="ok"><slot/></template>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? renderSlot(_ctx.$slots, \"default\", new Map<string, any | null>([[\"key\", 0]])) ? renderSlot(_ctx.$slots, \"default\", utsMapOf({ key: 0 }))
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
) )
}) })
...@@ -167,7 +167,7 @@ describe('compiler: v-if', () => { ...@@ -167,7 +167,7 @@ describe('compiler: v-if', () => {
assert( assert(
`<slot v-if="ok"></slot>`, `<slot v-if="ok"></slot>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? renderSlot(_ctx.$slots, \"default\", new Map<string, any | null>([[\"key\", 0]])) ? renderSlot(_ctx.$slots, \"default\", utsMapOf({ key: 0 }))
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
) )
}) })
...@@ -176,10 +176,10 @@ describe('compiler: v-if', () => { ...@@ -176,10 +176,10 @@ describe('compiler: v-if', () => {
`<view><view v-if="ok"/><view v-if="orNot"/></view>`, `<view><view v-if="ok"/><view v-if="orNot"/></view>`,
`createElementVNode("view", null, [ `createElementVNode("view", null, [
isTrue(_ctx.ok) isTrue(_ctx.ok)
? createElementVNode("view", new Map<string, any | null>([["key", 0]])) ? createElementVNode("view", utsMapOf({ key: 0 }))
: createCommentVNode("v-if", true), : createCommentVNode("v-if", true),
isTrue(_ctx.orNot) isTrue(_ctx.orNot)
? createElementVNode("view", new Map<string, any | null>([["key", 1]])) ? createElementVNode("view", utsMapOf({ key: 1 }))
: createCommentVNode("v-if", true) : createCommentVNode("v-if", true)
])` ])`
) )
...@@ -189,13 +189,13 @@ describe('compiler: v-if', () => { ...@@ -189,13 +189,13 @@ describe('compiler: v-if', () => {
`<view><view v-if="ok"/><view v-else/><view v-if="another"/><view v-else-if="orNot"/><view v-else/></view>`, `<view><view v-if="ok"/><view v-else/><view v-if="another"/><view v-else-if="orNot"/><view v-else/></view>`,
`createElementVNode("view", null, [ `createElementVNode("view", null, [
isTrue(_ctx.ok) isTrue(_ctx.ok)
? createElementVNode("view", new Map<string, any | null>([["key", 0]])) ? createElementVNode("view", utsMapOf({ key: 0 }))
: createElementVNode("view", new Map<string, any | null>([["key", 1]])), : createElementVNode("view", utsMapOf({ key: 1 })),
isTrue(_ctx.another) isTrue(_ctx.another)
? createElementVNode("view", new Map<string, any | null>([["key", 2]])) ? createElementVNode("view", utsMapOf({ key: 2 }))
: isTrue(_ctx.orNot) : isTrue(_ctx.orNot)
? createElementVNode("view", new Map<string, any | null>([["key", 3]])) ? createElementVNode("view", utsMapOf({ key: 3 }))
: createElementVNode("view", new Map<string, any | null>([["key", 4]])) : createElementVNode("view", utsMapOf({ key: 4 }))
])` ])`
) )
}) })
...@@ -203,7 +203,7 @@ describe('compiler: v-if', () => { ...@@ -203,7 +203,7 @@ describe('compiler: v-if', () => {
assert( assert(
`<view v-if="ok" v-bind="obj"/>`, `<view v-if="ok" v-bind="obj"/>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createElementVNode(\"view\", normalizeProps(mergeProps(new Map<string, any | null>([[\"key\", 0]]), _ctx.obj)), null, 16 /* FULL_PROPS */) ? createElementVNode(\"view\", normalizeProps(mergeProps(utsMapOf({ key: 0 }), _ctx.obj)), null, 16 /* FULL_PROPS */)
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
) )
}) })
...@@ -211,10 +211,10 @@ describe('compiler: v-if', () => { ...@@ -211,10 +211,10 @@ describe('compiler: v-if', () => {
assert( assert(
`<view v-if="ok" id="foo" v-bind="obj"/>`, `<view v-if="ok" id="foo" v-bind="obj"/>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createElementVNode(\"view\", mergeProps(new Map<string, any | null>([ ? createElementVNode(\"view\", mergeProps(utsMapOf({
[\"key\", 0], key: 0,
[\"id\", \"foo\"] id: "foo"
]), _ctx.obj), null, 16 /* FULL_PROPS */) }), _ctx.obj), null, 16 /* FULL_PROPS */)
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
) )
}) })
...@@ -222,7 +222,7 @@ describe('compiler: v-if', () => { ...@@ -222,7 +222,7 @@ describe('compiler: v-if', () => {
assert( assert(
`<view v-if="ok" v-bind="obj" id="foo"/>`, `<view v-if="ok" v-bind="obj" id="foo"/>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createElementVNode(\"view\", mergeProps(new Map<string, any | null>([[\"key\", 0]]), _ctx.obj, new Map<string, any | null>([[\"id\", \"foo\"]])), null, 16 /* FULL_PROPS */) ? createElementVNode(\"view\", mergeProps(utsMapOf({ key: 0 }), _ctx.obj, utsMapOf({ id: "foo" })), null, 16 /* FULL_PROPS */)
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
) )
}) })
...@@ -230,7 +230,7 @@ describe('compiler: v-if', () => { ...@@ -230,7 +230,7 @@ describe('compiler: v-if', () => {
assert( assert(
`<view v-if="ok" key="custom_key" v-bind="obj"/>`, `<view v-if="ok" key="custom_key" v-bind="obj"/>`,
`isTrue(_ctx.ok) `isTrue(_ctx.ok)
? createElementVNode(\"view\", mergeProps(new Map<string, any | null>([[\"key\", \"custom_key\"]]), _ctx.obj), null, 16 /* FULL_PROPS */) ? createElementVNode(\"view\", mergeProps(utsMapOf({ key: "custom_key" }), _ctx.obj), null, 16 /* FULL_PROPS */)
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
) )
}) })
...@@ -239,10 +239,10 @@ describe('compiler: v-if', () => { ...@@ -239,10 +239,10 @@ describe('compiler: v-if', () => {
`<view><text v-if="ok">1</text> <text v-else-if="orNot">2</text> <text v-else>3</text></view>`, `<view><text v-if="ok">1</text> <text v-else-if="orNot">2</text> <text v-else>3</text></view>`,
`createElementVNode("view", null, [ `createElementVNode("view", null, [
isTrue(_ctx.ok) isTrue(_ctx.ok)
? createElementVNode("text", new Map<string, any | null>([["key", 0]]), "1") ? createElementVNode("text", utsMapOf({ key: 0 }), "1")
: isTrue(_ctx.orNot) : isTrue(_ctx.orNot)
? createElementVNode("text", new Map<string, any | null>([["key", 1]]), "2") ? createElementVNode("text", utsMapOf({ key: 1 }), "2")
: createElementVNode("text", new Map<string, any | null>([["key", 2]]), "3") : createElementVNode("text", utsMapOf({ key: 2 }), "3")
])` ])`
) )
}) })
...@@ -250,7 +250,7 @@ describe('compiler: v-if', () => { ...@@ -250,7 +250,7 @@ describe('compiler: v-if', () => {
assert( assert(
`<view v-on="{ click: clickEvent }" v-if="true">w/ v-if</view>`, `<view v-on="{ click: clickEvent }" v-if="true">w/ v-if</view>`,
`isTrue(true) `isTrue(true)
? createElementVNode(\"view\", mergeProps(new Map<string, any | null>([[\"key\", 0]]), toHandlers(new Map<string, any | null>([["click",_ctx.clickEvent] ]), true)), [ ? createElementVNode(\"view\", mergeProps(utsMapOf({ key: 0 }), toHandlers(utsMapOf({ click: _ctx.clickEvent }), true)), [
createElementVNode(\"text\", null, \"w/ v-if\") createElementVNode(\"text\", null, \"w/ v-if\")
], 16 /* FULL_PROPS */) ], 16 /* FULL_PROPS */)
: createCommentVNode(\"v-if\", true)` : createCommentVNode(\"v-if\", true)`
......
...@@ -47,11 +47,11 @@ describe('compiler: transform v-model', () => { ...@@ -47,11 +47,11 @@ describe('compiler: transform v-model', () => {
test('simple expression', () => { test('simple expression', () => {
assert( assert(
`<input v-model="model" />`, `<input v-model="model" />`,
`createElementVNode("input", new Map<string, any | null>([ `createElementVNode("input", utsMapOf({
["modelValue", _ctx.model], modelValue: _ctx.model,
["onInput", ($event: InputEvent): any => {_ctx.model = $event.detail.value; onInput: ($event: InputEvent): any => {_ctx.model = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])` }), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])`
) )
}) })
...@@ -59,86 +59,86 @@ return $event.detail.value;}] ...@@ -59,86 +59,86 @@ return $event.detail.value;}]
test('simple expression (with multilines)', () => { test('simple expression (with multilines)', () => {
assert( assert(
`<input v-model="\nmodel.\nfoo\n" />`, `<input v-model="\nmodel.\nfoo\n" />`,
`createElementVNode("input", new Map<string, any | null>([ `createElementVNode("input", utsMapOf({
["modelValue", \n_ctx.model. modelValue: \n_ctx.model.
foo foo
], ,
["onInput", ($event: InputEvent): any => { onInput: ($event: InputEvent): any => {
_ctx.model. _ctx.model.
foo foo
= $event.detail.value; = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])` }), null, 40 /* PROPS, HYDRATE_EVENTS */, ["modelValue", "onInput"])`
) )
}) })
test('compound expression', () => { test('compound expression', () => {
assert( assert(
`<input v-model="model[index]" />`, `<input v-model="model[index]" />`,
`createElementVNode(\"input\", new Map<string, any | null>([ `createElementVNode(\"input\", utsMapOf({
[\"modelValue\", _ctx.model[_ctx.index]], modelValue: _ctx.model[_ctx.index],
[\"onInput\", ($event: InputEvent): any => {_ctx.model[_ctx.index] = $event.detail.value; onInput: ($event: InputEvent): any => {_ctx.model[_ctx.index] = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, [\"modelValue\", \"onInput\"])` }), null, 40 /* PROPS, HYDRATE_EVENTS */, [\"modelValue\", \"onInput\"])`
) )
}) })
test('with argument', () => { test('with argument', () => {
assert( assert(
`<Foo v-model:title="model" />`, `<Foo v-model:title="model" />`,
`createVNode(_component_Foo, new Map<string, any | null>([ `createVNode(_component_Foo, utsMapOf({
["title", _ctx.model], title: _ctx.model,
["onUpdate:title", $event => {(_ctx.model) = $event}] "onUpdate:title": $event => {(_ctx.model) = $event}
]), null, 8 /* PROPS */, ["title", "onUpdate:title"])` }), null, 8 /* PROPS */, ["title", "onUpdate:title"])`
) )
}) })
test('with dynamic argument', () => { test('with dynamic argument', () => {
assert( assert(
`<Foo v-model:[value]="model" />`, `<Foo v-model:[value]="model" />`,
`createVNode(_component_Foo, normalizeProps(new Map<string, any | null>([ `createVNode(_component_Foo, normalizeProps(utsMapOf({
[_ctx.value, _ctx.model], [_ctx.value]: _ctx.model,
[\"onUpdate:\" + _ctx.value, $event => {(_ctx.model) = $event}] ["onUpdate:" + _ctx.value]: $event => {(_ctx.model) = $event}
])), null, 16 /* FULL_PROPS */)` })), null, 16 /* FULL_PROPS */)`
) )
}) })
test('with modifier lazy', () => { test('with modifier lazy', () => {
assert( assert(
`<input v-model.lazy="model" />`, `<input v-model.lazy="model" />`,
`createElementVNode(\"input\", new Map<string, any | null>([ `createElementVNode(\"input\", utsMapOf({
[\"modelValue\", _ctx.model], modelValue: _ctx.model,
[\"onBlur\", ($event: InputBlurEvent): any => {_ctx.model = $event.detail.value; onBlur: ($event: InputBlurEvent): any => {_ctx.model = $event.detail.value;
return $event.detail.value;}] return $event.detail.value;}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, [\"modelValue\", \"onBlur\"])` }), null, 40 /* PROPS, HYDRATE_EVENTS */, [\"modelValue\", \"onBlur\"])`
) )
}) })
test('with modifier number', () => { test('with modifier number', () => {
assert( assert(
`<input v-model.number="model" />`, `<input v-model.number="model" />`,
`createElementVNode(\"input\", new Map<string, any | null>([ `createElementVNode(\"input\", utsMapOf({
[\"modelValue\", _ctx.model], modelValue: _ctx.model,
[\"onInput\", ($event: InputEvent): any => {_ctx.model = _looseToNumber($event.detail.value); onInput: ($event: InputEvent): any => {_ctx.model = _looseToNumber($event.detail.value);
return _looseToNumber($event.detail.value);}] return _looseToNumber($event.detail.value);}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, [\"modelValue\", \"onInput\"])` }), null, 40 /* PROPS, HYDRATE_EVENTS */, [\"modelValue\", \"onInput\"])`
) )
}) })
test('with modifier trim', () => { test('with modifier trim', () => {
assert( assert(
`<input v-model.trim="model" />`, `<input v-model.trim="model" />`,
`createElementVNode(\"input\", new Map<string, any | null>([ `createElementVNode(\"input\", utsMapOf({
[\"modelValue\", _ctx.model], modelValue: _ctx.model,
[\"onInput\", ($event: InputEvent): any => {_ctx.model = $event.detail.value.trim(); onInput: ($event: InputEvent): any => {_ctx.model = $event.detail.value.trim();
return $event.detail.value.trim();}] return $event.detail.value.trim();}
]), null, 40 /* PROPS, HYDRATE_EVENTS */, [\"modelValue\", \"onInput\"])` }), null, 40 /* PROPS, HYDRATE_EVENTS */, [\"modelValue\", \"onInput\"])`
) )
}) })
test('expression width type', () => { test('expression width type', () => {
assert( assert(
`<Foo v-model="model as string" />`, `<Foo v-model="model as string" />`,
`createVNode(_component_Foo, new Map<string, any | null>([ `createVNode(_component_Foo, utsMapOf({
[\"modelValue\", _ctx.model], modelValue: _ctx.model,
[\"onUpdate:modelValue\", ($event: string) => {(_ctx.model) = $event}] "onUpdate:modelValue": ($event: string) => {(_ctx.model) = $event}
]), null, 8 /* PROPS */, [\"modelValue\", \"onUpdate:modelValue\"])` }), null, 8 /* PROPS */, [\"modelValue\", \"onUpdate:modelValue\"])`
) )
}) })
......
...@@ -39,74 +39,74 @@ describe('compiler: v-on', () => { ...@@ -39,74 +39,74 @@ describe('compiler: v-on', () => {
test('basic', () => { test('basic', () => {
assert( assert(
`<text v-on:click="() => console.log('v-on:click')"/>`, `<text v-on:click="() => console.log('v-on:click')"/>`,
`createElementVNode("text", new Map<string, any | null>([ `createElementVNode("text", utsMapOf({
["onClick", () => console.log('v-on:click')] onClick: () => console.log('v-on:click')
]), null, 8 /* PROPS */, ["onClick"])` }), null, 8 /* PROPS */, ["onClick"])`
) )
assert( assert(
`<text v-on:click="onClick"/>`, `<text v-on:click="onClick"/>`,
`createElementVNode("text", new Map<string, any | null>([["onClick", _ctx.onClick]]), null, 8 /* PROPS */, ["onClick"])` `createElementVNode("text", utsMapOf({ onClick: _ctx.onClick }), null, 8 /* PROPS */, ["onClick"])`
) )
}) })
test('dynamic arg', () => { test('dynamic arg', () => {
assert( assert(
`<text v-on:[event]="handler"/>`, `<text v-on:[event]="handler"/>`,
`createElementVNode("text", new Map<string, any | null>([[toHandlerKey(_ctx.event), _ctx.handler]]), null, 16 /* FULL_PROPS */)` `createElementVNode("text", utsMapOf({ [toHandlerKey(_ctx.event)]: _ctx.handler }), null, 16 /* FULL_PROPS */)`
) )
}) })
test('dynamic arg with complex exp', () => { test('dynamic arg with complex exp', () => {
assert( assert(
`<text v-on:[event(foo)]="handler"/>`, `<text v-on:[event(foo)]="handler"/>`,
`createElementVNode("text", new Map<string, any | null>([[toHandlerKey(_ctx.event(_ctx.foo)), _ctx.handler]]), null, 16 /* FULL_PROPS */)` `createElementVNode("text", utsMapOf({ [toHandlerKey(_ctx.event(_ctx.foo))]: _ctx.handler }), null, 16 /* FULL_PROPS */)`
) )
}) })
test('shorthand', () => { test('shorthand', () => {
assert( assert(
`<text @click="() => console.warn('@click')"/>`, `<text @click="() => console.warn('@click')"/>`,
`createElementVNode("text", new Map<string, any | null>([ `createElementVNode("text", utsMapOf({
["onClick", () => console.warn('@click')] onClick: () => console.warn('@click')
]), null, 8 /* PROPS */, ["onClick"])` }), null, 8 /* PROPS */, ["onClick"])`
) )
}) })
test('inline statement handler', () => { test('inline statement handler', () => {
assert( assert(
`<text @click="count++"/>`, `<text @click="count++"/>`,
`createElementVNode("text", new Map<string, any | null>([ `createElementVNode("text", utsMapOf({
["onClick", () => {_ctx.count++}] onClick: () => {_ctx.count++}
]), null, 8 /* PROPS */, ["onClick"])` }), null, 8 /* PROPS */, ["onClick"])`
) )
}) })
test('should handle multi-line statement', () => { test('should handle multi-line statement', () => {
assert( assert(
`<text @click="\nfoo();\nbar()\n"/>`, `<text @click="\nfoo();\nbar()\n"/>`,
`createElementVNode(\"text\", new Map<string, any | null>([ `createElementVNode(\"text\", utsMapOf({
[\"onClick\", () => { onClick: () => {
_ctx.foo(); _ctx.foo();
_ctx.bar() _ctx.bar()
}] }
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 8 /* PROPS */, [\"onClick\"])`
) )
assert( assert(
`<text @click="a.get('b' + c)()"/>`, `<text @click="a.get('b' + c)()"/>`,
`createElementVNode("text", new Map<string, any | null>([ `createElementVNode("text", utsMapOf({
[\"onClick\", () => {_ctx.a.get('b' + _ctx.c)()}] onClick: () => {_ctx.a.get('b' + _ctx.c)()}
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 8 /* PROPS */, [\"onClick\"])`
) )
}) })
test('inline statement with argument $event', () => { test('inline statement with argument $event', () => {
assert( assert(
`<text @click="foo($event as MouseEvent)"/>`, `<text @click="foo($event as MouseEvent)"/>`,
`createElementVNode(\"text\", new Map<string, any | null>([ `createElementVNode(\"text\", utsMapOf({
[\"onClick\", ($event: any) => {_ctx.foo($event as MouseEvent)}] onClick: ($event: any) => {_ctx.foo($event as MouseEvent)}
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 8 /* PROPS */, [\"onClick\"])`
) )
}) })
test('should NOT wrap as function if expression is already function expression', () => { test('should NOT wrap as function if expression is already function expression', () => {
assert( assert(
`<text @click="($event: MouseEvent) => foo($event)"/>`, `<text @click="($event: MouseEvent) => foo($event)"/>`,
`createElementVNode(\"text\", new Map<string, any | null>([ `createElementVNode(\"text\", utsMapOf({
[\"onClick\", ($event: MouseEvent) => _ctx.foo($event)] onClick: ($event: MouseEvent) => _ctx.foo($event)
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 8 /* PROPS */, [\"onClick\"])`
) )
}) })
test('should NOT wrap as function if expression is already function expression (with newlines)', () => { test('should NOT wrap as function if expression is already function expression (with newlines)', () => {
...@@ -116,13 +116,13 @@ _ctx.bar() ...@@ -116,13 +116,13 @@ _ctx.bar()
foo($event) foo($event)
} }
"/>`, "/>`,
`createElementVNode(\"text\", new Map<string, any | null>([ `createElementVNode(\"text\", utsMapOf({
[\"onClick\", onClick:
($event: MouseEvent) => { ($event: MouseEvent) => {
_ctx.foo($event) _ctx.foo($event)
} }
]
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 8 /* PROPS */, [\"onClick\"])`
) )
}) })
test('should NOT wrap as function if expression is already function expression (with newlines + function keyword)', () => { test('should NOT wrap as function if expression is already function expression (with newlines + function keyword)', () => {
...@@ -132,64 +132,64 @@ _ctx.bar() ...@@ -132,64 +132,64 @@ _ctx.bar()
foo($event) foo($event)
} }
"/>`, "/>`,
`createElementVNode(\"text\", new Map<string, any | null>([ `createElementVNode(\"text\", utsMapOf({
[\"onClick\", onClick:
function($event: MouseEvent) { function($event: MouseEvent) {
_ctx.foo($event) _ctx.foo($event)
} }
]
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 8 /* PROPS */, [\"onClick\"])`
) )
}) })
test('should NOT wrap as function if expression is complex member expression', () => { test('should NOT wrap as function if expression is complex member expression', () => {
assert( assert(
`<text @click="a['b' + c]"/>`, `<text @click="a['b' + c]"/>`,
`createElementVNode("text", new Map<string, any | null>([ `createElementVNode("text", utsMapOf({
[\"onClick\", _ctx.a['b' + _ctx.c]] onClick: _ctx.a['b' + _ctx.c]
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 8 /* PROPS */, [\"onClick\"])`
) )
}) })
test('case conversion for vnode hooks', () => { test('case conversion for vnode hooks', () => {
assert( assert(
`<text v-on:vue:mounted="onMount" @vue:before-update="onBeforeUpdate" />`, `<text v-on:vue:mounted="onMount" @vue:before-update="onBeforeUpdate" />`,
`createElementVNode("text", new Map<string, any | null>([ `createElementVNode("text", utsMapOf({
["onVnodeMounted", _ctx.onMount], onVnodeMounted: _ctx.onMount,
["onVnodeBeforeUpdate", _ctx.onBeforeUpdate] onVnodeBeforeUpdate: _ctx.onBeforeUpdate
]), null, 8 /* PROPS */, ["onVnodeMounted", "onVnodeBeforeUpdate"])` }), null, 8 /* PROPS */, ["onVnodeMounted", "onVnodeBeforeUpdate"])`
) )
}) })
test('inline function expression handler', () => { test('inline function expression handler', () => {
assert( assert(
`<text v-on:click="() => foo()" />`, `<text v-on:click="() => foo()" />`,
`createElementVNode("text", new Map<string, any | null>([ `createElementVNode("text", utsMapOf({
["onClick", () => _ctx.foo()] onClick: () => _ctx.foo()
]), null, 8 /* PROPS */, ["onClick"])` }), null, 8 /* PROPS */, ["onClick"])`
) )
}) })
test('object syntax', () => { test('object syntax', () => {
assert( assert(
`<text v-on="{mousedown: doThis, mouseup: doThat}"/>`, `<text v-on="{mousedown: doThis, mouseup: doThat}"/>`,
`createElementVNode("text", toHandlers(new Map<string, any | null>([["mousedown",_ctx.doThis],["mouseup",_ctx.doThat]]), true), null, 16 /* FULL_PROPS */)` `createElementVNode("text", toHandlers(utsMapOf({mousedown: _ctx.doThis, mouseup: _ctx.doThat}), true), null, 16 /* FULL_PROPS */)`
) )
}) })
test('empty object syntax', () => { test('empty object syntax', () => {
assert( assert(
`<text v-on="{ }"/>`, `<text v-on="{ }"/>`,
`createElementVNode("text", toHandlers(new Map<string, any | null>([]), true), null, 16 /* FULL_PROPS */)` `createElementVNode("text", toHandlers(utsMapOf({ }), true), null, 16 /* FULL_PROPS */)`
) )
}) })
test('simple object syntax', () => { test('simple object syntax', () => {
assert( assert(
`<text v-on="{'a':'aaa'}"/>`, `<text v-on="{'a':'aaa'}"/>`,
`createElementVNode("text", toHandlers(new Map<string, any | null>([['a', 'aaa']]), true), null, 16 /* FULL_PROPS */)` `createElementVNode("text", toHandlers(utsMapOf({'a':'aaa'}), true), null, 16 /* FULL_PROPS */)`
) )
}) })
test('parameter with type', () => { test('parameter with type', () => {
assert( assert(
`<text @click="(e: any) => click(e)" />`, `<text @click="(e: any) => click(e)" />`,
`createElementVNode(\"text\", new Map<string, any | null>([ `createElementVNode(\"text\", utsMapOf({
[\"onClick\", (e: any) => _ctx.click(e)] onClick: (e: any) => _ctx.click(e)
]), null, 8 /* PROPS */, [\"onClick\"])` }), null, 8 /* PROPS */, [\"onClick\"])`
) )
}) })
......
...@@ -95,7 +95,7 @@ describe('compiler: slot', () => { ...@@ -95,7 +95,7 @@ describe('compiler: slot', () => {
`@Suppress("UNUSED_PARAMETER") function PagesIndexIndexRender(): VNode | null { `@Suppress("UNUSED_PARAMETER") function PagesIndexIndexRender(): VNode | null {
const _ctx = this const _ctx = this
return createElementVNode("view", null, [ return createElementVNode("view", null, [
renderSlot(_ctx.$slots, "default", new Map<string, any | null>([["data", "data"]])) renderSlot(_ctx.$slots, "default", utsMapOf({ data: "data" }))
]) ])
}`, }`,
{ {
...@@ -113,12 +113,12 @@ const _ctx = this ...@@ -113,12 +113,12 @@ const _ctx = this
const _component_Foo = resolveComponent("Foo") const _component_Foo = resolveComponent("Foo")
return createElementVNode("view", null, [ return createElementVNode("view", null, [
createVNode(_component_Foo, new Map<string, any | null>([["onClick", _ctx.test]]), new Map<string, any | null>([ createVNode(_component_Foo, utsMapOf({ onClick: _ctx.test }), utsMapOf({
["default", ((): any[] => [ default: ((): any[] => [
createElementVNode("text", null, "test") createElementVNode("text", null, "test")
])], ]),
["_", 1 /* STABLE */] _: 1 /* STABLE */
]), 8 /* PROPS */, ["onClick"]) }), 8 /* PROPS */, ["onClick"])
]) ])
}`, }`,
{ {
...@@ -154,12 +154,12 @@ const _ctx = this ...@@ -154,12 +154,12 @@ const _ctx = this
const _component_Foo = resolveComponent("Foo") const _component_Foo = resolveComponent("Foo")
return createElementVNode("view", null, [ return createElementVNode("view", null, [
createVNode(_component_Foo, null, new Map<string, any | null>([ createVNode(_component_Foo, null, utsMapOf({
["default", ((props: Map<string, any | null>): any[] => [ default: ((props: Map<string, any | null>): any[] => [
createElementVNode("text", null, "msg: " + toDisplayString(props.msg), 1 /* TEXT */) createElementVNode("text", null, "msg: " + toDisplayString(props.msg), 1 /* TEXT */)
])], ]),
["_", 1 /* STABLE */] _: 1 /* STABLE */
])) }))
]) ])
}`, }`,
{ {
...@@ -177,12 +177,12 @@ const _ctx = this ...@@ -177,12 +177,12 @@ const _ctx = this
const _component_Foo = resolveComponent("Foo") const _component_Foo = resolveComponent("Foo")
return createElementVNode("view", null, [ return createElementVNode("view", null, [
createVNode(_component_Foo, null, new Map<string, any | null>([ createVNode(_component_Foo, null, utsMapOf({
["default", ((props: Map<string, any | null>): any[] => [ default: ((props: Map<string, any | null>): any[] => [
createElementVNode("text", null, "msg: " + toDisplayString(props.msg), 1 /* TEXT */) createElementVNode("text", null, "msg: " + toDisplayString(props.msg), 1 /* TEXT */)
])], ]),
["_", 1 /* STABLE */] _: 1 /* STABLE */
])) }))
]) ])
}`, }`,
{ {
......
...@@ -4,9 +4,9 @@ describe('compiler:v-text', () => { ...@@ -4,9 +4,9 @@ describe('compiler:v-text', () => {
test('template v-text', () => { test('template v-text', () => {
assert( assert(
`<text v-text="a"/>`, `<text v-text="a"/>`,
`createElementVNode("text", new Map<string, any | null>([ `createElementVNode("text", utsMapOf({
["value", toDisplayString(_ctx.a)] value: toDisplayString(_ctx.a)
]), null, 8 /* PROPS */, ["value"])` }), null, 8 /* PROPS */, ["value"])`
) )
}) })
}) })
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
"@vue/shared": "3.2.47", "@vue/shared": "3.2.47",
"debug": "^4.3.3", "debug": "^4.3.3",
"es-module-lexer": "^1.2.1", "es-module-lexer": "^1.2.1",
"estree-walker": "^2.0.2",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"picocolors": "^1.0.0", "picocolors": "^1.0.0",
"source-map": "^0.6.1" "source-map": "^0.6.1"
......
...@@ -46,8 +46,7 @@ export function uniAppCssPlugin(): Plugin { ...@@ -46,8 +46,7 @@ export function uniAppCssPlugin(): Plugin {
const { code, messages } = await parse(cssCode, { const { code, messages } = await parse(cssCode, {
filename, filename,
logLevel: 'ERROR', logLevel: 'ERROR',
map: true, mapOf: true,
ts: true,
chunk: 100, chunk: 100,
type: 'uvue', type: 'uvue',
platform: process.env.UNI_UTS_PLATFORM, platform: process.env.UNI_UTS_PLATFORM,
......
...@@ -80,7 +80,10 @@ function serialize(obj: unknown, ts: boolean = false): string { ...@@ -80,7 +80,10 @@ function serialize(obj: unknown, ts: boolean = false): string {
const entries = Object.entries(obj).map( const entries = Object.entries(obj).map(
([key, value]) => `[${serialize(key, ts)},${serialize(value, ts)}]` ([key, value]) => `[${serialize(key, ts)},${serialize(value, ts)}]`
) )
return `new Map${ts ? '<string, any>' : ''}([${entries.join(',')}])` if (entries.length) {
return `utsMapOf([${entries.join(',')}])`
}
return `utsMapOf()`
} else if (isArray(obj)) { } else if (isArray(obj)) {
return `[${obj.map((item) => serialize(item, ts)).join(',')}]` return `[${obj.map((item) => serialize(item, ts)).join(',')}]`
} else { } else {
......
...@@ -44,7 +44,10 @@ import { ...@@ -44,7 +44,10 @@ import {
RESOLVE_EASY_COMPONENT, RESOLVE_EASY_COMPONENT,
TO_HANDLERS, TO_HANDLERS,
} from './runtimeHelpers' } from './runtimeHelpers'
import { objectStringToMapString } from './utils' import {
isCompoundExpressionNode,
isSimpleExpressionNode,
} from '@dcloudio/uni-cli-shared'
type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode
...@@ -429,18 +432,17 @@ function genExpressionAsPropertyKey( ...@@ -429,18 +432,17 @@ function genExpressionAsPropertyKey(
) { ) {
const { push } = context const { push } = context
if (node.type === NodeTypes.COMPOUND_EXPRESSION) { if (node.type === NodeTypes.COMPOUND_EXPRESSION) {
// dynamic arg genObjectExpression have added [] push(`[`)
// push(`[`)
genCompoundExpression(node, context) genCompoundExpression(node, context)
// push(`]`) push(`]`)
} else if (node.isStatic) { } else if (node.isStatic) {
// only quote keys if necessary // only quote keys if necessary
const text = JSON.stringify(node.content) const text = isSimpleIdentifier(node.content)
? node.content
: JSON.stringify(node.content)
push(text, node) push(text, node)
} else { } else {
// dynamic arg genObjectExpression have added [] push(`[${node.content}]`, node)
// push(`[${node.content}]`, node)
push(`${node.content}`, node)
} }
} }
...@@ -538,10 +540,10 @@ function genCallExpression(node: CallExpression, context: CodegenContext) { ...@@ -538,10 +540,10 @@ function genCallExpression(node: CallExpression, context: CodegenContext) {
genRenderList(node) genRenderList(node)
} }
if (callee === helper(TO_HANDLERS)) { if (callee === helper(TO_HANDLERS)) {
genToHandlers(node, push) genToHandlers(node, context)
} }
genNodeList(node.arguments, context) genNodeList(node.arguments, context)
push(`)`) push(`)`)
} }
...@@ -553,45 +555,15 @@ function genRenderList(node: CallExpression) { ...@@ -553,45 +555,15 @@ function genRenderList(node: CallExpression) {
}) })
} }
function genToHandlers( function genToHandlers(node: CallExpression, context: CodegenContext) {
node: CallExpression, const args = node.arguments[0]
push: (code: string, node?: CodegenNode) => void if (isString(args) || isSymbol(args) || isArray(args)) {
) { // skip
push(`new Map<string, any | null>([`) } else if (isSimpleExpressionNode(args)) {
const argument = node.arguments[0] args.content = `utsMapOf(${args.content})`
if ( } else if (isCompoundExpressionNode(args)) {
(argument as CompoundExpressionNode)?.type === NodeTypes.COMPOUND_EXPRESSION args.children.unshift(`utsMapOf(`)
) { args.children.push(')')
;(argument as CompoundExpressionNode).children.forEach(
(child: any, index: number) => {
if (isString(child)) {
if (
index ===
(argument as CompoundExpressionNode).children.length - 1
) {
;(argument as CompoundExpressionNode).children[index] =
child.replace('}', '])')
} else {
;(argument as CompoundExpressionNode).children[index] = child
.replace('{', '["')
.replace(',', ',["')
.replace(':', '",')
.replaceAll(' ', '')
}
} else {
child.content = child.content += ']'
}
}
)
}
if (
(argument as SimpleExpressionNode)?.type === NodeTypes.SIMPLE_EXPRESSION
) {
;(argument as SimpleExpressionNode).content =
objectStringToMapString(
(argument as SimpleExpressionNode).content,
false
) + '])'
} }
} }
...@@ -599,23 +571,22 @@ function genObjectExpression(node: ObjectExpression, context: CodegenContext) { ...@@ -599,23 +571,22 @@ function genObjectExpression(node: ObjectExpression, context: CodegenContext) {
const { push, indent, deindent, newline } = context const { push, indent, deindent, newline } = context
const { properties } = node const { properties } = node
if (!properties.length) { if (!properties.length) {
push(`new Map<string, any | null>()`, node) push(`utsMapOf()`, node)
return return
} }
push(`utsMapOf(`)
const multilines = const multilines =
properties.length > 1 || properties.length > 1 ||
properties.some((p) => p.value.type !== NodeTypes.SIMPLE_EXPRESSION) properties.some((p) => p.value.type !== NodeTypes.SIMPLE_EXPRESSION)
push(`new Map<string, any | null>([`) push(multilines ? `{` : `{ `)
multilines && indent() multilines && indent()
for (let i = 0; i < properties.length; i++) { for (let i = 0; i < properties.length; i++) {
const { key, value } = properties[i] const { key, value } = properties[i]
push(`[`)
// key // key
genExpressionAsPropertyKey(key, context) genExpressionAsPropertyKey(key, context)
push(`, `) push(`: `)
// value // value
genNode(value, context) genNode(value, context)
push(`]`)
if (i < properties.length - 1) { if (i < properties.length - 1) {
// will only reach this if it's multilines // will only reach this if it's multilines
push(`,`) push(`,`)
...@@ -623,7 +594,8 @@ function genObjectExpression(node: ObjectExpression, context: CodegenContext) { ...@@ -623,7 +594,8 @@ function genObjectExpression(node: ObjectExpression, context: CodegenContext) {
} }
} }
multilines && deindent() multilines && deindent()
push(`])`) push(multilines ? `}` : ` }`)
push(`)`)
} }
function genArrayExpression(node: ArrayExpression, context: CodegenContext) { function genArrayExpression(node: ArrayExpression, context: CodegenContext) {
......
...@@ -24,6 +24,7 @@ import { transformText } from './transforms/transformText' ...@@ -24,6 +24,7 @@ import { transformText } from './transforms/transformText'
import { transformOn } from './transforms/vOn' import { transformOn } from './transforms/vOn'
import { transformBind } from './transforms/vBind' import { transformBind } from './transforms/vBind'
import { transformSlotOutlet } from './transforms/transformSlotOutlet' import { transformSlotOutlet } from './transforms/transformSlotOutlet'
// import { transformExpression } from './transforms/transformExpression'
export type TransformPreset = [ export type TransformPreset = [
NodeTransform[], NodeTransform[],
......
import { DirectiveTransform } from '../transform' import { camelize } from '@vue/shared'
import { parseExpression } from '@babel/parser'
import type { Node } from '@babel/types'
import { CAMELIZE } from '@vue/compiler-core'
import { import {
createObjectProperty, createObjectProperty,
createSimpleExpression, createSimpleExpression,
ExpressionNode, ExpressionNode,
NodeTypes, NodeTypes,
} from '@vue/compiler-core' } from '@vue/compiler-core'
import type { DirectiveTransform } from '../transform'
import { createCompilerError, ErrorCodes } from '../errors' import { createCompilerError, ErrorCodes } from '../errors'
import { camelize } from '@vue/shared'
import { CAMELIZE } from '@vue/compiler-core' import { stringifyExpression } from './transformExpression'
import { OBJECT_EXP, objectStringToMapString } from '../utils' import { MagicString, walk } from '@vue/compiler-sfc'
import { isString } from '@vue/shared'
// v-bind without arg is handled directly in ./transformElements.ts due to it affecting // 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 // codegen for the entire props object. This transform here is only for v-bind
...@@ -57,39 +61,30 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => { ...@@ -57,39 +61,30 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
props: [createObjectProperty(arg, createSimpleExpression('', true, loc))], props: [createObjectProperty(arg, createSimpleExpression('', true, loc))],
} }
} }
// 简易处理,理论上rust中也可以处理,但为了单元测试一致性,还是在该阶段中处理
if ((exp as any).content && OBJECT_EXP.test((exp as any).content)) { const source = stringifyExpression(exp)
;(exp as any).content = objectStringToMapString((exp as any).content) if (source.includes('{')) {
} else if ((exp as any).children) { const s = new MagicString(source)
// {'opacity': count > 0.3 ? 1: count * 3, 'color': 'red'} to map const ast = parseExpression(source, {
// TODO: 考虑更多边缘情况 plugins: context.expressionPlugins,
if ( })
isString((exp as any).children[0]) && walk(ast, {
(exp as any).children[0].startsWith('{') && enter(node: Node) {
isString((exp as any).children[(exp as any).children.length - 1]) && if (node.type === 'ObjectExpression') {
(exp as any).children[(exp as any).children.length - 1].endsWith('}') s.prependLeft(node.start!, 'utsMapOf(')
) { s.prependRight(node.end!, ')')
let str = ''
;(exp as any).children.forEach(
(child: ExpressionNode | string, index: number) => {
if (isString(child)) {
str += child
} else {
str += (child as any).content
}
} }
) },
;(exp as any).children = [str] })
return {
props: [
createObjectProperty(
arg,
createSimpleExpression(s.toString(), false, exp.loc)
),
],
} }
;(exp as any).children.forEach(
(child: ExpressionNode | string, index: number) => {
if (isString(child) && OBJECT_EXP.test(child)) {
;(exp as any).children[index] = objectStringToMapString(child)
}
}
)
} }
return { return {
props: [createObjectProperty(arg, exp)], props: [createObjectProperty(arg, exp)],
} }
......
import { makeMap } from '@vue/shared'
import { CompilerOptions } from './options' import { CompilerOptions } from './options'
import { isObject } from '@vue/shared'
export function genRenderFunctionDecl({ export function genRenderFunctionDecl({
targetLanguage, targetLanguage,
...@@ -10,155 +10,10 @@ export function genRenderFunctionDecl({ ...@@ -10,155 +10,10 @@ export function genRenderFunctionDecl({
}function ${filename}Render(): VNode | null` }function ${filename}Render(): VNode | null`
} }
export const OBJECT_EXP = /\{[\s\S]*\}/g const GLOBALS_WHITE_LISTED =
export function objectStringToMapString(content: string, wrap = true): string { 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
content = content.replace(/\n/g, '') 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
const matched = content.match(OBJECT_EXP)![0] 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt' +
const matchedObj = stringToData(matched) as Record<any, any> 'console'
const mapConstructor = convertObjectToMapString(matchedObj)
return content.replace(
matched,
wrap ? mapConstructor : removeMapWrap(mapConstructor)
)
}
function stringToData(str: string): object | any[] | string {
str = str.trim()
if (str.startsWith('{')) {
return stringToObject(removeStartAndEndChar(str))
}
if (str.startsWith('[')) {
return stringToArray(removeStartAndEndChar(str))
}
return str
}
function stringToObject(str: string): object {
const result: Record<string, any> = {}
let preIndex = -1
for (let i = 0; i < str.length; i++) {
const char = str[i]
if (char === ':') {
const key = str.substring(preIndex + 1, i).trim()
const { value, endIndex } = findObjectValueInString(i + 1, str)
result[key] = value
i = endIndex
preIndex = endIndex
}
}
return result
}
function findObjectValueInString(
startIndex: number,
str: string
): { value: any; endIndex: number } {
let num = 0
for (let i = startIndex; i < str.length; i++) {
const char = str[i]
if (isLeftBracket(char)) {
num++
} else if (isRightBracket(char)) {
num--
}
if (char === ',' && num === 0) {
const value = str.substring(startIndex, i).trim()
return {
value: isComplexExpressionString(value) ? stringToData(value) : value,
endIndex: i,
}
}
if (i === str.length - 1 && num === 0) {
const value = str.substring(startIndex, str.length).trim()
return {
value: isComplexExpressionString(value) ? stringToData(value) : value,
endIndex: i,
}
}
}
return { value: '', endIndex: startIndex }
}
function stringToArray(str: string): any[] {
const result = []
let preIndex = -1
let num = 0
for (let i = 0; i < str.length; i++) {
const char = str[i]
if (isLeftBracket(char)) {
num++
} else if (isRightBracket(char)) {
num--
}
if (char === ',' && num === 0) {
const item = str.substring(preIndex + 1, i).trim()
result.push(isComplexExpressionString(item) ? stringToData(item) : item)
preIndex = i
}
if (i === str.length - 1 && num === 0) {
const item = str.substring(preIndex + 1, str.length).trim()
item &&
result.push(isComplexExpressionString(item) ? stringToData(item) : item)
}
}
return result
}
function convertObjectToMapString(obj: Record<any, any>): string {
const keys = Object.keys(obj)
const result = keys.map((key) => getKeyValueString(key, obj[key])).join(', ')
return `new Map<string, any | null>(${result ? `[${result}]` : ''})`
}
function getKeyValueString(key: string, value: any): string { export const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED)
value = getValueString(value)
key = hasExtraQuotationMarks(key) || isBooleanString(value) ? key : `'${key}'`
return `[${key}, ${value}]`
}
function getValueString(value: any): string {
if (Array.isArray(value)) {
return `[${value.map((item) => getValueString(item)).join(', ')}]`
}
if (isObject(value)) {
return convertObjectToMapString(value)
}
return value
}
function removeMapWrap(content: string): string {
const mapPrefixLength = 29 // new Map<string, any | null>([
return content === 'new Map<string, any | null>()'
? ''
: content.substring(mapPrefixLength, content.length - 2)
}
function hasExtraQuotationMarks(str: string): boolean {
return str.startsWith("'") || str.endsWith("'")
}
function removeStartAndEndChar(str: string): string {
return str.substring(1, str.length - 1)
}
function isComplexExpressionString(str: string): boolean {
return /[{[]/.test(str)
}
function isBooleanString(str: string): boolean {
return str === 'true' || str === 'false'
}
function isLeftBracket(char: string): boolean {
return char === '[' || char === '{' || char === '('
}
function isRightBracket(char: string): boolean {
return char === ']' || char === '}' || char === ')'
}
...@@ -18,6 +18,7 @@ import { ...@@ -18,6 +18,7 @@ import {
DirectiveNode, DirectiveNode,
SimpleExpressionNode, SimpleExpressionNode,
AttributeNode, AttributeNode,
CompoundExpressionNode,
} from '@vue/compiler-core' } from '@vue/compiler-core'
import { parse } from '@vue/compiler-dom' import { parse } from '@vue/compiler-dom'
...@@ -112,3 +113,9 @@ export function isSimpleExpressionNode( ...@@ -112,3 +113,9 @@ export function isSimpleExpressionNode(
): node is SimpleExpressionNode { ): node is SimpleExpressionNode {
return node.type === NodeTypes.SIMPLE_EXPRESSION return node.type === NodeTypes.SIMPLE_EXPRESSION
} }
export function isCompoundExpressionNode(
node: Node
): node is CompoundExpressionNode {
return node.type === NodeTypes.COMPOUND_EXPRESSION
}
...@@ -2,7 +2,11 @@ ...@@ -2,7 +2,11 @@
exports[`uvue-style chunk 1`] = `"[new Map<string, Map<string, Map<string, any>>>([["content", new Map<string, any>([["", new Map<string, any>([["display", "flex"]])]])], ["logo", new Map<string, any>([[".content ", new Map<string, any>([["width", "200rpx"], ["height", "200rpx"]])]])]]),new Map<string, Map<string, Map<string, any>>>([["text-area", new Map<string, any>([["", new Map<string, any>([["fontSize", "36rpx"]])]])], ["title", new Map<string, any>([["", new Map<string, any>([["fontSize", "36rpx"]])]])]])]"`; exports[`uvue-style chunk 1`] = `"[new Map<string, Map<string, Map<string, any>>>([["content", new Map<string, any>([["", new Map<string, any>([["display", "flex"]])]])], ["logo", new Map<string, any>([[".content ", new Map<string, any>([["width", "200rpx"], ["height", "200rpx"]])]])]]),new Map<string, Map<string, Map<string, any>>>([["text-area", new Map<string, any>([["", new Map<string, any>([["fontSize", "36rpx"]])]])], ["title", new Map<string, any>([["", new Map<string, any>([["fontSize", "36rpx"]])]])]])]"`;
exports[`uvue-style chunk 2`] = `"[new Map<string, Map<string, Map<string, any>>>([["content", new Map<string, any>([["", new Map<string, any>([["display", "flex"]])]])], ["logo", new Map<string, any>([[".content ", new Map<string, any>([["width", "200rpx"], ["height", "200rpx"]])]])]]),new Map<string, Map<string, Map<string, any>>>([["text-area", new Map<string, any>([["", new Map<string, any>([["fontSize", "36rpx"], ["transitionProperty", "marginTop"], ["transitionDuration", 300]])]])], ["title", new Map<string, any>([["", new Map<string, any>([["fontSize", "36rpx"], ["transitionProperty", "marginTop"], ["transitionDuration", 300]])]])]]),new Map<string, Map<string, Map<string, any>>>([["@FONT-FACE", new Map<string, any>([["0", new Map<string, any>([["fontFamily", "font-family-name-1"], ["src", "url(\\"font file url 1-1\\") format(\\"truetype\\")"]])]])], ["@TRANSITION", new Map<string, any>([["text-area", new Map<string, any>([["property", "marginTop"], ["duration", 300]])], ["title", new Map<string, any>([["property", "marginTop"], ["duration", 300]])]])]])]"`; exports[`uvue-style chunk font-face 1`] = `"[new Map<string, Map<string, Map<string, any>>>([["content", new Map<string, any>([["", new Map<string, any>([["display", "flex"]])]])], ["logo", new Map<string, any>([[".content ", new Map<string, any>([["width", "200rpx"], ["height", "200rpx"]])]])]]),new Map<string, Map<string, Map<string, any>>>([["text-area", new Map<string, any>([["", new Map<string, any>([["fontSize", "36rpx"], ["transitionProperty", "marginTop"], ["transitionDuration", 300]])]])], ["title", new Map<string, any>([["", new Map<string, any>([["fontSize", "36rpx"], ["transitionProperty", "marginTop"], ["transitionDuration", 300]])]])]]),new Map<string, Map<string, Map<string, any>>>([["@FONT-FACE", new Map<string, any>([["0", new Map<string, any>([["fontFamily", "font-family-name-1"], ["src", "url(\\"font file url 1-1\\") format(\\"truetype\\")"]])]])], ["@TRANSITION", new Map<string, any>([["text-area", new Map<string, any>([["property", "marginTop"], ["duration", 300]])], ["title", new Map<string, any>([["property", "marginTop"], ["duration", 300]])]])]])]"`;
exports[`uvue-style chunk font-face with mapOf 1`] = `"[utsMapOf([["content", utsMapOf([["", utsMapOf([["display", "flex"]])]])], ["logo", utsMapOf([[".content ", utsMapOf([["width", "200rpx"], ["height", "200rpx"]])]])]]),utsMapOf([["text-area", utsMapOf([["", utsMapOf([["fontSize", "36rpx"], ["transitionProperty", "marginTop"], ["transitionDuration", 300]])]])], ["title", utsMapOf([["", utsMapOf([["fontSize", "36rpx"], ["transitionProperty", "marginTop"], ["transitionDuration", 300]])]])]]),utsMapOf([["@FONT-FACE", utsMapOf([["0", utsMapOf([["fontFamily", "font-family-name-1"], ["src", "url(\\"font file url 1-1\\") format(\\"truetype\\")"]])]])], ["@TRANSITION", utsMapOf([["text-area", utsMapOf([["property", "marginTop"], ["duration", 300]])], ["title", utsMapOf([["property", "marginTop"], ["duration", 300]])]])]])]"`;
exports[`uvue-style chunk with mapOf 1`] = `"[utsMapOf([["content", utsMapOf([["", utsMapOf([["display", "flex"]])]])], ["logo", utsMapOf([[".content ", utsMapOf([["width", "200rpx"], ["height", "200rpx"]])]])]]),utsMapOf([["text-area", utsMapOf([["", utsMapOf([["fontSize", "36rpx"]])]])], ["title", utsMapOf([["", utsMapOf([["fontSize", "36rpx"]])]])]])]"`;
exports[`uvue-style js 1`] = `"new Map([["content", new Map([["", new Map([["display", "flex"]])]])], ["logo", new Map([[".content ", new Map([["width", "200rpx"], ["height", "200rpx"]])]])], ["text-area", new Map([["", new Map([["fontSize", "36rpx"]])]])], ["title", new Map([["", new Map([["fontSize", "36rpx"]])]])]])"`; exports[`uvue-style js 1`] = `"new Map([["content", new Map([["", new Map([["display", "flex"]])]])], ["logo", new Map([[".content ", new Map([["width", "200rpx"], ["height", "200rpx"]])]])], ["text-area", new Map([["", new Map([["fontSize", "36rpx"]])]])], ["title", new Map([["", new Map([["fontSize", "36rpx"]])]])]])"`;
......
...@@ -54,7 +54,25 @@ describe('uvue-style', () => { ...@@ -54,7 +54,25 @@ describe('uvue-style', () => {
) )
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })
test('chunk', async () => { test('chunk with mapOf', async () => {
const { code } = await parse(
`
.content {
display: flex;
}
.content .logo {
width: 200rpx;
height: 200rpx;
}
.text-area, .title {
font-size: 36rpx;
}
`,
{ mapOf: true, chunk: 2 }
)
expect(code).toMatchSnapshot()
})
test('chunk font-face', async () => {
const { code } = await parse( const { code } = await parse(
` `
@font-face { @font-face {
...@@ -78,4 +96,28 @@ describe('uvue-style', () => { ...@@ -78,4 +96,28 @@ describe('uvue-style', () => {
) )
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })
test('chunk font-face with mapOf', async () => {
const { code } = await parse(
`
@font-face {
font-family: "font-family-name-1";
src: url("font file url 1-1") format("truetype");
}
.content {
display: flex;
}
.content .logo {
width: 200rpx;
height: 200rpx;
}
.text-area, .title {
font-size: 36rpx;
transition-property: margin-top;
transition-duration: 300ms;
}
`,
{ mapOf: true, chunk: 2 }
)
expect(code).toMatchSnapshot()
})
}) })
...@@ -7,6 +7,7 @@ import { NormalizeOptions } from './utils' ...@@ -7,6 +7,7 @@ import { NormalizeOptions } from './utils'
interface ParseOptions extends NormalizeOptions { interface ParseOptions extends NormalizeOptions {
filename?: string filename?: string
map?: boolean map?: boolean
mapOf?: boolean
ts?: boolean ts?: boolean
chunk?: number chunk?: number
noCode?: boolean noCode?: boolean
...@@ -35,12 +36,13 @@ export async function parse(input: string, options: ParseOptions = {}) { ...@@ -35,12 +36,13 @@ export async function parse(input: string, options: ParseOptions = {}) {
return { code: '', messages } return { code: '', messages }
} }
const obj = root ? objectifier(root) : {} const obj = root ? objectifier(root) : {}
if (options.map) { if (options.map || options.mapOf) {
return { return {
code: mapToInitStringChunk( code: mapToInitStringChunk(
objToMap(obj), objToMap(obj),
options.ts, options.ts,
true, true,
options.mapOf,
options.chunk options.chunk
), ),
messages, messages,
...@@ -53,17 +55,18 @@ function mapToInitStringChunk( ...@@ -53,17 +55,18 @@ function mapToInitStringChunk(
map: Map<string, unknown>, map: Map<string, unknown>,
ts: boolean = false, ts: boolean = false,
isRoot: boolean = false, isRoot: boolean = false,
isMapOf: boolean = false,
chunk: number = 0 chunk: number = 0
): string { ): string {
if (!chunk) { if (!chunk) {
return mapToInitString(map, ts, isRoot) return mapToInitString(map, ts, isRoot, isMapOf)
} }
const chunks: string[] = [] const chunks: string[] = []
let chunkMap: Map<string, unknown> = new Map() let chunkMap: Map<string, unknown> = new Map()
let chunkCount = 0 let chunkCount = 0
for (const [key, value] of map) { for (const [key, value] of map) {
if (chunkCount === chunk) { if (chunkCount === chunk) {
chunks.push(mapToInitString(chunkMap, ts, isRoot)) chunks.push(mapToInitString(chunkMap, ts, isRoot, isMapOf))
chunkMap = new Map() chunkMap = new Map()
chunkCount = 0 chunkCount = 0
} }
...@@ -71,7 +74,7 @@ function mapToInitStringChunk( ...@@ -71,7 +74,7 @@ function mapToInitStringChunk(
chunkCount++ chunkCount++
} }
if (chunkCount) { if (chunkCount) {
chunks.push(mapToInitString(chunkMap, ts, isRoot)) chunks.push(mapToInitString(chunkMap, ts, isRoot, isMapOf))
} }
return `[${chunks.join(',')}]` return `[${chunks.join(',')}]`
} }
...@@ -79,16 +82,20 @@ function mapToInitStringChunk( ...@@ -79,16 +82,20 @@ function mapToInitStringChunk(
function mapToInitString( function mapToInitString(
map: Map<string, unknown>, map: Map<string, unknown>,
ts: boolean = false, ts: boolean = false,
isRoot: boolean = false isRoot: boolean = false,
isMapOf: boolean = false
): string { ): string {
const entries = [] const entries = []
for (let [key, value] of map) { for (let [key, value] of map) {
if (value instanceof Map) { if (value instanceof Map) {
entries.push(`["${key}", ${mapToInitString(value, ts)}]`) entries.push(`["${key}", ${mapToInitString(value, ts, false, isMapOf)}]`)
} else { } else {
entries.push(`["${key}", ${JSON.stringify(value)}]`) entries.push(`["${key}", ${JSON.stringify(value)}]`)
} }
} }
if (isMapOf) {
return `utsMapOf([${entries.join(', ')}])`
}
return `new Map${ return `new Map${
ts ts
? isRoot ? isRoot
......
...@@ -397,6 +397,9 @@ importers: ...@@ -397,6 +397,9 @@ importers:
es-module-lexer: es-module-lexer:
specifier: ^1.2.1 specifier: ^1.2.1
version: 1.2.1 version: 1.2.1
estree-walker:
specifier: ^2.0.2
version: 2.0.2
fs-extra: fs-extra:
specifier: ^10.0.0 specifier: ^10.0.0
version: 10.0.0 version: 10.0.0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册