Skip to content

Commit 0f52a71

Browse files
committed
feat: implement delete-key-attribute transformation
1 parent b92b2c7 commit 0f52a71

File tree

4 files changed

+107
-0
lines changed

4 files changed

+107
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { runTest } from '../../src/testUtils'
2+
3+
runTest(
4+
'Delete the key attribute at the same level as if/else/else-if ',
5+
'v-else-if-key',
6+
'v-else-if-key',
7+
'vue',
8+
'vue'
9+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<template>
2+
<div id="app">
3+
<div v-if="condition" key="yes">Yes</div>
4+
<div v-else-if="condition1" key="no">No</div>
5+
<div v-else key="no">No</div>
6+
</div>
7+
</template>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<template>
2+
<div id="app">
3+
<div v-if="condition" >Yes</div>
4+
<div v-else-if="condition1" >No</div>
5+
<div v-else >No</div>
6+
</div>
7+
</template>

vue-transformations/v-else-if-key.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import * as OperationUtils from '../src/operationUtils'
2+
import * as parser from 'vue-eslint-parser'
3+
import type { Node } from 'vue-eslint-parser/ast/nodes'
4+
import type { Operation } from '../src/operationUtils'
5+
import type { VueASTTransformation } from '../src/wrapVueTransformation'
6+
import wrap from '../src/wrapVueTransformation'
7+
8+
/**
9+
* 每一个实际的规则,需要做以下几件事:
10+
* 1、findNodes(fileInfo, ast): 寻找匹配规则的节点
11+
* 2、fix(nodes): 完善匹配节点的增删改逻辑
12+
* 3、applyFix(fileInfo, tempFixes): 执行fixer,对源码进行增删改,并返回转换后的代码
13+
* @param context
14+
*/
15+
16+
export const transformAST: VueASTTransformation = (context) => {
17+
let fixOperations: Operation[] = []
18+
const toFixNodes: Node[] = findNodes(context)
19+
toFixNodes.forEach((node) => {
20+
// fix(node) 返回的为 Operation 数组,因此用 concat 合并多个数组
21+
fixOperations = fixOperations.concat(fix(node))
22+
})
23+
return fixOperations
24+
}
25+
26+
export default wrap(transformAST)
27+
/**
28+
* 定位 slot attribute 节点
29+
*
30+
* @param context { file: FileInfo, api: API }
31+
* @param templateBody
32+
* @returns 所有的 slot attribute 节点
33+
*/
34+
function findNodes(context: any): Node[] {
35+
const { file } = context
36+
const source = file.source
37+
const options = { sourceType: 'module' }
38+
const ast = parser.parse(source, options)
39+
let toFixNodes: Node[] = []
40+
let root: Node = <Node>ast.templateBody // 强制类型转换
41+
parser.AST.traverseNodes(root, {
42+
enterNode(node: Node) {
43+
if (
44+
node.type === 'VAttribute' &&
45+
node.key.type === 'VIdentifier' &&
46+
node.key.name === 'key'
47+
) {
48+
toFixNodes.push(node)
49+
}
50+
},
51+
leaveNode(node: Node) {},
52+
})
53+
return toFixNodes
54+
}
55+
/**
56+
* The repair logic for
57+
* @param node The Target Node
58+
*/
59+
function fix(node: any): Operation[] {
60+
let fixOperations: Operation[] = []
61+
const target: any = node!.parent!.parent
62+
63+
// The current node has no attribute that is v-for
64+
let havaBrotherAttr: boolean = false
65+
target.startTag.attributes
66+
.filter(
67+
(attr: any) =>
68+
attr.type === 'VAttribute' &&
69+
attr.key.type === 'VDirectiveKey' &&
70+
(attr.key.name.name === 'if' ||
71+
attr.key.name.name === 'else-if' ||
72+
attr.key.name.name === 'else')
73+
)
74+
.forEach((element: any) => {
75+
havaBrotherAttr = true
76+
})
77+
if (!havaBrotherAttr) {
78+
return fixOperations
79+
}
80+
81+
fixOperations.push(OperationUtils.remove(node))
82+
83+
return fixOperations
84+
}

0 commit comments

Comments
 (0)