Skip to content

Commit aca17d7

Browse files
authored
Make to use project: undefined when parsing script-fragments in <template>. (#195)
* Make to use `project: undefined` when parsing template script-let. * fix for css v-bind * add `projectService: undefined`
1 parent d1d2540 commit aca17d7

File tree

7 files changed

+153
-9
lines changed

7 files changed

+153
-9
lines changed

Diff for: src/common/parser-options.ts

+8
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export interface ParserOptions {
3030
lib?: string[]
3131

3232
project?: string | string[]
33+
projectService?: boolean | ProjectServiceOptions
3334
projectFolderIgnoreList?: string[]
3435
tsconfigRootDir?: string
3536
extraFileExtensions?: string[]
@@ -55,6 +56,13 @@ export interface ParserOptions {
5556
>
5657
}
5758

59+
interface ProjectServiceOptions {
60+
allowDefaultProject?: string[]
61+
defaultProject?: string
62+
loadTypeScriptPlugins?: boolean
63+
maximumDefaultProjectFileMatchCount_THIS_WILL_SLOW_DOWN_LINTING?: number
64+
}
65+
5866
export function isSFCFile(parserOptions: ParserOptions) {
5967
if (parserOptions.filePath === "<input>") {
6068
return true

Diff for: src/html/parser.ts

+2
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ export class Parser {
302302
yield getParserLangFromSFC(doc)
303303
},
304304
),
305+
project: undefined,
306+
projectService: undefined,
305307
}
306308
const scriptParserOptions = {
307309
...this.baseParserOptions,

Diff for: src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ function parseAsSFC(code: string, options: ParserOptions) {
165165
yield "<template>"
166166
yield getParserLangFromSFC(rootAST)
167167
}),
168+
project: undefined,
169+
projectService: undefined,
168170
})
169171
}
170172
result.ast.templateBody = templateBody

