Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Dec 25, 2024. It is now read-only.

Commiteb9c5b2

Browse files
committed
feat: use @babel/traverse to get identifiers
1 parent8d785a3 commiteb9c5b2

File tree

5 files changed

+124
-111
lines changed

5 files changed

+124
-111
lines changed

‎src/core/babel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import*asbabelfrom'@babel/core'
22
import{parse,parseExpression}from'@babel/parser'
33
importgfrom'@babel/generator'
4+
import*asbabel_traversefrom'@babel/traverse'
45

56
exportconstt:typeofbabel['types']=((babelasany).default||babel).types
67
exportconstgenerate:typeofg=((gasany).default||g)
8+
exportconsttraverse=((babel_traverseasany)?.default?.defaultasnull)??babel_traverse?.default??babel_traverse
79
export{parseExpression,parse}

‎src/core/identifiers.ts

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,41 @@
1-
importtype{Expression,Node,PrivateName,SpreadElement,Statement,TSType}from'@babel/types'
1+
importtype{
2+
Expression,
3+
File,
4+
PrivateName,
5+
SpreadElement,
6+
Statement,
7+
TSType,
8+
}from'@babel/types'
9+
importtype{ParseResult}from'@babel/parser'
10+
import{t,traverse}from'./babel'
211

3-
exportfunctiongetIdentifierDeclarations(nodes:Statement[],identifiers=newSet<string>()){
4-
for(letnodeofnodes){
5-
if(node.type==='ExportNamedDeclaration'){
6-
node=node.declaration!
7-
if(!node)
8-
continue
9-
}
10-
if(node.type==='ImportDeclaration'){
11-
for(constspecifierofnode.specifiers)
12-
identifiers.add(specifier.local.name)
13-
}
14-
elseif(node.type==='VariableDeclaration'){
15-
functionhandleVariableId(node:Node){
16-
if(node.type==='Identifier'){
17-
identifiers.add(node.name)
18-
}
19-
elseif(node.type==='ObjectPattern'){
20-
for(constpropertyofnode.properties){
21-
if(property.type==='ObjectProperty')
22-
handleVariableId(property.value)
23-
elseif(property.type==='RestElement'&&property.argument.type==='Identifier')
24-
identifiers.add(property.argument.name)
25-
}
26-
}
27-
elseif(node.type==='ArrayPattern'){
28-
for(constelementofnode.elements){
29-
if(element?.type==='Identifier')
30-
identifiers.add(element.name)
31-
elseif(element?.type==='RestElement'&&element.argument.type==='Identifier')
32-
identifiers.add(element.argument.name)
33-
elseif(element?.type==='ObjectPattern'||element?.type==='ArrayPattern')
34-
handleVariableId(element)
35-
}
36-
}
12+
exportfunctiongetIdentifierDeclarations(nodes:Statement[]){
13+
letresult!:Set<string>
14+
letprogramScopeUid:number
15+
traverse(t.file(t.program(nodes)),{
16+
Program(path){
17+
result=newSet(Object.keys(path.scope.bindings))
18+
programScopeUid=(path.scopeasany).uid
19+
},
20+
// FIXME: babel bug, temporary add TSEnumDeclaration and TSModuleDeclaration logic
21+
TSEnumDeclaration(path){
22+
if((path.scopeasany).uid===programScopeUid)
23+
result.add(path.node.id.name)
24+
},
25+
TSModuleDeclaration(path){
26+
if((path.scopeasany).uid===programScopeUid){
27+
constid=path.node.id
28+
if(id.type==='Identifier')
29+
result.add(id.name)
3730
}
38-
39-
for(constdeclaratorofnode.declarations)
40-
handleVariableId(declarator.id)
41-
}
42-
elseif(node.type==='FunctionDeclaration'||node.type==='ClassDeclaration'){
43-
if(node.id)
44-
identifiers.add(node.id.name)
45-
}
46-
elseif(node.type==='TSEnumDeclaration'){
47-
if(node.id)
48-
identifiers.add(node.id.name)
49-
}
50-
// else {
51-
// console.log(node)
52-
// }
53-
}
54-
returnidentifiers
31+
},
32+
})
33+
returnArray.from(result)
5534
}
5635

36+
/**
37+
*@deprecated use `getFileGlobals` instead
38+
*/
5739
exportfunctiongetIdentifierUsages(node?:Expression|TSType|SpreadElement|PrivateName|Statement|null,identifiers=newSet<string>()){
5840
if(!node)
5941
returnidentifiers
@@ -124,3 +106,27 @@ export function getIdentifierUsages(node?: Expression | TSType | SpreadElement |
124106
// }
125107
returnidentifiers
126108
}
109+
110+
exportfunctiongetFileGlobals(result:ParseResult<File>){
111+
letglobals!:Set<string>
112+
letprogramScopeUid:number
113+
traverse(result,{
114+
Program(path){
115+
globals=newSet(Object.keys((path.scopeasany).globals))
116+
programScopeUid=(path.scopeasany).uid
117+
},
118+
// FIXME: babel bug, temporary add TSEnumDeclaration and TSModuleDeclaration logic
119+
TSEnumDeclaration(path){
120+
if((path.scopeasany).uid===programScopeUid)
121+
globals.delete(path.node.id.name)
122+
},
123+
TSModuleDeclaration(path){
124+
if((path.scopeasany).uid===programScopeUid){
125+
constid=path.node.id
126+
if(id.type==='Identifier')
127+
globals.delete(id.name)
128+
}
129+
},
130+
})
131+
returnArray.from(globals)
132+
}

‎src/core/parseSFC.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type {
1919
ScriptSetupTransformOptions,
2020
ScriptTagMeta,
2121
}from'../types'
22-
import{getIdentifierUsages}from'./identifiers'
22+
import{getFileGlobals}from'./identifiers'
2323
import{parse}from'./babel'
2424
import{exhaustiveCheckReturnUndefined,pascalize}from'./utils'
2525

@@ -137,12 +137,8 @@ function getDirectiveNames(node: TemplateChildNode): string[] {
137137
}
138138

139139
functiongetFreeVariablesForText(input:string):string[]{
140-
constidentifiers=newSet<string>()
141140
constinputWithPrefix=input.trimStart()[0]==='{' ?`(${input})` :input
142-
143-
constnodes=parse(inputWithPrefix).program.body
144-
nodes.forEach(node=>getIdentifierUsages(node,identifiers))
145-
return[...identifiers.values()]
141+
returngetFileGlobals(parse(inputWithPrefix))
146142
}
147143

148144
functiongetFreeVariablesForPropsNode(

‎src/core/transformScriptSetup.ts

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
import{capitalize}from'@vue/shared'
22
importtype{Node,ObjectExpression,Statement}from'@babel/types'
3-
import{partition}from'@antfu/utils'
3+
import{notNullish,partition,uniq}from'@antfu/utils'
44
importtype{ParsedSFC,ScriptSetupTransformOptions}from'../types'
55
import{applyMacros}from'./macros'
66
import{getIdentifierDeclarations}from'./identifiers'
77
import{generate,t}from'./babel'
8-
import{isNotNil,pascalize}from'./utils'
8+
import{pascalize}from'./utils'
99

10-
functionisAsyncImport(node:any){
11-
if(node.type==='VariableDeclaration'){
10+
functionisAsyncImport(node:Statement){
11+
if(t.isVariableDeclaration(node)){
1212
constdeclaration=node.declarations[0]
1313

14-
returndeclaration?.init?.callee?.name==='defineAsyncComponent'
14+
return(
15+
declaration!==undefined
16+
&&t.isCallExpression(declaration.init)
17+
&&t.isIdentifier(declaration.init.callee)
18+
&&declaration.init.callee.name==='defineAsyncComponent'
19+
)
1520
}
1621

1722
returnfalse
1823
}
1924

20-
exportfunctiontransformScriptSetup(sfc:ParsedSFC,options?:ScriptSetupTransformOptions){
25+
exportfunctiontransformScriptSetup(
26+
sfc:ParsedSFC,
27+
options?:ScriptSetupTransformOptions,
28+
){
2129
const{ scriptSetup, script, template}=sfc
2230

2331
const{nodes:body, props, expose}=applyMacros(scriptSetup.ast.body)
@@ -26,16 +34,17 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
2634
body,
2735
n=>
2836
isAsyncImport(n)
29-
||n.type==='ImportDeclaration'
30-
||n.type==='ExportNamedDeclaration'
31-
||n.type.startsWith('TS'),
37+
||t.isImportDeclaration(n)
38+
||t.isExportNamedDeclaration(n)
39+
||n.type.startsWith('TS'),
3240
)
3341

3442
// get all identifiers in `<script setup>`
35-
constdeclarations=newSet<string>()
36-
getIdentifierDeclarations(hoisted,declarations)
37-
getIdentifierDeclarations(setupBody,declarations)
38-
constdeclarationArray=Array.from(declarations).filter(isNotNil)
43+
constdeclarations=[
44+
...getIdentifierDeclarations(hoisted),
45+
...getIdentifierDeclarations(setupBody),
46+
]
47+
constdeclarationArray=uniq(declarations).filter(notNullish)
3948

4049
// filter out identifiers that are used in `<template>`
4150
constreturns:ObjectExpression['properties']=declarationArray
@@ -45,19 +54,24 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
4554
returnt.objectProperty(id,id,false,true)
4655
})
4756

48-
constcomponents=Array.from(template.components).map(component=>
49-
declarationArray.find(declare=>declare===component)
50-
??declarationArray.find(declare=>pascalize(declare)===component),
51-
).filter(isNotNil)
57+
constcomponents=Array.from(template.components)
58+
.map(
59+
component=>
60+
declarationArray.find(declare=>declare===component)
61+
??declarationArray.find(declare=>pascalize(declare)===component),
62+
)
63+
.filter(notNullish)
5264

53-
constdirectiveDeclaration=Array.from(template.directives).map((directive)=>{
54-
constidentifier=declarationArray.find(declaration=>declaration===`v${capitalize(directive)}`)
55-
if(identifier===undefined)
56-
returnundefined
65+
constdirectiveDeclaration=Array.from(template.directives)
66+
.map((directive)=>{
67+
constidentifier=declarationArray.find(
68+
declaration=>declaration===`v${capitalize(directive)}`,
69+
)
70+
if(identifier===undefined)returnundefined
5771

58-
return{ identifier, directive}
59-
},
60-
).filter(isNotNil)
72+
return{ identifier, directive}
73+
})
74+
.filter(notNullish)
6175

6276
// append `<script setup>` imports to `<script>`
6377

@@ -71,10 +85,7 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
7185
if(node.type==='ExportDefaultDeclaration'){
7286
hasBody=true
7387
returnt.variableDeclaration('const',[
74-
t.variableDeclarator(
75-
__sfc,
76-
node.declarationasany,
77-
),
88+
t.variableDeclarator(__sfc,node.declarationasany),
7889
])
7990
}
8091
returnnode
@@ -90,10 +101,7 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
90101
if(!hasBody){
91102
ast.body.push(
92103
t.variableDeclaration('const',[
93-
t.variableDeclarator(
94-
__sfc,
95-
t.objectExpression([]),
96-
),
104+
t.variableDeclarator(__sfc,t.objectExpression([])),
97105
]),
98106
)
99107
}
@@ -104,7 +112,8 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
104112
hasBody=true
105113
ast.body.push(
106114
t.expressionStatement(
107-
t.assignmentExpression('=',
115+
t.assignmentExpression(
116+
'=',
108117
t.memberExpression(__sfc,t.identifier('props')),
109118
propsasany,
110119
),
@@ -126,15 +135,13 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
126135

127136
ast.body.push(
128137
t.expressionStatement(
129-
t.assignmentExpression('=',
138+
t.assignmentExpression(
139+
'=',
130140
t.memberExpression(__sfc,t.identifier('setup')),
131-
t.arrowFunctionExpression([
132-
t.identifier('__props'),
133-
t.identifier('__ctx'),
134-
],t.blockStatement([
135-
...setupBody,
136-
returnStatementasany,
137-
])),
141+
t.arrowFunctionExpression(
142+
[t.identifier('__props'),t.identifier('__ctx')],
143+
t.blockStatement([...setupBody,returnStatementasany]),
144+
),
138145
),
139146
)asany,
140147
)
@@ -153,7 +160,8 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
153160

154161
ast.body.push(
155162
t.expressionStatement(
156-
t.assignmentExpression('=',
163+
t.assignmentExpression(
164+
'=',
157165
t.memberExpression(__sfc,t.identifier('components')),
158166
t.callExpression(
159167
t.memberExpression(t.identifier('Object'),t.identifier('assign')),
@@ -172,17 +180,20 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
172180
if(directiveDeclaration.length){
173181
hasBody=true
174182
constdirectivesObject=t.objectExpression(
175-
directiveDeclaration.map(({ directive, identifier})=>(t.objectProperty(
176-
t.identifier(directive),
177-
t.identifier(identifier),
178-
false,
179-
false,
180-
))),
183+
directiveDeclaration.map(({ directive, identifier})=>
184+
t.objectProperty(
185+
t.identifier(directive),
186+
t.identifier(identifier),
187+
false,
188+
false,
189+
),
190+
),
181191
)
182192

183193
ast.body.push(
184194
t.expressionStatement(
185-
t.assignmentExpression('=',
195+
t.assignmentExpression(
196+
'=',
186197
t.memberExpression(__sfc,t.identifier('directives')),
187198
t.callExpression(
188199
t.memberExpression(t.identifier('Object'),t.identifier('assign')),
@@ -205,9 +216,7 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf
205216

206217
// re-export
207218
// `export default __sfc_main`
208-
ast.body.push(
209-
t.exportDefaultDeclaration(__sfc)asany,
210-
)
219+
ast.body.push(t.exportDefaultDeclaration(__sfc)asany)
211220

212221
ast=options?.astTransforms?.post?.(ast,sfc)||ast
213222

‎test/identifiers.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe('identifiers', () => {
2727
sourceType:'module',
2828
})
2929

30-
expect(getIdentifierDeclarations(ast.program.body)).toEqual(newSet(output))
30+
expect(newSet(getIdentifierDeclarations(ast.program.body))).toEqual(newSet(output))
3131
})
3232
}
3333
})

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp