Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MuGuiLin
uni-app
提交
34d1e5e1
U
uni-app
项目概览
MuGuiLin
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
34d1e5e1
编写于
10月 14, 2021
作者:
fxy060608
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip(mp): v-bind:style object syntax
上级
c211db8b
变更
12
显示空白变更内容
内联
并排
Showing
12 changed file
with
895 addition
and
255 deletion
+895
-255
packages/uni-mp-compiler/__tests__/class.spec.ts
packages/uni-mp-compiler/__tests__/class.spec.ts
+97
-6
packages/uni-mp-compiler/__tests__/style.spec.ts
packages/uni-mp-compiler/__tests__/style.spec.ts
+146
-0
packages/uni-mp-compiler/__tests__/test.spec.ts
packages/uni-mp-compiler/__tests__/test.spec.ts
+3
-3
packages/uni-mp-compiler/src/ast.ts
packages/uni-mp-compiler/src/ast.ts
+2
-31
packages/uni-mp-compiler/src/runtimeHelpers.ts
packages/uni-mp-compiler/src/runtimeHelpers.ts
+2
-0
packages/uni-mp-compiler/src/transforms/transformClass.ts
packages/uni-mp-compiler/src/transforms/transformClass.ts
+217
-0
packages/uni-mp-compiler/src/transforms/transformIdentifier.ts
...ges/uni-mp-compiler/src/transforms/transformIdentifier.ts
+29
-213
packages/uni-mp-compiler/src/transforms/transformKey.ts
packages/uni-mp-compiler/src/transforms/transformKey.ts
+25
-0
packages/uni-mp-compiler/src/transforms/transformStyle.ts
packages/uni-mp-compiler/src/transforms/transformStyle.ts
+217
-0
packages/uni-mp-compiler/src/transforms/utils.ts
packages/uni-mp-compiler/src/transforms/utils.ts
+155
-0
packages/uni-mp-compiler/src/transforms/vIf.ts
packages/uni-mp-compiler/src/transforms/vIf.ts
+1
-2
packages/uni-mp-vue/src/index.ts
packages/uni-mp-vue/src/index.ts
+1
-0
未找到文件。
packages/uni-mp-compiler/__tests__/class.spec.ts
浏览文件 @
34d1e5e1
...
...
@@ -29,14 +29,30 @@ describe('compiler: transform class', () => {
`<view :class="foo"/>`
,
`<view class="{{a}}"/>`
,
`(_ctx, _cache) => {
return { a: _
ctx.foo
}
return { a: _
normalizeClass(_ctx.foo)
}
}`
)
assert
(
`<view :class="foo | bar"/>`
,
`<view class="{{a}}"/>`
,
`(_ctx, _cache) => {
return { a: _ctx.foo | _ctx.bar }
return { a: _normalizeClass(_ctx.foo | _ctx.bar) }
}`
)
})
test
(
'
v-bind:class basic + class
'
,
()
=>
{
assert
(
`<view :class="foo" class="bar"/>`
,
`<view class="{{[a, 'bar']}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeClass(_ctx.foo) }
}`
)
assert
(
`<view class="bar" :class="foo"/>`
,
`<view class="{{['bar', a]}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeClass(_ctx.foo) }
}`
)
})
...
...
@@ -49,12 +65,87 @@ describe('compiler: transform class', () => {
}`
)
assert
(
`<view :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1 }"/>`
,
`<view class="{{['a', 'c', a && 'g', b && 'h', c && 'i']}}"/>`
,
`<view :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }"/>`
,
`<view class="{{['a', 'c', a && 'g', b && 'h', c && 'i', d && 'j', e, g && f, h, i, j]}}"/>`
,
`(_ctx, _cache) => {
return { a: _ctx.ok, b: _ctx.handle(_ctx.ok), c: _ctx.ok > 1, d: _ctx.j, e: _ctx.k, f: _ctx.l, g: _ctx.m, h: _normalizeClass(_ctx.n), i: _normalizeClass({ a: true }), j: _normalizeClass({ b: _ctx.o }) }
}`
)
})
test
(
'
v-bind:class object syntax + class
'
,
()
=>
{
assert
(
`<view :class="{ red: isRed }" class="foo bar"/>`
,
`<view class="{{[a && 'red', 'foo bar']}}"/>`
,
`(_ctx, _cache) => {
return { a: _ctx.isRed }
}`
)
assert
(
`<view class="foo bar" :class="{ red: isRed }"/>`
,
`<view class="{{['foo bar', a && 'red']}}"/>`
,
`(_ctx, _cache) => {
return { a: _ctx.isRed }
}`
)
assert
(
`<view :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }" class="foo bar"/>`
,
`<view class="{{['a', 'c', a && 'g', b && 'h', c && 'i', d && 'j', e, g && f, h, i, j, 'foo bar']}}"/>`
,
`(_ctx, _cache) => {
return { a: _ctx.ok, b: _ctx.handle(_ctx.ok), c: _ctx.ok > 1, d: _ctx.j, e: _ctx.k, f: _ctx.l, g: _ctx.m, h: _normalizeClass(_ctx.n), i: _normalizeClass({ a: true }), j: _normalizeClass({ b: _ctx.o }) }
}`
)
assert
(
`<view class="foo bar" :class="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }"/>`
,
`<view class="{{['foo bar', 'a', 'c', a && 'g', b && 'h', c && 'i', d && 'j', e, g && f, h, i, j]}}"/>`
,
`(_ctx, _cache) => {
return { a: _ctx.ok, b: _ctx.handle(_ctx.ok), c: _ctx.ok > 1, d: _ctx.j, e: _ctx.k, f: _ctx.l, g: _ctx.m, h: _normalizeClass(_ctx.n), i: _normalizeClass({ a: true }), j: _normalizeClass({ b: _ctx.o }) }
}`
)
})
test
(
'
v-bind:class array syntax
'
,
()
=>
{
assert
(
`<view :class="[classA, classB]"/>`
,
`<view class="{{[a, b]}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB) }
}`
)
assert
(
`<view :class="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]"/>`
,
`<view class="{{[a, b, c, 'classE', d, e, f, g, h]}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB), c: _normalizeClass({ classC: _ctx.isC, classD: _ctx.isD }), d: _normalizeClass(_ctx.isF ? 'classF' : ''), e: _normalizeClass(_ctx.isG && 'classG'), f: _normalizeClass(_ctx.classH), g: _normalizeClass([_ctx.classI, _ctx.classJ]), h: _normalizeClass(_ctx.handle(_ctx.classK)) }
}`
)
})
test
(
'
v-bind:class array syntax + class
'
,
()
=>
{
assert
(
`<view :class="[classA, classB]" class="foo bar"/>`
,
`<view class="{{[a, b, 'foo bar']}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB) }
}`
)
assert
(
`<view class="foo bar" :class="[classA, classB]"/>`
,
`<view class="{{['foo bar', a, b]}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB) }
}`
)
assert
(
`<view :class="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]" class="foo bar"/>`
,
`<view class="{{[a, b, c, 'classE', d, e, f, g, h, 'foo bar']}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB), c: _normalizeClass({ classC: _ctx.isC, classD: _ctx.isD }), d: _normalizeClass(_ctx.isF ? 'classF' : ''), e: _normalizeClass(_ctx.isG && 'classG'), f: _normalizeClass(_ctx.classH), g: _normalizeClass([_ctx.classI, _ctx.classJ]), h: _normalizeClass(_ctx.handle(_ctx.classK)) }
}`
)
assert
(
`<view class="foo bar" :class="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]"/>`
,
`<view class="{{['foo bar', a, b, c, 'classE', d, e, f, g, h]}}"/>`
,
`(_ctx, _cache) => {
return { a: _
ctx.ok, b: _ctx.handle(_ctx.ok), c: _ctx.ok > 1
}
return { a: _
normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB), c: _normalizeClass({ classC: _ctx.isC, classD: _ctx.isD }), d: _normalizeClass(_ctx.isF ? 'classF' : ''), e: _normalizeClass(_ctx.isG && 'classG'), f: _normalizeClass(_ctx.classH), g: _normalizeClass([_ctx.classI, _ctx.classJ]), h: _normalizeClass(_ctx.handle(_ctx.classK))
}
}`
)
})
test
(
'
v-bind:class array syntax
'
,
()
=>
{})
})
packages/uni-mp-compiler/__tests__/style.spec.ts
0 → 100644
浏览文件 @
34d1e5e1
import
{
assert
}
from
'
./testUtils
'
describe
(
'
compiler: transform style
'
,
()
=>
{
test
(
`static style`
,
()
=>
{
assert
(
`<view style="color: green"/>`
,
`<view style="color: green"/>`
,
`(_ctx, _cache) => {
return {}
}`
)
assert
(
`<view style="color: green;font-size: 15px"/>`
,
`<view style="color: green;font-size: 15px"/>`
,
`(_ctx, _cache) => {
return {}
}`
)
})
test
(
'
v-bind:style basic
'
,
()
=>
{
assert
(
`<view :style="foo"/>`
,
`<view style="{{a}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeStyle(_ctx.foo) }
}`
)
assert
(
`<view :style="foo | bar"/>`
,
`<view style="{{a}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeStyle(_ctx.foo | _ctx.bar) }
}`
)
})
test
(
'
v-bind:style basic + style
'
,
()
=>
{
assert
(
`<view :style="foo" style="color:green;"/>`
,
`<view style="{{a + ';' + 'color:green;'}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeStyle(_ctx.foo) }
}`
)
assert
(
`<view style="color:green;" :style="foo"/>`
,
`<view style="{{'color:green;' + ';' + a}}"/>`
,
`(_ctx, _cache) => {
return { a: _normalizeStyle(_ctx.foo) }
}`
)
})
test
(
'
v-bind:style object syntax
'
,
()
=>
{
assert
(
`<view :style="{ color: 'green' }"/>`
,
`<view style="{{'color:' + 'green'}}"/>`
,
`(_ctx, _cache) => {
return {}
}`
)
// 暂不支持数组,用的较少
// display:['-webkit-box', '-ms-flexbox', 'flex']
assert
(
`<view :style="{color:'green',fontSize:'15px',backgroundColor: handle(bg),fontWeight,[padding]:box.padding,...style,...{margin:'0px'}}"/>`
,
`<view style="{{'color:' + 'green' + ';' + ('font-size:' + '15px') + ';' + ('background-color:' + a) + ';' + ('font-weight:' + b) + ';' + (c + ':' + d) + ';' + e + ';' + f}}"/>`
,
`(_ctx, _cache) => {
return { a: _ctx.handle(_ctx.bg), b: _ctx.fontWeight, c: _hyphenate(_ctx.padding), d: _ctx.box.padding, e: _normalizeStyle(_ctx.style), f: _normalizeStyle({ margin: '0px' }) }
}`
)
})
// test('v-bind:style object syntax + style', () => {
// assert(
// `<view :style="{ red: isRed }" style="foo bar"/>`,
// `<view style="{{[a && 'red', 'foo bar']}}"/>`,
// `(_ctx, _cache) => {
// return { a: _ctx.isRed }
// }`
// )
// assert(
// `<view style="foo bar" :style="{ red: isRed }"/>`,
// `<view style="{{['foo bar', a && 'red']}}"/>`,
// `(_ctx, _cache) => {
// return { a: _ctx.isRed }
// }`
// )
// assert(
// `<view :style="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }" style="foo bar"/>`,
// `<view style="{{['a', 'c', a && 'g', b && 'h', c && 'i', d && 'j', e, g && f, h, i, j, 'foo bar']}}"/>`,
// `(_ctx, _cache) => {
// return { a: _ctx.ok, b: _ctx.handle(_ctx.ok), c: _ctx.ok > 1, d: _ctx.j, e: _ctx.k, f: _ctx.l, g: _ctx.m, h: _normalizeClass({ ..._ctx.n }), i: _normalizeClass({ ...{ a: true } }), j: _normalizeClass({ ...{ b: _ctx.o } }) }
// }`
// )
// assert(
// `<view style="foo bar" :style="{ a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1, j, [k]:1, [l]:m, ...n, ...{a:true}, ...{b:o} }"/>`,
// `<view style="{{['foo bar', 'a', 'c', a && 'g', b && 'h', c && 'i', d && 'j', e, g && f, h, i, j]}}"/>`,
// `(_ctx, _cache) => {
// return { a: _ctx.ok, b: _ctx.handle(_ctx.ok), c: _ctx.ok > 1, d: _ctx.j, e: _ctx.k, f: _ctx.l, g: _ctx.m, h: _normalizeClass({ ..._ctx.n }), i: _normalizeClass({ ...{ a: true } }), j: _normalizeClass({ ...{ b: _ctx.o } }) }
// }`
// )
// })
// test('v-bind:style array syntax', () => {
// assert(
// `<view :style="[classA, classB]"/>`,
// `<view style="{{[a, b]}}"/>`,
// `(_ctx, _cache) => {
// return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB) }
// }`
// )
// assert(
// `<view :style="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]"/>`,
// `<view style="{{[a, b, c, 'classE', d, e, f, g, h]}}"/>`,
// `(_ctx, _cache) => {
// return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB), c: _normalizeClass({ classC: _ctx.isC, classD: _ctx.isD }), d: _normalizeClass(_ctx.isF ? 'classF' : ''), e: _normalizeClass(_ctx.isG && 'classG'), f: _normalizeClass([..._ctx.classH]), g: _normalizeClass([...[_ctx.classI, _ctx.classJ]]), h: _normalizeClass(_ctx.handle(_ctx.classK)) }
// }`
// )
// })
// test('v-bind:style array syntax + style', () => {
// assert(
// `<view :style="[classA, classB]" style="foo bar"/>`,
// `<view style="{{[a, b, 'foo bar']}}"/>`,
// `(_ctx, _cache) => {
// return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB) }
// }`
// )
// assert(
// `<view style="foo bar" :style="[classA, classB]"/>`,
// `<view style="{{['foo bar', a, b]}}"/>`,
// `(_ctx, _cache) => {
// return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB) }
// }`
// )
// assert(
// `<view :style="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]" style="foo bar"/>`,
// `<view style="{{[a, b, c, 'classE', d, e, f, g, h, 'foo bar']}}"/>`,
// `(_ctx, _cache) => {
// return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB), c: _normalizeClass({ classC: _ctx.isC, classD: _ctx.isD }), d: _normalizeClass(_ctx.isF ? 'classF' : ''), e: _normalizeClass(_ctx.isG && 'classG'), f: _normalizeClass([..._ctx.classH]), g: _normalizeClass([...[_ctx.classI, _ctx.classJ]]), h: _normalizeClass(_ctx.handle(_ctx.classK)) }
// }`
// )
// assert(
// `<view style="foo bar" :style="[classA, classB, { classC: isC, classD: isD }, 'classE', isF ? 'classF' : '', isG && 'classG', ...classH, ...[classI,classJ], handle(classK) ]"/>`,
// `<view style="{{['foo bar', a, b, c, 'classE', d, e, f, g, h]}}"/>`,
// `(_ctx, _cache) => {
// return { a: _normalizeClass(_ctx.classA), b: _normalizeClass(_ctx.classB), c: _normalizeClass({ classC: _ctx.isC, classD: _ctx.isD }), d: _normalizeClass(_ctx.isF ? 'classF' : ''), e: _normalizeClass(_ctx.isG && 'classG'), f: _normalizeClass([..._ctx.classH]), g: _normalizeClass([...[_ctx.classI, _ctx.classJ]]), h: _normalizeClass(_ctx.handle(_ctx.classK)) }
// }`
// )
// })
})
packages/uni-mp-compiler/__tests__/test.spec.ts
浏览文件 @
34d1e5e1
...
...
@@ -33,10 +33,10 @@ function assert(
describe
(
'
compiler
'
,
()
=>
{
test
(
'
should wrap as function if expression is inline statement
'
,
()
=>
{
assert
(
`<view :class="{
a: 1, b: 0, c: true, d: false, e: null, f: undefined, g: ok, h: handle(ok), i: ok>1
}"/>`
,
`<view class="{{[
'a', 'c', a && 'g', b && 'h', c && 'i'
]}}"/>`
,
`<view :class="{
...{red:red}
}"/>`
,
`<view class="{{[
a
]}}"/>`
,
`(_ctx, _cache) => {
return { a: _
ctx.ok, b: _ctx.handle(_ctx.ok), c: _ctx.ok > 1
}
return { a: _
normalizeClass({ red: _ctx.red })
}
}`
,
{}
)
...
...
packages/uni-mp-compiler/src/ast.ts
浏览文件 @
34d1e5e1
...
...
@@ -23,17 +23,14 @@ import {
Pattern
,
RestElement
,
ArrowFunctionExpression
,
logicalExpression
,
stringLiteral
,
StringLiteral
,
isIdentifier
,
isStringLiteral
,
isLiteral
,
isBooleanLiteral
,
isBigIntLiteral
,
isDecimalLiteral
,
Literal
,
LogicalExpression
,
isNullLiteral
,
}
from
'
@babel/types
'
import
{
...
...
@@ -167,37 +164,11 @@ function createVForArrowFunctionExpression({
)
}
export
function
createClassBindingArrayExpression
(
expr
:
ObjectExpression
)
{
const
elements
:
(
LogicalExpression
|
StringLiteral
)[]
=
[]
expr
.
properties
.
forEach
((
prop
)
=>
{
const
{
value
}
=
prop
as
ObjectProperty
if
(
isUndefined
(
value
as
Expression
))
{
// remove {a:undefined}
return
}
if
(
isLiteral
(
value
))
{
// {a:true,b:1,c:0} => ['a','b']
if
(
isTrueExpr
(
value
))
{
elements
.
push
(
parseStringLiteral
((
prop
as
ObjectProperty
).
key
))
}
return
}
elements
.
push
(
logicalExpression
(
'
&&
'
,
value
as
Expression
,
parseStringLiteral
((
prop
as
ObjectProperty
).
key
)
)
)
})
return
arrayExpression
(
elements
)
}
export
function
isUndefined
(
expr
:
Expression
)
{
return
isIdentifier
(
expr
)
&&
expr
.
name
===
'
undefined
'
}
function
isTrueExpr
(
expr
:
Literal
)
{
export
function
isTrueExpr
(
expr
:
Literal
)
{
if
(
isNullLiteral
(
expr
))
{
return
false
}
...
...
@@ -213,7 +184,7 @@ function isTrueExpr(expr: Literal) {
return
true
}
function
parseStringLiteral
(
export
function
parseStringLiteral
(
expr
:
Expression
|
Identifier
|
StringLiteral
|
NumericLiteral
)
{
if
(
isIdentifier
(
expr
))
{
...
...
packages/uni-mp-compiler/src/runtimeHelpers.ts
浏览文件 @
34d1e5e1
...
...
@@ -2,8 +2,10 @@ import { registerRuntimeHelpers } from '@vue/compiler-core'
export
const
V_ON
=
Symbol
(
`vOn`
)
export
const
V_FOR
=
Symbol
(
`vFor`
)
export
const
HYPHENATE
=
Symbol
(
`hyphenate`
)
registerRuntimeHelpers
({
[
V_ON
]:
'
vOn
'
,
[
V_FOR
]:
'
vFor
'
,
[
HYPHENATE
]:
'
hyphenate
'
,
})
packages/uni-mp-compiler/src/transforms/transformClass.ts
0 → 100644
浏览文件 @
34d1e5e1
import
{
Expression
,
isObjectExpression
,
isArrayExpression
,
arrayExpression
,
stringLiteral
,
ArrayExpression
,
isStringLiteral
,
identifier
,
isSpreadElement
,
ObjectExpression
,
objectProperty
,
booleanLiteral
,
isObjectProperty
,
Identifier
,
isLiteral
,
isIdentifier
,
LogicalExpression
,
logicalExpression
,
StringLiteral
,
}
from
'
@babel/types
'
import
{
DirectiveNode
,
NodeTypes
,
AttributeNode
,
createSimpleExpression
,
ExpressionNode
,
createCompoundExpression
,
NORMALIZE_CLASS
,
SourceLocation
,
}
from
'
@vue/compiler-core
'
import
{
parseExpr
,
isTrueExpr
,
isUndefined
,
parseStringLiteral
}
from
'
../ast
'
import
{
genBabelExpr
}
from
'
../codegen
'
import
{
TransformContext
}
from
'
../transform
'
import
{
parseExprWithRewrite
,
rewriteExpression
,
rewriteSpreadElement
,
}
from
'
./utils
'
export
function
isClassBinding
({
arg
,
exp
}:
DirectiveNode
)
{
return
(
arg
&&
arg
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
arg
.
content
===
'
class
'
)
}
export
function
findStaticClassIndex
(
props
:
(
AttributeNode
|
DirectiveNode
)[])
{
return
props
.
findIndex
((
prop
)
=>
prop
.
name
===
'
class
'
)
}
export
function
rewriteClass
(
index
:
number
,
classBindingProp
:
DirectiveNode
,
props
:
(
AttributeNode
|
DirectiveNode
)[],
context
:
TransformContext
)
{
if
(
!
classBindingProp
.
exp
)
{
return
}
const
expr
=
parseExpr
(
classBindingProp
.
exp
,
context
)
if
(
!
expr
)
{
return
}
let
classBidingExpr
:
Expression
=
expr
if
(
isObjectExpression
(
expr
))
{
classBidingExpr
=
createClassBindingByObjectExpression
(
rewriteClassObjectExpression
(
expr
,
classBindingProp
.
loc
,
context
)
)
}
else
if
(
isArrayExpression
(
expr
))
{
classBidingExpr
=
createClassBindingByArrayExpression
(
rewriteClassArrayExpression
(
expr
,
context
)
)
}
else
{
classBidingExpr
=
parseExpr
(
rewriteClassExpression
(
classBindingProp
.
exp
,
context
).
content
,
context
)
as
Expression
}
const
staticClassPropIndex
=
findStaticClassIndex
(
props
)
if
(
staticClassPropIndex
>
-
1
)
{
const
staticClass
=
(
props
[
staticClassPropIndex
]
as
AttributeNode
).
value
!
.
content
if
(
staticClass
.
trim
())
{
if
(
!
isArrayExpression
(
classBidingExpr
))
{
classBidingExpr
=
arrayExpression
([
classBidingExpr
])
}
if
(
index
>
staticClassPropIndex
)
{
classBidingExpr
.
elements
.
unshift
(
stringLiteral
(
staticClass
))
}
else
{
classBidingExpr
.
elements
.
push
(
stringLiteral
(
staticClass
))
}
}
}
classBindingProp
.
exp
=
createSimpleExpression
(
genBabelExpr
(
classBidingExpr
))
}
function
rewriteClassExpression
(
expr
:
ExpressionNode
,
context
:
TransformContext
)
{
return
rewriteExpression
(
createCompoundExpression
([
context
.
helperString
(
NORMALIZE_CLASS
)
+
'
(
'
,
expr
,
'
)
'
,
]),
context
)
}
function
rewriteClassArrayExpression
(
expr
:
ArrayExpression
,
context
:
TransformContext
)
{
expr
.
elements
.
forEach
((
prop
,
index
)
=>
{
if
(
!
isStringLiteral
(
prop
))
{
const
code
=
genBabelExpr
(
arrayExpression
([
isSpreadElement
(
prop
)
?
prop
.
argument
:
prop
])
)
expr
.
elements
[
index
]
=
identifier
(
rewriteClassExpression
(
createSimpleExpression
(
code
.
slice
(
1
,
-
1
),
false
),
context
).
content
)
}
})
return
expr
}
function
rewriteClassObjectExpression
(
expr
:
ObjectExpression
,
loc
:
SourceLocation
,
context
:
TransformContext
)
{
expr
.
properties
.
forEach
((
prop
,
index
)
=>
{
if
(
isSpreadElement
(
prop
))
{
// <view :class="{...obj}"/>
// <view class="{{[a]}}"/>
const
newExpr
=
rewriteSpreadElement
(
NORMALIZE_CLASS
,
prop
,
loc
,
context
)
if
(
newExpr
)
{
expr
.
properties
[
index
]
=
objectProperty
(
newExpr
,
booleanLiteral
(
true
),
true
)
}
}
else
if
(
isObjectProperty
(
prop
))
{
const
{
key
,
value
,
computed
}
=
prop
if
(
computed
)
{
// {[handle(computedKey)]:1} => {[a]:1}
prop
.
key
=
parseExprWithRewrite
(
genBabelExpr
(
key
as
Expression
),
loc
,
context
,
key
as
Expression
)
as
Identifier
}
if
(
isLiteral
(
value
))
{
return
}
else
{
const
newExpr
=
parseExprWithRewrite
(
genBabelExpr
(
value
as
Expression
),
loc
,
context
,
value
as
Expression
)
if
(
newExpr
)
{
prop
.
value
=
newExpr
}
}
}
})
return
expr
}
function
createClassBindingByArrayExpression
(
expr
:
ArrayExpression
)
{
const
elements
:
(
StringLiteral
|
Identifier
)[]
=
[]
expr
.
elements
.
forEach
((
prop
)
=>
{
if
(
isStringLiteral
(
prop
)
||
isIdentifier
(
prop
))
{
elements
.
push
(
prop
)
}
})
return
arrayExpression
(
elements
)
}
function
createClassBindingByObjectExpression
(
expr
:
ObjectExpression
)
{
const
elements
:
(
LogicalExpression
|
StringLiteral
|
Identifier
)[]
=
[]
expr
.
properties
.
forEach
((
prop
)
=>
{
if
(
isObjectProperty
(
prop
))
{
const
{
value
}
=
prop
if
(
isUndefined
(
value
as
Expression
))
{
// remove {a:undefined}
return
}
if
(
isLiteral
(
value
))
{
// {a:true,b:1,c:0} => ['a','b']
if
(
isTrueExpr
(
value
))
{
elements
.
push
(
prop
.
computed
?
(
prop
.
key
as
Identifier
)
:
parseStringLiteral
(
prop
.
key
)
)
}
return
}
elements
.
push
(
logicalExpression
(
'
&&
'
,
value
as
Expression
,
prop
.
computed
?
prop
.
key
:
parseStringLiteral
(
prop
.
key
)
)
)
}
})
return
arrayExpression
(
elements
)
}
packages/uni-mp-compiler/src/transforms/transformIdentifier.ts
浏览文件 @
34d1e5e1
import
{
BaseNode
}
from
'
estree
'
import
{
walk
}
from
'
estree-walker
'
import
{
Expression
,
isIdentifier
,
isLiteral
,
isObjectExpression
,
isReferenced
,
ObjectExpression
,
ObjectProperty
,
stringLiteral
,
}
from
'
@babel/types
'
import
{
AttributeNode
,
createCompoundExpression
,
createSimpleExpression
,
DirectiveNode
,
ExpressionNode
,
NodeTypes
,
SimpleExpressionNode
,
SourceLocation
,
TO_DISPLAY_STRING
,
}
from
'
@vue/compiler-core
'
import
{
NodeTransform
}
from
'
../transform
'
import
{
isForElementNode
}
from
'
./vFor
'
import
{
rewriteExpression
}
from
'
./utils
'
import
{
isSelfKey
,
rewriteSelfKey
}
from
'
./transformKey
'
import
{
createClassBindingArrayExpression
,
createObjectProperty
,
isUndefined
,
parseExpr
,
}
from
'
../ast
'
import
{
genBabelExpr
,
genExpr
}
from
'
../codegen
'
import
{
CodegenScope
,
CodegenVForScope
}
from
'
../options
'
findStaticClassIndex
,
isClassBinding
,
rewriteClass
,
}
from
'
./transformClass
'
import
{
isRootScope
,
isVForScope
,
isVIfScope
,
NodeTransform
,
TransformContext
,
}
from
'
../transform
'
import
{
ForElementNode
,
isForElementNode
}
from
'
./vFor
'
findStaticStyleIndex
,
isStyleBinding
,
rewriteStyle
,
}
from
'
./transformStyle
'
export
const
transformIdentifier
:
NodeTransform
=
(
node
,
context
)
=>
{
return
()
=>
{
...
...
@@ -52,6 +33,8 @@ export const transformIdentifier: NodeTransform = (node, context) => {
}
else
if
(
node
.
type
===
NodeTypes
.
ELEMENT
)
{
const
vFor
=
isForElementNode
(
node
)
&&
node
.
vFor
const
{
props
}
=
node
let
hasClassBinding
=
false
let
hasStyleBinding
=
false
for
(
let
i
=
0
;
i
<
props
.
length
;
i
++
)
{
const
dir
=
props
[
i
]
if
(
dir
.
type
===
NodeTypes
.
DIRECTIVE
)
{
...
...
@@ -69,196 +52,29 @@ export const transformIdentifier: NodeTransform = (node, context) => {
if
(
isSelfKey
(
dir
,
vFor
))
{
rewriteSelfKey
(
dir
)
}
else
if
(
isClassBinding
(
dir
))
{
hasClassBinding
=
true
rewriteClass
(
i
,
dir
,
props
,
context
)
}
else
if
(
isStyleBinding
(
dir
))
{
hasStyleBinding
=
true
rewriteStyle
(
i
,
dir
,
props
,
context
)
}
else
{
dir
.
exp
=
rewriteExpression
(
exp
,
context
)
}
}
}
}
if
(
hasClassBinding
)
{
const
staticClassIndex
=
findStaticClassIndex
(
props
)
if
(
staticClassIndex
>
-
1
)
{
props
.
splice
(
staticClassIndex
,
1
)
}
}
}
function
isSelfKey
(
{
arg
,
exp
}:
DirectiveNode
,
vFor
:
ForElementNode
[
'
vFor
'
]
|
false
)
{
return
(
vFor
&&
arg
&&
exp
&&
arg
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
arg
.
content
===
'
key
'
&&
exp
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
exp
.
content
===
vFor
.
valueAlias
)
}
function
rewriteSelfKey
(
dir
:
DirectiveNode
)
{
;(
dir
.
exp
as
SimpleExpressionNode
).
content
=
'
*this
'
}
function
isClassBinding
({
arg
,
exp
}:
DirectiveNode
)
{
return
(
arg
&&
arg
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
arg
.
content
===
'
class
'
)
}
function
findStaticClassIndex
(
props
:
(
AttributeNode
|
DirectiveNode
)[])
{
return
props
.
findIndex
((
prop
)
=>
prop
.
name
===
'
class
'
)
}
function
rewriteClass
(
index
:
number
,
classBindingProp
:
DirectiveNode
,
props
:
(
AttributeNode
|
DirectiveNode
)[],
context
:
TransformContext
)
{
if
(
!
classBindingProp
.
exp
)
{
return
}
const
staticClassPropIndex
=
findStaticClassIndex
(
props
)
const
staticClass
=
staticClassPropIndex
>
-
1
?
(
props
[
staticClassPropIndex
]
as
AttributeNode
).
value
!
.
content
:
''
const
expr
=
parseExpr
(
classBindingProp
.
exp
,
context
)
if
(
!
expr
)
{
return
}
if
(
isObjectExpression
(
expr
))
{
// 重写{ key:value }所有的 value
rewriteObjectExpression
(
expr
,
classBindingProp
.
loc
,
context
)
const
arrExpr
=
createClassBindingArrayExpression
(
expr
)
if
(
staticClass
)
{
if
(
index
>
staticClassPropIndex
)
{
arrExpr
.
elements
.
unshift
(
stringLiteral
(
staticClass
))
}
else
{
arrExpr
.
elements
.
push
(
stringLiteral
(
staticClass
))
}
}
classBindingProp
.
exp
=
createSimpleExpression
(
genBabelExpr
(
arrExpr
))
}
else
{
classBindingProp
.
exp
=
rewriteExpression
(
classBindingProp
.
exp
,
context
)
}
}
function
rewriteObjectExpression
(
expr
:
ObjectExpression
,
loc
:
SourceLocation
,
context
:
TransformContext
)
{
expr
.
properties
.
forEach
((
prop
)
=>
{
const
{
value
}
=
prop
as
ObjectProperty
if
(
isLiteral
(
value
))
{
return
}
else
{
const
newExpr
=
parseExpr
(
rewriteExpression
(
createSimpleExpression
(
genBabelExpr
(
value
as
Expression
),
false
,
loc
),
context
,
value
as
Expression
),
context
)
if
(
newExpr
)
{
;(
prop
as
ObjectProperty
).
value
=
newExpr
}
}
})
}
export
function
rewriteExpression
(
node
:
ExpressionNode
,
context
:
TransformContext
,
babelNode
?:
Expression
,
scope
:
CodegenScope
=
context
.
currentScope
)
{
if
(
node
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
node
.
isStatic
)
{
return
node
}
if
(
!
babelNode
)
{
const
code
=
genExpr
(
node
)
babelNode
=
parseExpr
(
code
,
context
,
node
)
if
(
!
babelNode
)
{
return
createSimpleExpression
(
code
)
}
}
if
(
isUndefined
(
babelNode
))
{
return
createSimpleExpression
(
'
undefined
'
,
false
,
node
.
loc
)
if
(
hasStyleBinding
)
{
const
staticStyleIndex
=
findStaticStyleIndex
(
props
)
if
(
staticStyleIndex
>
-
1
)
{
props
.
splice
(
staticStyleIndex
,
1
)
}
scope
=
findScope
(
babelNode
,
scope
)
!
const
id
=
scope
.
id
.
next
()
scope
.
properties
.
push
(
createObjectProperty
(
id
,
babelNode
!
))
if
(
node
.
type
===
NodeTypes
.
COMPOUND_EXPRESSION
)
{
const
firstChild
=
node
.
children
[
0
]
if
(
isSimpleExpression
(
firstChild
))
{
const
content
=
firstChild
.
content
.
trim
()
if
(
scope
.
identifiers
.
includes
(
content
))
{
return
createSimpleExpression
(
content
+
'
.
'
+
id
)
}
}
}
return
createSimpleExpression
(
id
)
}
// function findReferencedScope(
// node: Expression,
// scope: CodegenScope
// ): CodegenRootScope | CodegenVForScope {
// if (isRootScope(scope)) {
// return scope
// }
// }
function
findScope
(
node
:
Expression
,
scope
:
CodegenScope
)
{
if
(
isRootScope
(
scope
)
||
isVIfScope
(
scope
))
{
return
scope
}
return
findVForScope
(
node
,
scope
)
||
scope
}
function
findVForScope
(
node
:
Expression
,
scope
:
CodegenScope
):
CodegenVForScope
|
undefined
{
if
(
isVForScope
(
scope
))
{
if
(
isReferencedScope
(
node
,
scope
))
{
return
scope
}
}
// if (scope.parent) {
// return findVForScope(node, scope.parent)
// }
}
function
isReferencedScope
(
node
:
Expression
,
scope
:
CodegenVForScope
)
{
const
knownIds
:
string
[]
=
scope
.
locals
let
referenced
=
false
walk
(
node
as
unknown
as
BaseNode
,
{
enter
(
node
:
BaseNode
,
parent
:
BaseNode
)
{
if
(
referenced
)
{
return
this
.
skip
()
}
if
(
!
isIdentifier
(
node
))
{
return
}
if
(
parent
&&
knownIds
.
includes
(
node
.
name
)
&&
isReferenced
(
node
,
parent
as
any
)
)
{
referenced
=
true
return
this
.
skip
()
}
},
})
return
referenced
}
function
isSimpleExpression
(
val
:
any
):
val
is
SimpleExpressionNode
{
return
val
.
type
&&
val
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
}
packages/uni-mp-compiler/src/transforms/transformKey.ts
0 → 100644
浏览文件 @
34d1e5e1
import
{
DirectiveNode
,
NodeTypes
,
SimpleExpressionNode
,
}
from
'
@vue/compiler-core
'
import
{
ForElementNode
}
from
'
./vFor
'
export
function
isSelfKey
(
{
arg
,
exp
}:
DirectiveNode
,
vFor
:
ForElementNode
[
'
vFor
'
]
|
false
)
{
return
(
vFor
&&
arg
&&
exp
&&
arg
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
arg
.
content
===
'
key
'
&&
exp
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
exp
.
content
===
vFor
.
valueAlias
)
}
export
function
rewriteSelfKey
(
dir
:
DirectiveNode
)
{
;(
dir
.
exp
as
SimpleExpressionNode
).
content
=
'
*this
'
}
packages/uni-mp-compiler/src/transforms/transformStyle.ts
0 → 100644
浏览文件 @
34d1e5e1
import
{
Expression
,
isObjectExpression
,
isArrayExpression
,
arrayExpression
,
stringLiteral
,
ArrayExpression
,
isStringLiteral
,
isSpreadElement
,
identifier
,
ObjectExpression
,
isLiteral
,
isObjectProperty
,
binaryExpression
,
}
from
'
@babel/types
'
import
{
DirectiveNode
,
NodeTypes
,
AttributeNode
,
createSimpleExpression
,
ExpressionNode
,
createCompoundExpression
,
NORMALIZE_STYLE
,
SourceLocation
,
}
from
'
@vue/compiler-core
'
import
{
hyphenate
}
from
'
@vue/shared
'
import
{
HYPHENATE
}
from
'
../runtimeHelpers
'
import
{
parseExpr
,
parseStringLiteral
}
from
'
../ast
'
import
{
genBabelExpr
}
from
'
../codegen
'
import
{
TransformContext
}
from
'
../transform
'
import
{
parseExprWithRewrite
,
rewirteWithHelper
,
rewriteExpression
,
rewriteSpreadElement
,
}
from
'
./utils
'
export
function
isStyleBinding
({
arg
,
exp
}:
DirectiveNode
)
{
return
(
arg
&&
arg
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
arg
.
content
===
'
style
'
)
}
export
function
findStaticStyleIndex
(
props
:
(
AttributeNode
|
DirectiveNode
)[])
{
return
props
.
findIndex
((
prop
)
=>
prop
.
name
===
'
style
'
)
}
export
function
rewriteStyle
(
index
:
number
,
styleBindingProp
:
DirectiveNode
,
props
:
(
AttributeNode
|
DirectiveNode
)[],
context
:
TransformContext
)
{
if
(
!
styleBindingProp
.
exp
)
{
return
}
const
expr
=
parseExpr
(
styleBindingProp
.
exp
,
context
)
if
(
!
expr
)
{
return
}
let
styleBidingExpr
:
Expression
|
undefined
=
expr
if
(
isObjectExpression
(
expr
))
{
styleBidingExpr
=
createStyleBindingByObjectExpression
(
rewriteStyleObjectExpression
(
expr
,
styleBindingProp
.
loc
,
context
)
)
}
else
if
(
isArrayExpression
(
expr
))
{
styleBidingExpr
=
createStyleBindingByArrayExpression
(
rewriteStyleArrayExpression
(
expr
,
context
)
)
}
else
{
styleBidingExpr
=
parseExpr
(
rewriteStyleExpression
(
styleBindingProp
.
exp
,
context
).
content
,
context
)
as
Expression
}
if
(
!
styleBidingExpr
)
{
return
}
const
staticStylePropIndex
=
findStaticStyleIndex
(
props
)
if
(
staticStylePropIndex
>
-
1
)
{
const
staticStyle
=
(
props
[
staticStylePropIndex
]
as
AttributeNode
).
value
!
.
content
if
(
staticStyle
.
trim
())
{
if
(
index
>
staticStylePropIndex
)
{
styleBidingExpr
=
binaryExpression
(
'
+
'
,
addSemicolon
(
stringLiteral
(
staticStyle
)),
styleBidingExpr
)
}
else
{
styleBidingExpr
=
binaryExpression
(
'
+
'
,
addSemicolon
(
styleBidingExpr
),
stringLiteral
(
staticStyle
)
)
}
}
}
styleBindingProp
.
exp
=
createSimpleExpression
(
genBabelExpr
(
styleBidingExpr
))
}
function
rewriteStyleExpression
(
expr
:
ExpressionNode
,
context
:
TransformContext
)
{
return
rewriteExpression
(
createCompoundExpression
([
context
.
helperString
(
NORMALIZE_STYLE
)
+
'
(
'
,
expr
,
'
)
'
,
]),
context
)
}
function
rewriteStyleArrayExpression
(
expr
:
ArrayExpression
,
context
:
TransformContext
)
{
expr
.
elements
.
forEach
((
prop
,
index
)
=>
{
if
(
!
isStringLiteral
(
prop
))
{
const
code
=
genBabelExpr
(
arrayExpression
([
prop
]))
expr
.
elements
[
index
]
=
identifier
(
rewriteStyleExpression
(
createSimpleExpression
(
isSpreadElement
(
prop
)
?
code
:
code
.
slice
(
1
,
-
1
),
false
),
context
).
content
)
}
})
return
expr
}
function
rewriteStyleObjectExpression
(
expr
:
ObjectExpression
,
loc
:
SourceLocation
,
context
:
TransformContext
)
{
expr
.
properties
.
forEach
((
prop
,
index
)
=>
{
if
(
isSpreadElement
(
prop
))
{
// <view :style="{...obj}"/>
// <view style="{{a}}"/>
const
newExpr
=
rewriteSpreadElement
(
NORMALIZE_STYLE
,
prop
,
loc
,
context
)
if
(
newExpr
)
{
prop
.
argument
=
newExpr
}
}
else
if
(
isObjectProperty
(
prop
))
{
const
{
key
,
value
,
computed
}
=
prop
if
(
computed
)
{
// {[handle(computedKey)]:1} => {[a]:1}
const
newExpr
=
rewirteWithHelper
(
HYPHENATE
,
key
,
loc
,
context
)
if
(
newExpr
)
{
prop
.
key
=
newExpr
}
}
else
{
// {fontSize:'15px'} => {'font-size':'15px'}
prop
.
key
=
parseStringLiteral
(
prop
.
key
)
prop
.
key
.
value
=
hyphenate
(
prop
.
key
.
value
)
+
'
:
'
}
if
(
isLiteral
(
value
))
{
return
}
else
{
const
newExpr
=
parseExprWithRewrite
(
genBabelExpr
(
value
as
Expression
),
loc
,
context
,
value
as
Expression
)
if
(
newExpr
)
{
prop
.
value
=
newExpr
}
}
}
})
return
expr
}
function
addSemicolon
(
expr
:
Expression
)
{
return
createBinaryExpression
(
expr
,
stringLiteral
(
'
;
'
))
}
function
createBinaryExpression
(
left
:
Expression
,
right
:
Expression
)
{
return
binaryExpression
(
'
+
'
,
left
,
right
)
}
function
createStyleBindingByArrayExpression
(
expr
:
ArrayExpression
)
{
let
result
:
Expression
|
undefined
return
result
}
function
createStyleBindingByObjectExpression
(
expr
:
ObjectExpression
)
{
let
result
:
Expression
|
undefined
function
concat
(
expr
:
Expression
)
{
if
(
!
result
)
{
result
=
expr
}
else
{
result
=
createBinaryExpression
(
addSemicolon
(
result
),
expr
)
}
}
expr
.
properties
.
forEach
((
prop
)
=>
{
if
(
isSpreadElement
(
prop
))
{
concat
(
prop
.
argument
)
}
else
if
(
isObjectProperty
(
prop
))
{
const
{
key
,
value
}
=
prop
const
expr
=
createBinaryExpression
(
isStringLiteral
(
key
)
?
key
// 之前已经补充了:
:
createBinaryExpression
(
key
,
stringLiteral
(
'
:
'
)),
value
as
Expression
)
concat
(
expr
)
}
})
return
result
}
packages/uni-mp-compiler/src/transforms/utils.ts
0 → 100644
浏览文件 @
34d1e5e1
import
{
Expression
,
Identifier
,
identifier
,
isIdentifier
,
isReferenced
,
MemberExpression
,
objectProperty
,
SpreadElement
,
}
from
'
@babel/types
'
import
{
createSimpleExpression
,
ExpressionNode
,
NodeTypes
,
SimpleExpressionNode
,
SourceLocation
,
}
from
'
@vue/compiler-core
'
import
{
walk
,
BaseNode
}
from
'
estree-walker
'
import
{
isUndefined
,
parseExpr
}
from
'
../ast
'
import
{
genBabelExpr
,
genExpr
}
from
'
../codegen
'
import
{
CodegenScope
,
CodegenVForScope
}
from
'
../options
'
import
{
isRootScope
,
isVForScope
,
isVIfScope
,
TransformContext
,
}
from
'
../transform
'
export
function
rewriteSpreadElement
(
name
:
symbol
,
expr
:
SpreadElement
,
loc
:
SourceLocation
,
context
:
TransformContext
)
{
return
rewirteWithHelper
(
name
,
expr
.
argument
,
loc
,
context
)
}
export
function
rewirteWithHelper
(
name
:
symbol
,
expr
:
Expression
,
loc
:
SourceLocation
,
context
:
TransformContext
)
{
return
parseExprWithRewrite
(
context
.
helperString
(
name
)
+
'
(
'
+
genBabelExpr
(
expr
)
+
'
)
'
,
loc
,
context
)
}
export
function
parseExprWithRewrite
(
code
:
string
,
loc
:
SourceLocation
,
context
:
TransformContext
,
node
?:
Expression
)
{
return
parseExpr
(
rewriteExpression
(
createSimpleExpression
(
code
,
false
,
loc
),
context
,
node
),
context
)
as
Identifier
|
MemberExpression
|
undefined
}
export
function
rewriteExpression
(
node
:
ExpressionNode
,
context
:
TransformContext
,
babelNode
?:
Expression
,
scope
:
CodegenScope
=
context
.
currentScope
)
{
if
(
node
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
&&
node
.
isStatic
)
{
return
node
}
if
(
!
babelNode
)
{
const
code
=
genExpr
(
node
)
babelNode
=
parseExpr
(
code
,
context
,
node
)
if
(
!
babelNode
)
{
return
createSimpleExpression
(
code
)
}
}
if
(
isUndefined
(
babelNode
))
{
return
createSimpleExpression
(
'
undefined
'
,
false
,
node
.
loc
)
}
scope
=
findScope
(
babelNode
,
scope
)
!
const
id
=
scope
.
id
.
next
()
scope
.
properties
.
push
(
objectProperty
(
identifier
(
id
),
babelNode
!
))
if
(
node
.
type
===
NodeTypes
.
COMPOUND_EXPRESSION
)
{
const
firstChild
=
node
.
children
[
0
]
if
(
isSimpleExpression
(
firstChild
))
{
const
content
=
firstChild
.
content
.
trim
()
if
(
scope
.
identifiers
.
includes
(
content
))
{
return
createSimpleExpression
(
content
+
'
.
'
+
id
)
}
}
}
return
createSimpleExpression
(
id
)
}
// function findReferencedScope(
// node: Expression,
// scope: CodegenScope
// ): CodegenRootScope | CodegenVForScope {
// if (isRootScope(scope)) {
// return scope
// }
// }
function
findScope
(
node
:
Expression
,
scope
:
CodegenScope
)
{
if
(
isRootScope
(
scope
)
||
isVIfScope
(
scope
))
{
return
scope
}
return
findVForScope
(
node
,
scope
)
||
scope
}
function
findVForScope
(
node
:
Expression
,
scope
:
CodegenScope
):
CodegenVForScope
|
undefined
{
if
(
isVForScope
(
scope
))
{
if
(
isReferencedScope
(
node
,
scope
))
{
return
scope
}
}
// if (scope.parent) {
// return findVForScope(node, scope.parent)
// }
}
function
isReferencedScope
(
node
:
Expression
,
scope
:
CodegenVForScope
)
{
const
knownIds
:
string
[]
=
scope
.
locals
let
referenced
=
false
walk
(
node
as
unknown
as
BaseNode
,
{
enter
(
node
:
BaseNode
,
parent
:
BaseNode
)
{
if
(
referenced
)
{
return
this
.
skip
()
}
if
(
!
isIdentifier
(
node
))
{
return
}
if
(
parent
&&
knownIds
.
includes
(
node
.
name
)
&&
isReferenced
(
node
,
parent
as
any
)
)
{
referenced
=
true
return
this
.
skip
()
}
},
})
return
referenced
}
function
isSimpleExpression
(
val
:
any
):
val
is
SimpleExpressionNode
{
return
val
.
type
&&
val
.
type
===
NodeTypes
.
SIMPLE_EXPRESSION
}
packages/uni-mp-compiler/src/transforms/vIf.ts
浏览文件 @
34d1e5e1
...
...
@@ -26,8 +26,7 @@ import {
import
{
CodegenScope
}
from
'
../options
'
import
{
NodeTransform
,
TransformContext
,
traverseNode
}
from
'
../transform
'
import
{
processExpression
}
from
'
./transformExpression
'
import
{
rewriteExpression
}
from
'
./transformIdentifier
'
import
{
rewriteExpression
}
from
'
./utils
'
interface
IfOptions
{
name
:
string
condition
?:
string
...
...
packages/uni-mp-vue/src/index.ts
浏览文件 @
34d1e5e1
...
...
@@ -7,5 +7,6 @@ export function createApp(rootComponent: unknown, rootProps = null) {
}
export
const
createSSRApp
=
createApp
export
*
from
'
./helpers
'
export
{
hyphenate
}
from
'
@vue/shared
'
// @ts-ignore
export
*
from
'
../lib/vue.runtime.esm.js
'
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录