Diff for: src/script-setup/index.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -516,14 +516,12 @@ function getScriptSetupCodeBlocks(
516516
const offsetLocationCalculator =
517517
linesAndColumns.createOffsetLocationCalculator(scriptSetupStartOffset)
518518

519-
const result = parseScript(
519+
const { ast, visitorKeys } = parseScript(
520520
scriptCode,
521-
parserOptions,
521+
{ ...parserOptions, project: undefined, projectService: undefined },
522522
offsetLocationCalculator,
523523
)
524524

525-
const { ast } = result
526-
527525
// Holds the `import` and re-`export` statements.
528526
// All import and re-`export` statements are hoisted to the top.
529527
const importCodeBlocks = new CodeBlocks()
@@ -597,7 +595,7 @@ function getScriptSetupCodeBlocks(
597595
}
598596
fixNodeLocations(
599597
body,
600-
result.visitorKeys,
598+
visitorKeys,
601599
offsetLocationCalculator,
602600
)
603601
fixLocation(exportToken, offsetLocationCalculator)
@@ -695,7 +693,7 @@ function getScriptSetupCodeBlocks(
695693
// restore
696694
fixNodeLocations(
697695
body,
698-
result.visitorKeys,
696+
visitorKeys,
699697
offsetLocationCalculator,
700698
)
701699
for (const token of restoreTokens) {
@@ -826,7 +824,7 @@ function getScriptSetupCodeBlocks(
826824
let start = n.range[0]
827825
let end = n.range[1]
828826
traverseNodes(n, {
829-
visitorKeys: result.visitorKeys,
827+
visitorKeys,
830828
enterNode(c) {
831829
start = Math.min(start, c.range[0])
832830
end = Math.max(end, c.range[1])

Diff for: src/script-setup/parser-options.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function getScriptSetupParserOptions(
1616

1717
return {
1818
...parserOptions,
19-
ecmaVersion: espreeEcmaVersion,
19+
ecmaVersion: espreeEcmaVersion || parserOptions.ecmaVersion,
2020
}
2121
}
2222

Diff for: src/script/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,7 @@ export function parseGenericExpression(
13021302
const result = parseScriptFragmentWithOption(
13031303
scriptLet,
13041304
locationCalculator.getSubCalculatorShift(-14),
1305-
{ ...parserOptions, project: undefined },
1305+
{ ...parserOptions, project: undefined, projectService: undefined },
13061306
{
13071307
preFixLocationProcess(preResult) {
13081308
const params = getParams(preResult)

Diff for: test/parser-options-project.js

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
"use strict"
2+
3+
const assert = require("assert")
4+
const { parseForESLint } = require("../src")
5+
const espree = require("espree")
6+
7+
describe("use `project: undefined` when parsing template script-let", () => {
8+
it("should be the project option is defined only once in Simple SFC.", () => {
9+
let projectCount = 0
10+
parseForESLint(
11+
`<template>
12+
<div v-bind:class="{}">
13+
<template v-for="item in items">
14+
{{ 'str' }}
15+
<button v-on:click="handler()"></button>
16+
</template>
17+
<MyComponent>
18+
<template v-slot="{a}">
19+
<div v-if="a">A</div>
20+
</template>
21+
</MyComponent>
22+
</div>
23+
</template>
24+
<script>
25+
export default {}
26+
</script>
27+
`,
28+
{
29+
project: true,
30+
sourceType: "module",
31+
ecmaVersion: 2018,
32+
parser: {
33+
parseForESLint(code, options) {
34+
if (options.project) {
35+
projectCount++
36+
}
37+
38+
return {
39+
ast: espree.parse(code, options),
40+
}
41+
},
42+
},
43+
},
44+
)
45+
assert.strictEqual(projectCount, 1)
46+
})
47+
it("should be the project option is defined only once in <script setup>.", () => {
48+
let projectCount = 0
49+
parseForESLint(
50+
`<script setup>
51+
let items = ["foo"]
52+
</script>
53+
<template>
54+
<div v-bind:class="{}">
55+
<template v-for="item in items">
56+
{{ 'str' }}
57+
<button v-on:click="handler()"></button>
58+
</template>
59+
<MyComponent>
60+
<template v-slot="{a}">
61+
<div v-if="a">A</div>
62+
</template>
63+
</MyComponent>
64+
</div>
65+
</template>
66+
<style scoped>
67+
.a {
68+
color: v-bind(color)
69+
}
70+
</style>
71+
`,
72+
{
73+
project: true,
74+
sourceType: "module",
75+
ecmaVersion: 2018,
76+
parser: {
77+
parseForESLint(code, options) {
78+
if (options.project) {
79+
projectCount++
80+
}
81+
82+
return {
83+
ast: espree.parse(code, options),
84+
}
85+
},
86+
},
87+
},
88+
)
89+
assert.strictEqual(projectCount, 1)
90+
})
91+
92+
it("should be the project option is defined only once in <script setup> with <script>.", () => {
93+
let projectCount = 0
94+
parseForESLint(
95+
`<script>
96+
import { ref } from 'vue'
97+
</script>
98+
<script setup>
99+
let items = ref(["foo"])
100+
</script>
101+
<template>
102+
<div v-bind:class="{}">
103+
<template v-for="item in items">
104+
{{ 'str' }}
105+
<button v-on:click="handler()"></button>
106+
</template>
107+
<MyComponent>
108+
<template v-slot="{a}">
109+
<div v-if="a">A</div>
110+
</template>
111+
</MyComponent>
112+
</div>
113+
</template>
114+
`,
115+
{
116+
project: true,
117+
sourceType: "module",
118+
ecmaVersion: 2018,
119+
parser: {
120+
parseForESLint(code, options) {
121+
if (options.project) {
122+
projectCount++
123+
}
124+
125+
return {
126+
ast: espree.parse(code, options),
127+
}
128+
},
129+
},
130+
},
131+
)
132+
assert.strictEqual(projectCount, 1)
133+
})
134+
})

0 commit comments

Comments
 (0)