Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
uni-app
提交
0c535ff4
U
uni-app
项目概览
DCloud
/
uni-app
6 个月 前同步成功
通知
751
Star
38709
Fork
3642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
8
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
8
Issue
8
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
0c535ff4
编写于
12月 21, 2023
作者:
fxy060608
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip(uvue): setup
上级
233fe0c6
变更
14
展开全部
隐藏空白更改
内联
并排
Showing
14 changed file
with
2555 addition
and
32 deletion
+2555
-32
packages/uni-app-uts/__tests__/android/sfc/__snapshots__/compileScript.spec.ts.snap
...ts__/android/sfc/__snapshots__/compileScript.spec.ts.snap
+779
-0
packages/uni-app-uts/__tests__/android/sfc/compileScript.spec.ts
...s/uni-app-uts/__tests__/android/sfc/compileScript.spec.ts
+1559
-0
packages/uni-app-uts/__tests__/android/sfc/utils.ts
packages/uni-app-uts/__tests__/android/sfc/utils.ts
+58
-0
packages/uni-app-uts/__tests__/android/transforms/__snapshots__/transformExpressions.spec.ts.snap
...ransforms/__snapshots__/transformExpressions.spec.ts.snap
+2
-2
packages/uni-app-uts/__tests__/android/transforms/transformExpressions.spec.ts
...__tests__/android/transforms/transformExpressions.spec.ts
+2
-3
packages/uni-app-uts/src/plugins/android/uvue/compiler/codegen.ts
.../uni-app-uts/src/plugins/android/uvue/compiler/codegen.ts
+1
-1
packages/uni-app-uts/src/plugins/android/uvue/compiler/index.ts
...es/uni-app-uts/src/plugins/android/uvue/compiler/index.ts
+0
-1
packages/uni-app-uts/src/plugins/android/uvue/compiler/options.ts
.../uni-app-uts/src/plugins/android/uvue/compiler/options.ts
+4
-5
packages/uni-app-uts/src/plugins/android/uvue/compiler/transform.ts
...ni-app-uts/src/plugins/android/uvue/compiler/transform.ts
+3
-1
packages/uni-app-uts/src/plugins/android/uvue/compiler/transforms/transformExpression.ts
...s/android/uvue/compiler/transforms/transformExpression.ts
+6
-1
packages/uni-app-uts/src/plugins/android/uvue/index.ts
packages/uni-app-uts/src/plugins/android/uvue/index.ts
+0
-1
packages/uni-app-uts/src/plugins/android/uvue/sfc/compiler/compileScript.ts
...ts/src/plugins/android/uvue/sfc/compiler/compileScript.ts
+130
-14
packages/uni-app-uts/src/plugins/android/uvue/sfc/main.ts
packages/uni-app-uts/src/plugins/android/uvue/sfc/main.ts
+9
-2
packages/uni-app-uts/src/plugins/android/uvue/sfc/template.ts
...ages/uni-app-uts/src/plugins/android/uvue/sfc/template.ts
+2
-1
未找到文件。
packages/uni-app-uts/__tests__/android/sfc/__snapshots__/compileScript.spec.ts.snap
0 → 100644
浏览文件 @
0c535ff4
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SFC analyze <script> bindings auto name inference basic 1`] = `
"const a = 1
export default {
__name: 'FooBar',
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC analyze <script> bindings auto name inference do not overwrite manual name (call) 1`] = `
"import { defineComponent } from 'vue'
const __default__ = defineComponent({
name: 'Baz'
})
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const a = 1
return "INLINE_RENDER"
}
}"
`;
exports[`SFC analyze <script> bindings auto name inference do not overwrite manual name (object) 1`] = `
"const __default__ = {
name: 'Baz'
}
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const a = 1
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> binding analysis for destructure 1`] = `
"export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const { foo, b: bar, ['x' + 'y']: baz, x: { y, zz: { z }}} = {}
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check TS annotations 1`] = `
"import { Foo, Bar, Baz, Qux, Fred } from './x'
const a = 1
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
function b() {}
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check attribute expressions 1`] = `
"import { bar, baz } from './x'
const cond = true
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check components 1`] = `
"import { FooBar, FooBaz, FooQux, foo } from './x'
const fooBar: FooBar = 1
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check directive 1`] = `
"import { vMyDir } from './x'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check dynamic arguments 1`] = `
"import { FooBar, foo, bar, unused, baz } from './x'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check js template string interpolations 1`] = `
"import { VAR, VAR2, VAR3 } from './x'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check last tag 1`] = `
"import { FooBaz, Last } from './x'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check template ref 1`] = `
"import { foo, bar, Baz } from './foo'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> dev mode import usage check vue interpolations 1`] = `
"import { x, y, z, x$y } from './x'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> errors should allow defineProps/Emit() referencing imported binding 1`] = `
"import { bar } from './bar'
export default {
props: {
foo: {
default: () => bar
}
},
emits: {
foo: () => bar > 1
},
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> errors should allow defineProps/Emit() referencing scope var 1`] = `
"const bar = 1
export default {
props: {
foo: {
default: bar => bar + 1
}
},
emits: {
foo: bar => bar > 1
},
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> imports dedupe between user & helper 1`] = `
"import { ref } from 'vue'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
let foo = $ref(1)
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> imports import dedupe between <script> and <script setup> 1`] = `
"import { x } from './x'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
x()
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> imports should allow defineProps/Emit at the start of imports 1`] = `
"import { ref } from 'vue'
export default {
props: ['foo'],
emits: ['bar'],
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const r = ref(0)
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> imports should extract comment for import or type declarations 1`] = `
"import a from 'a' // comment
import b from 'b'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> imports should hoist and expose imports 1`] = `
"import { ref } from 'vue'
import 'foo/css'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> imports should support module string names syntax 1`] = `
"import { "😏" as foo } from './foo'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> inlineTemplate mode avoid unref() when necessary 1`] = `
"import { ref } from 'vue'
import Foo, { bar } from './Foo.vue'
import other from './util'
import * as tree from './tree'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const count = ref(0)
const constant = {}
const maybe = foo()
let lett = 1
function fn() {}
return
function GenAnonymousRender(): VNode | null {
const _component_div = resolveComponent("div")
return createElementVNode(Fragment, null, [
createVNode(Foo, null, utsMapOf({
default: withSlotCtx((): any[] => [toDisplayString(unref(bar))]),
_: 1 /* STABLE */
})),
createVNode(_component_div, utsMapOf({ onClick: fn }), utsMapOf({
default: withSlotCtx((): any[] => [toDisplayString(count.value) + " " + toDisplayString(constant) + " " + toDisplayString(unref(maybe)) + " " + toDisplayString(unref(lett)) + " " + toDisplayString(unref(other))]),
_: 1 /* STABLE */
})),
" " + toDisplayString(tree.foo())
], 64 /* STABLE_FRAGMENT */)
}
}
}"
`;
exports[`SFC compile <script setup> inlineTemplate mode referencing scope components and directives 1`] = `
"import ChildComp from './Child.vue'
import SomeOtherComp from './Other.vue'
import vMyDir from './my-dir'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return
function GenAnonymousRender(): VNode | null {
const _component_div = resolveComponent("div")
return createElementVNode(Fragment, null, [
withDirectives(createVNode(_component_div, null, null, 512 /* NEED_PATCH */), [
[unref(vMyDir)]
]),
createVNode(ChildComp),
createVNode(SomeOtherComp)
], 64 /* STABLE_FRAGMENT */)
}
}
}"
`;
exports[`SFC compile <script setup> inlineTemplate mode should work 1`] = `
"import { ref } from 'vue'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const count = ref(0)
return
function GenAnonymousRender(): VNode | null {
const _component_div = resolveComponent("div")
return createElementVNode(Fragment, null, [
createVNode(_component_div, null, utsMapOf({
default: withSlotCtx((): any[] => [toDisplayString(count.value)]),
_: 1 /* STABLE */
})),
createVNode(_component_div, null, utsMapOf({
default: withSlotCtx((): any[] => ["static"]),
_: 1 /* STABLE */
}))
], 64 /* STABLE_FRAGMENT */)
}
}
}"
`;
exports[`SFC compile <script setup> inlineTemplate mode template assignment expression codegen 1`] = `
"import { ref } from 'vue'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const count = ref(0)
const maybe = foo()
let lett = 1
let v = ref(1)
return
function GenAnonymousRender(): VNode | null {
const _component_div = resolveComponent("div")
return createElementVNode(Fragment, null, [
createVNode(_component_div, utsMapOf({
onClick: () => {count.value = 1}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {maybe.value = count.value}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {isRef(lett) ? lett.value = count.value : lett = count.value}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {isRef(v) ? v.value += 1 : v += 1}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {isRef(v) ? v.value -= 1 : v -= 1}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {
let a = '' + unref(lett)
isRef(v) ? v.value = a : v = a
}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {
// nested scopes
(()=>{
let x = _ctx.a
(()=>{
let z = x
let z2 = z
})
let lz = _ctx.z
})
isRef(v) ? v.value = _ctx.a : v = _ctx.a
}
}), null, 8 /* PROPS */, ["onClick"])
], 64 /* STABLE_FRAGMENT */)
}
}
}"
`;
exports[`SFC compile <script setup> inlineTemplate mode template destructure assignment codegen 1`] = `
"import { ref } from 'vue'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const val = {}
const count = ref(0)
const maybe = foo()
let lett = 1
return
function GenAnonymousRender(): VNode | null {
const _component_div = resolveComponent("div")
return createElementVNode(Fragment, null, [
createVNode(_component_div, utsMapOf({
onClick: () => {({ count: count.value } = val)}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {[maybe.value] = val}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {({ lett: lett } = val)}
}), null, 8 /* PROPS */, ["onClick"])
], 64 /* STABLE_FRAGMENT */)
}
}
}"
`;
exports[`SFC compile <script setup> inlineTemplate mode template update expression codegen 1`] = `
"import { ref } from 'vue'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const count = ref(0)
const maybe = foo()
let lett = 1
return
function GenAnonymousRender(): VNode | null {
const _component_div = resolveComponent("div")
return createElementVNode(Fragment, null, [
createVNode(_component_div, utsMapOf({
onClick: () => {count.value++}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {--count.value}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {maybe.value++}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {--maybe.value}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {isRef(lett) ? lett.value++ : lett++}
}), null, 8 /* PROPS */, ["onClick"]),
createVNode(_component_div, utsMapOf({
onClick: () => {isRef(lett) ? --lett.value : --lett}
}), null, 8 /* PROPS */, ["onClick"])
], 64 /* STABLE_FRAGMENT */)
}
}
}"
`;
exports[`SFC compile <script setup> inlineTemplate mode v-model codegen 1`] = `
"import { ref } from 'vue'
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const count = ref(0)
const maybe = foo()
let lett = 1
return
function GenAnonymousRender(): VNode | null {
return createElementVNode(Fragment, null, [
createElementVNode("input", utsMapOf({
modelValue: count.value,
onInput: ($event: InputEvent) => {(count).value = $event.detail.value}
}), null, 40 /* PROPS, NEED_HYDRATION */, ["modelValue", "onInput"]),
createElementVNode("input", utsMapOf({
modelValue: unref(maybe),
onInput: ($event: InputEvent) => {isRef(maybe) ? (maybe).value = $event.detail.value : null}
}), null, 40 /* PROPS, NEED_HYDRATION */, ["modelValue", "onInput"]),
createElementVNode("input", utsMapOf({
modelValue: unref(lett),
onInput: ($event: InputEvent) => {isRef(lett) ? (lett).value = $event.detail.value : lett = $event.detail.value}
}), null, 40 /* PROPS, NEED_HYDRATION */, ["modelValue", "onInput"])
], 64 /* STABLE_FRAGMENT */)
}
}
}"
`;
exports[`SFC compile <script setup> inlineTemplate mode with defineExpose() 1`] = `
"export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
const count = ref(0)
__expose({ count })
return function GenAnonymousRender(): VNode | null { return null }
}
}"
`;
exports[`SFC compile <script setup> should compile JS syntax 1`] = `
"const a = 1
const b = 2
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> should expose top level declarations 1`] = `
"import { x } from './x'
import { xx } from './x'
let aa = 1
const bb = 2
function cc() {}
class dd {}
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
let a = 1
const b = 2
function c() {}
class d {}
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> with TypeScript const Enum 1`] = `
"const enum Foo { A = 123 }
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> with TypeScript hoist type declarations 1`] = `
"export interface Foo {}
type Bar = {}
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> with TypeScript runtime Enum 1`] = `
"enum Foo { A = 123 }
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
return "INLINE_RENDER"
}
}"
`;
exports[`SFC compile <script setup> with TypeScript runtime Enum in normal script 1`] = `
"export enum D { D = "D" }
const enum C { C = "C" }
enum B { B = "B" }
export default {
setup() {
const __ins = getCurrentInstance()!;
const _ctx = __ins.proxy;
const _cache = __ins.renderCache;
enum Foo { A = 123 }
return "INLINE_RENDER"
}
}"
`;
packages/uni-app-uts/__tests__/android/sfc/compileScript.spec.ts
0 → 100644
浏览文件 @
0c535ff4
此差异已折叠。
点击以展开。
packages/uni-app-uts/__tests__/android/sfc/utils.ts
0 → 100644
浏览文件 @
0c535ff4
import
{
parse
,
SFCParseOptions
}
from
'
@vue/compiler-sfc
'
import
{
parse
as
babelParse
}
from
'
@babel/parser
'
import
{
compileScript
,
SFCScriptCompileOptions
,
}
from
'
../../../src/plugins/android/uvue/sfc/compiler/compileScript
'
import
{
genTemplateCode
}
from
'
../../../src/plugins/android/uvue/code/template
'
import
{
resolveGenTemplateCodeOptions
}
from
'
../../../src/plugins/android/uvue/sfc/template
'
export
const
mockId
=
'
xxxxxxxx
'
export
function
compileSFCScript
(
src
:
string
,
options
?:
Partial
<
SFCScriptCompileOptions
>
,
parseOptions
?:
SFCParseOptions
)
{
const
{
descriptor
}
=
parse
(
src
,
parseOptions
)
const
result
=
compileScript
(
descriptor
,
{
...
options
,
id
:
mockId
,
className
:
''
,
inlineTemplate
:
true
,
scriptAndScriptSetup
:
true
,
})
if
(
options
?.
inlineTemplate
)
{
const
isInline
=
!!
descriptor
.
scriptSetup
const
templateResult
=
genTemplateCode
(
descriptor
,
resolveGenTemplateCodeOptions
(
descriptor
.
filename
,
src
,
descriptor
,
{
mode
:
'
module
'
,
inline
:
isInline
,
rootDir
:
''
,
sourceMap
:
false
,
bindingMetadata
:
result
.
bindings
,
})
)
result
.
content
=
result
.
content
.
replace
(
`"INLINE_RENDER"`
,
templateResult
.
code
)
}
return
result
}
export
function
assertCode
(
code
:
string
)
{
// parse the generated code to make sure it is valid
try
{
babelParse
(
code
,
{
sourceType
:
'
module
'
,
plugins
:
[
'
typescript
'
],
})
}
catch
(
e
:
any
)
{
console
.
log
(
code
,
e
)
throw
e
}
// console.log(code)
expect
(
code
).
toMatchSnapshot
()
}
packages/uni-app-uts/__tests__/android/transforms/__snapshots__/transformExpressions.spec.ts.snap
浏览文件 @
0c535ff4
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: expression transform bindingMetadata inline mode 1`] = `"createElementVNode("view", null, toDisplayString(__props.props) + " " + toDisplayString(unref(setup)) + " " + toDisplayString(setupConst) + " " + toDisplayString(_ctx.data) + " " + toDisplayString(_ctx.options) + " " + toDisplayString(isNaN), 1 /* TEXT */)"`;
exports[`compiler: expression transform bindingMetadata inline mode 1`] = `"createElementVNode("view", null, toDisplayString(__props.props) + " " + toDisplayString(unref(setup)) + " " + toDisplayString(setupConst) + " " + toDisplayString(_ctx.data) + " " + toDisplayString(_ctx.options) + " " + toDisplayString(isNaN
.value
), 1 /* TEXT */)"`;
exports[`compiler: expression transform bindingMetadata non-inline mode 1`] = `"createElementVNode("view", null, toDisplayString($props.props) + " " + toDisplayString($setup.setup) + " " + toDisplayString($data.data) + " " + toDisplayString($options.options) + " " + toDisplayString(isNaN), 1 /* TEXT */)"`;
exports[`compiler: expression transform bindingMetadata non-inline mode 1`] = `"createElementVNode("view", null, toDisplayString($props.props) + " " + toDisplayString($setup.setup) + " " + toDisplayString($data.data) + " " + toDisplayString($options.options) + " " + toDisplayString(
$setup.
isNaN), 1 /* TEXT */)"`;
exports[`compiler: expression transform bindingMetadata should not prefix temp variable of for loop 1`] = `
"createVNode(_component_div, utsMapOf({
...
...
packages/uni-app-uts/__tests__/android/transforms/transformExpressions.spec.ts
浏览文件 @
0c535ff4
...
...
@@ -532,7 +532,7 @@ describe('compiler: expression transform', () => {
)
expect
(
code
).
toMatch
(
`$props.props`
)
expect
(
code
).
toMatch
(
`$setup.setup`
)
//
expect(code).toMatch(`$setup.isNaN`)
expect
(
code
).
toMatch
(
`$setup.isNaN`
)
expect
(
code
).
toMatch
(
`$data.data`
)
expect
(
code
).
toMatch
(
`$options.options`
)
// expect(code).toMatch(`_ctx, _cache, $props, $setup, $data, $options`)
...
...
@@ -585,8 +585,7 @@ describe('compiler: expression transform', () => {
expect
(
code
).
toMatch
(
`toDisplayString(setupConst)`
)
expect
(
code
).
toMatch
(
`_ctx.data`
)
expect
(
code
).
toMatch
(
`_ctx.options`
)
// isNaN 设置了全局方法
// expect(code).toMatch(`isNaN.value`)
expect
(
code
).
toMatch
(
`isNaN.value`
)
expect
(
code
).
toMatchSnapshot
()
})
...
...
packages/uni-app-uts/src/plugins/android/uvue/compiler/codegen.ts
浏览文件 @
0c535ff4
...
...
@@ -99,7 +99,7 @@ function createCodegenContext(
rootDir
=
''
,
targetLanguage
=
'
kotlin
'
,
mode
=
'
default
'
,
prefixIdentifiers
=
false
,
prefixIdentifiers
=
mode
===
'
module
'
,
bindingMetadata
=
{},
inline
=
false
,
sourceMap
=
false
,
...
...
packages/uni-app-uts/src/plugins/android/uvue/compiler/index.ts
浏览文件 @
0c535ff4
...
...
@@ -107,7 +107,6 @@ export function compile(
transform
(
ast
,
extend
({},
options
,
{
prefixIdentifiers
:
options
.
prefixIdentifiers
,
nodeTransforms
:
[
...
nodeTransforms
,
...
getBaseNodeTransforms
(
'
/
'
),
...
...
packages/uni-app-uts/src/plugins/android/uvue/compiler/options.ts
浏览文件 @
0c535ff4
...
...
@@ -3,6 +3,10 @@ import type { RawSourceMap } from 'source-map-js'
import
{
DirectiveTransform
,
NodeTransform
}
from
'
./transform
'
interface
SharedTransformCodegenOptions
{
/**
* @default 'default'
*/
mode
?:
'
default
'
|
'
module
'
rootDir
?:
string
targetLanguage
?:
'
kotlin
'
|
'
swift
'
/**
...
...
@@ -32,11 +36,6 @@ interface SharedTransformCodegenOptions {
className
?:
string
}
export
interface
CodegenOptions
extends
SharedTransformCodegenOptions
{
/**
* @default 'default'
*/
mode
?:
'
default
'
|
'
module
'
inMap
?:
RawSourceMap
/**
* Generate source map?
...
...
packages/uni-app-uts/src/plugins/android/uvue/compiler/transform.ts
浏览文件 @
0c535ff4
...
...
@@ -116,11 +116,12 @@ export interface TransformContext
export
function
createTransformContext
(
root
:
RootNode
,
{
mode
=
'
default
'
,
rootDir
=
''
,
targetLanguage
=
'
kotlin
'
,
filename
=
''
,
cacheHandlers
=
false
,
prefixIdentifiers
=
false
,
prefixIdentifiers
=
mode
===
'
module
'
,
nodeTransforms
=
[],
directiveTransforms
=
{},
scopeId
=
null
,
...
...
@@ -136,6 +137,7 @@ export function createTransformContext(
const
nameMatch
=
filename
.
replace
(
/
\?
.*$/
,
''
).
match
(
/
([^/\\]
+
)\.\w
+$/
)
const
context
:
TransformContext
=
{
// options
mode
,
rootDir
,
targetLanguage
,
selfName
:
nameMatch
&&
capitalize
(
camelize
(
nameMatch
[
1
])),
...
...
packages/uni-app-uts/src/plugins/android/uvue/compiler/transforms/transformExpression.ts
浏览文件 @
0c535ff4
...
...
@@ -221,7 +221,12 @@ export function processExpression(
const
isScopeVarReference
=
context
.
identifiers
[
rawExp
]
const
isAllowedGlobal
=
isGloballyWhitelisted
(
rawExp
)
const
isLiteral
=
isLiteralWhitelisted
(
rawExp
)
if
(
!
asParams
&&
!
isScopeVarReference
&&
!
isAllowedGlobal
&&
!
isLiteral
)
{
if
(
!
asParams
&&
!
isScopeVarReference
&&
!
isLiteral
&&
(
!
isAllowedGlobal
||
bindingMetadata
[
rawExp
])
)
{
// const bindings exposed from setup can be skipped for patching but
// cannot be hoisted to module scope
if
(
bindingMetadata
[
node
.
content
]
===
BindingTypes
.
SETUP_CONST
)
{
...
...
packages/uni-app-uts/src/plugins/android/uvue/index.ts
浏览文件 @
0c535ff4
...
...
@@ -258,7 +258,6 @@ export async function transformVue(
mode
:
'
module
'
,
filename
:
relativeFileName
,
className
:
className
,
prefixIdentifiers
:
true
,
// 方便测试,build模式也提供sourceMap
// sourceMap: false,
sourceMap
:
needSourceMap
,
...
...
packages/uni-app-uts/src/plugins/android/uvue/sfc/compiler/compileScript.ts
浏览文件 @
0c535ff4
...
...
@@ -13,6 +13,7 @@ import {
Identifier
,
Statement
,
CallExpression
,
ExportSpecifier
,
}
from
'
@babel/types
'
import
{
walk
}
from
'
estree-walker
'
import
type
{
RawSourceMap
}
from
'
source-map-js
'
...
...
@@ -43,12 +44,22 @@ import {
}
from
'
./script/utils
'
import
{
analyzeScriptBindings
}
from
'
./script/analyzeScriptBindings
'
import
{
parseUTSRelativeFilename
}
from
'
../../../utils
'
import
{
rewriteConsole
}
from
'
./script/rewriteConsole
'
import
{
hasConsole
,
rewriteConsole
}
from
'
./script/rewriteConsole
'
import
{
hasDebugError
,
rewriteDebugError
}
from
'
./script/rewriteDebugError
'
import
{
TypeScope
}
from
'
./script/resolveType
'
export
const
normalScriptDefaultVar
=
`__default__`
export
const
DEFAULT_FILENAME
=
'
anonymous.vue
'
export
interface
SFCScriptCompileOptions
{
/**
* 是否同时支持使用 <script> 和 <script setup>
*/
scriptAndScriptSetup
?:
boolean
/**
* Class name
*/
className
:
string
/**
* Scope ID for prefixing injected CSS variables.
...
...
@@ -162,6 +173,13 @@ export function compileScript(
const
hoistStatic
=
options
.
hoistStatic
!==
false
&&
!
script
const
scopeId
=
options
.
id
?
options
.
id
.
replace
(
/^data-v-/
,
''
)
:
''
// 目前暂不提供<script setup>和<script>同时使用
// 目前给了个开关,用于单元测试
if
(
!
options
.
scriptAndScriptSetup
)
{
if
(
script
&&
scriptSetup
)
{
throw
new
Error
(
`<script setup> and <script> cannot be used together.`
)
}
}
// TODO remove in 3.4
// const enableReactivityTransform = !!options.reactivityTransform
let
refBindings
:
string
[]
|
undefined
...
...
@@ -191,7 +209,7 @@ export function compileScript(
const
scriptBindings
:
Record
<
string
,
BindingTypes
>
=
Object
.
create
(
null
)
const
setupBindings
:
Record
<
string
,
BindingTypes
>
=
Object
.
create
(
null
)
//
let defaultExport: Node | undefined
let
defaultExport
:
Node
|
undefined
let
hasAwait
=
false
// let hasInlinedSsrRenderFn = false
...
...
@@ -296,7 +314,7 @@ export function compileScript(
startOffset
,
})
}
if
(
scriptSetupContent
.
includes
(
'
console
'
))
{
if
(
hasConsole
(
scriptSetupContent
))
{
rewriteConsole
(
scriptSetupAst
,
ctx
.
s
,
{
fileName
,
startLine
,
...
...
@@ -404,17 +422,115 @@ export function compileScript(
// 2.1 process normal <script> body
if
(
script
&&
scriptAst
)
{
const
scriptScope
=
{
offset
:
script
.
loc
.
start
.
offset
,
filename
:
ctx
.
filename
,
source
:
ctx
.
descriptor
.
source
,
}
as
TypeScope
for
(
const
node
of
scriptAst
.
body
)
{
if
(
node
.
type
===
'
ExportDefaultDeclaration
'
)
{
ctx
.
error
(
`When <script> and <script setup> are used together, export default is not supported within <script>.`
,
node
)
if
(
!
options
.
scriptAndScriptSetup
)
{
ctx
.
error
(
`When <script> and <script setup> are used together, export default is not supported within <script>.`
,
node
,
scriptScope
)
}
else
{
// export default
defaultExport
=
node
// check if user has manually specified `name` or 'render` option in
// export default
// if has name, skip name inference
// if has render and no template, generate return object instead of
// empty render function (#4980)
let
optionProperties
if
(
defaultExport
.
declaration
.
type
===
'
ObjectExpression
'
)
{
optionProperties
=
defaultExport
.
declaration
.
properties
}
else
if
(
defaultExport
.
declaration
.
type
===
'
CallExpression
'
&&
defaultExport
.
declaration
.
arguments
[
0
]
&&
defaultExport
.
declaration
.
arguments
[
0
].
type
===
'
ObjectExpression
'
)
{
optionProperties
=
defaultExport
.
declaration
.
arguments
[
0
].
properties
}
if
(
optionProperties
)
{
for
(
const
p
of
optionProperties
)
{
if
(
p
.
type
===
'
ObjectProperty
'
&&
p
.
key
.
type
===
'
Identifier
'
&&
p
.
key
.
name
===
'
name
'
)
{
ctx
.
hasDefaultExportName
=
true
}
if
(
(
p
.
type
===
'
ObjectMethod
'
||
p
.
type
===
'
ObjectProperty
'
)
&&
p
.
key
.
type
===
'
Identifier
'
&&
p
.
key
.
name
===
'
render
'
)
{
// TODO warn when we provide a better way to do it?
ctx
.
hasDefaultExportRender
=
true
}
}
}
// export default { ... } --> const __default__ = { ... }
const
start
=
node
.
start
!
+
scriptStartOffset
!
const
end
=
node
.
declaration
.
start
!
+
scriptStartOffset
!
ctx
.
s
.
overwrite
(
start
,
end
,
`const
${
normalScriptDefaultVar
}
= `
)
}
}
else
if
(
node
.
type
===
'
ExportNamedDeclaration
'
)
{
ctx
.
error
(
`When <script> and <script setup> are used together, export is not supported within <script>.`
,
node
)
if
(
!
options
.
scriptAndScriptSetup
)
{
ctx
.
error
(
`When <script> and <script setup> are used together, export is not supported within <script>.`
,
node
,
scriptScope
)
}
else
{
const
defaultSpecifier
=
node
.
specifiers
.
find
(
(
s
)
=>
s
.
exported
.
type
===
'
Identifier
'
&&
s
.
exported
.
name
===
'
default
'
)
as
ExportSpecifier
if
(
defaultSpecifier
)
{
defaultExport
=
node
// 1. remove specifier
if
(
node
.
specifiers
.
length
>
1
)
{
ctx
.
s
.
remove
(
defaultSpecifier
.
start
!
+
scriptStartOffset
!
,
defaultSpecifier
.
end
!
+
scriptStartOffset
!
)
}
else
{
ctx
.
s
.
remove
(
node
.
start
!
+
scriptStartOffset
!
,
node
.
end
!
+
scriptStartOffset
!
)
}
if
(
node
.
source
)
{
// export { x as default } from './x'
// rewrite to `import { x as __default__ } from './x'` and
// add to top
ctx
.
s
.
prepend
(
`import {
${
defaultSpecifier
.
local
.
name
}
as
${
normalScriptDefaultVar
}
} from '
${
node
.
source
.
value
}
'\n`
)
}
else
{
// export { x as default }
// rewrite to `const __default__ = x` and move to end
ctx
.
s
.
appendLeft
(
scriptEndOffset
!
,
`\nconst
${
normalScriptDefaultVar
}
=
${
defaultSpecifier
.
local
.
name
}
\n`
)
}
}
if
(
node
.
declaration
)
{
walkDeclaration
(
'
script
'
,
node
.
declaration
,
scriptBindings
,
vueImportAliases
,
hoistStatic
)
}
}
}
else
if
(
(
node
.
type
===
'
VariableDeclaration
'
||
node
.
type
===
'
FunctionDeclaration
'
||
...
...
@@ -855,9 +971,9 @@ __ins.emit(event, ...do_not_transform_spread)
startOffset
,
`\n
${
genDefaultAs
}
{
${
runtimeOptions
}
\n `
+
`
${
hasAwait
?
`async `
:
``
}
setup(
${
args
}
) {
const __ins = getCurrentInstance()!
const _ctx = __ins.proxy
as
${
options
.
className
}
const _cache = __ins.renderCache
const __ins = getCurrentInstance()!
;
const _ctx = __ins.proxy
${
options
.
className
?
` as
${
options
.
className
}
`
:
''
}
;
const _cache = __ins.renderCache
;
${
exposeCall
}
`
)
ctx
.
s
.
appendRight
(
endOffset
,
`}`
)
...
...
packages/uni-app-uts/src/plugins/android/uvue/sfc/main.ts
浏览文件 @
0c535ff4
...
...
@@ -16,7 +16,7 @@ import {
parseUTSComponent
,
removeExt
,
}
from
'
@dcloudio/uni-cli-shared
'
import
type
{
Position
}
from
'
@vue/compiler-core
'
import
type
{
BindingMetadata
,
Position
}
from
'
@vue/compiler-core
'
import
type
{
ImportSpecifier
}
from
'
es-module-lexer
'
import
{
createDescriptor
,
setSrcDescriptor
}
from
'
../descriptorCache
'
import
{
resolveScript
}
from
'
./script
'
...
...
@@ -58,7 +58,11 @@ export async function transformMain(
const
className
=
genClassName
(
relativeFileName
)
// script
const
{
code
:
scriptCode
,
map
:
scriptMap
}
=
await
genScriptCode
(
descriptor
,
{
const
{
code
:
scriptCode
,
map
:
scriptMap
,
bindingMetadata
,
}
=
await
genScriptCode
(
descriptor
,
{
...
options
,
className
,
})
...
...
@@ -79,6 +83,7 @@ export async function transformMain(
inline
:
isInline
,
rootDir
:
process
.
env
.
UNI_INPUT_DIR
,
sourceMap
:
process
.
env
.
NODE_ENV
===
'
development
'
,
bindingMetadata
,
})
)
...
...
@@ -228,6 +233,7 @@ async function genScriptCode(
):
Promise
<
{
code
:
string
map
:
RawSourceMap
|
undefined
bindingMetadata
?:
BindingMetadata
}
>
{
let
scriptCode
=
`export default {}`
let
map
:
RawSourceMap
|
undefined
...
...
@@ -240,6 +246,7 @@ async function genScriptCode(
return
{
code
:
scriptCode
,
map
,
bindingMetadata
:
script
?.
bindings
,
}
}
...
...
packages/uni-app-uts/src/plugins/android/uvue/sfc/template.ts
浏览文件 @
0c535ff4
import
type
{
BindingMetadata
,
CompilerOptions
,
SFCDescriptor
,
SFCTemplateCompileOptions
,
...
...
@@ -26,6 +27,7 @@ export function resolveGenTemplateCodeOptions(
inline
:
boolean
rootDir
:
string
sourceMap
:
boolean
bindingMetadata
?:
BindingMetadata
}
):
TemplateCompilerOptions
{
const
inputRoot
=
normalizePath
(
options
.
rootDir
)
...
...
@@ -35,7 +37,6 @@ export function resolveGenTemplateCodeOptions(
...
options
,
filename
:
relativeFileName
,
className
,
prefixIdentifiers
:
!
options
.
inline
,
inMap
:
descriptor
.
template
?.
map
,
matchEasyCom
:
(
tag
,
uts
)
=>
{
const
source
=
matchEasycom
(
tag
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录