Skip to content

Commit 711726c

Browse files
committed
feat: implement deprecated-slot-attribute transformation
1 parent 7c6854d commit 711726c

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

vue-transformations/slot-attribute.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { Node } from 'vue-eslint-parser/ast/nodes'
2+
import * as OperationUtils from '../src/operationUtils'
3+
import type { Operation } from '../src/operationUtils'
4+
import type { VueASTTransformation } from '../src/wrapVueTransformation'
5+
import * as parser from 'vue-eslint-parser'
6+
import wrap from '../src/wrapVueTransformation'
7+
8+
export const transformAST: VueASTTransformation = (context) => {
9+
var fixOperations: Operation[] = []
10+
const toFixNodes: Node[] = findNodes(context)
11+
toFixNodes.forEach((node) => {
12+
fixOperations = fixOperations.concat(fix(node))
13+
})
14+
return fixOperations
15+
}
16+
17+
export default wrap(transformAST)
18+
/**
19+
* search slot attribute nodes
20+
*
21+
* @param context
22+
* @param templateBody
23+
* @returns slot attribute nodes
24+
*/
25+
function findNodes(context: any): Node[] {
26+
const { file } = context
27+
const source = file.source
28+
const options = { sourceType: 'module' }
29+
const ast = parser.parse(source, options)
30+
var toFixNodes: Node[] = []
31+
var root: Node = <Node>ast.templateBody
32+
parser.AST.traverseNodes(root, {
33+
enterNode(node: Node) {
34+
if (node.type === 'VAttribute' && node.key.name === 'slot') {
35+
toFixNodes.push(node)
36+
}
37+
},
38+
leaveNode(node: Node) {},
39+
})
40+
return toFixNodes
41+
}
42+
/**
43+
* fix logic
44+
* @param fixer
45+
* @param slotAttr
46+
*/
47+
function fix(node: Node): Operation[] {
48+
var fixOperations: Operation[] = []
49+
50+
const target: any = node!.parent!.parent
51+
// @ts-ignore
52+
const slotValue: string = node!.value!.value
53+
54+
// remove v-slot:${slotValue}
55+
fixOperations.push(OperationUtils.remove(node))
56+
// add <template v-slot:${slotValue}>
57+
fixOperations.push(
58+
OperationUtils.insertTextBefore(target, `<template v-slot:${slotValue}>`)
59+
)
60+
// add </template>
61+
fixOperations.push(OperationUtils.insertTextAfter(target, `</template>`))
62+
63+
return fixOperations
64+
}

vue-transformations/slot-default.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { Node } from 'vue-eslint-parser/ast/nodes'
2+
import * as OperationUtils from '../src/operationUtils'
3+
import type { Operation } from '../src/operationUtils'
4+
import type { VueASTTransformation } from '../src/wrapVueTransformation'
5+
import * as parser from 'vue-eslint-parser'
6+
import wrap from '../src/wrapVueTransformation'
7+
8+
export const transformAST: VueASTTransformation = (context) => {
9+
var fixOperations: Operation[] = []
10+
const toFixNodes: Node[] = findNodes(context)
11+
toFixNodes.forEach((node) => {
12+
fixOperations = fixOperations.concat(fix(node))
13+
})
14+
return fixOperations
15+
}
16+
17+
export default wrap(transformAST)
18+
19+
function findNodes(context: any): Node[] {
20+
const { file } = context
21+
const source = file.source
22+
const options = { sourceType: 'module' }
23+
const ast = parser.parse(source, options)
24+
var toFixNodes: Node[] = []
25+
var root: Node = <Node>ast.templateBody
26+
parser.AST.traverseNodes(root, {
27+
enterNode(node: Node) {
28+
if (
29+
node.type === 'VAttribute' &&
30+
node.key.type === 'VDirectiveKey' &&
31+
node.key.name.name === 'slot' &&
32+
node.key.argument?.type === 'VIdentifier' &&
33+
node.key.argument?.name === 'default' &&
34+
node.parent.parent.type == 'VElement' &&
35+
node.parent.parent.name == 'template'
36+
) {
37+
toFixNodes.push(node)
38+
}
39+
},
40+
leaveNode(node: Node) {},
41+
})
42+
return toFixNodes
43+
}
44+
45+
function fix(node: Node): Operation[] {
46+
var fixOperations: Operation[] = []
47+
48+
const target: any = node!.parent!.parent
49+
const targetParent: any = target.parent
50+
51+
targetParent.children
52+
.filter((el: any) => el.type == 'VElement' && el.name != 'template')
53+
.forEach((element: any) => {
54+
fixOperations.push(OperationUtils.remove(element))
55+
})
56+
return fixOperations
57+
}

0 commit comments

Comments
 (0)