Skip to content

Commit

Permalink
Make to use project: undefined when parsing script-fragments in `<t…
Browse files Browse the repository at this point in the history
…emplate>`. (#195)

* Make to use `project: undefined` when parsing template script-let.

* fix for css v-bind

* add `projectService: undefined`
  • Loading branch information
ota-meshi authored Jan 29, 2025
1 parent d1d2540 commit aca17d7
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 9 deletions.
8 changes: 8 additions & 0 deletions src/common/parser-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface ParserOptions {
lib?: string[]

project?: string | string[]
projectService?: boolean | ProjectServiceOptions
projectFolderIgnoreList?: string[]
tsconfigRootDir?: string
extraFileExtensions?: string[]
Expand All @@ -55,6 +56,13 @@ export interface ParserOptions {
>
}

interface ProjectServiceOptions {
allowDefaultProject?: string[]
defaultProject?: string
loadTypeScriptPlugins?: boolean
maximumDefaultProjectFileMatchCount_THIS_WILL_SLOW_DOWN_LINTING?: number
}

export function isSFCFile(parserOptions: ParserOptions) {
if (parserOptions.filePath === "<input>") {
return true
Expand Down
2 changes: 2 additions & 0 deletions src/html/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ export class Parser {
yield getParserLangFromSFC(doc)
},
),
project: undefined,
projectService: undefined,
}
const scriptParserOptions = {
...this.baseParserOptions,
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ function parseAsSFC(code: string, options: ParserOptions) {
yield "<template>"
yield getParserLangFromSFC(rootAST)
}),
project: undefined,
projectService: undefined,
})
}
result.ast.templateBody = templateBody
Expand Down
12 changes: 5 additions & 7 deletions src/script-setup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,14 +516,12 @@ function getScriptSetupCodeBlocks(
const offsetLocationCalculator =
linesAndColumns.createOffsetLocationCalculator(scriptSetupStartOffset)

const result = parseScript(
const { ast, visitorKeys } = parseScript(
scriptCode,
parserOptions,
{ ...parserOptions, project: undefined, projectService: undefined },
offsetLocationCalculator,
)

const { ast } = result

// Holds the `import` and re-`export` statements.
// All import and re-`export` statements are hoisted to the top.
const importCodeBlocks = new CodeBlocks()
Expand Down Expand Up @@ -597,7 +595,7 @@ function getScriptSetupCodeBlocks(
}
fixNodeLocations(
body,
result.visitorKeys,
visitorKeys,
offsetLocationCalculator,
)
fixLocation(exportToken, offsetLocationCalculator)
Expand Down Expand Up @@ -695,7 +693,7 @@ function getScriptSetupCodeBlocks(
// restore
fixNodeLocations(
body,
result.visitorKeys,
visitorKeys,
offsetLocationCalculator,
)
for (const token of restoreTokens) {
Expand Down Expand Up @@ -826,7 +824,7 @@ function getScriptSetupCodeBlocks(
let start = n.range[0]
let end = n.range[1]
traverseNodes(n, {
visitorKeys: result.visitorKeys,
visitorKeys,
enterNode(c) {
start = Math.min(start, c.range[0])
end = Math.max(end, c.range[1])
Expand Down
2 changes: 1 addition & 1 deletion src/script-setup/parser-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function getScriptSetupParserOptions(

return {
...parserOptions,
ecmaVersion: espreeEcmaVersion,
ecmaVersion: espreeEcmaVersion || parserOptions.ecmaVersion,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1302,7 +1302,7 @@ export function parseGenericExpression(
const result = parseScriptFragmentWithOption(
scriptLet,
locationCalculator.getSubCalculatorShift(-14),
{ ...parserOptions, project: undefined },
{ ...parserOptions, project: undefined, projectService: undefined },
{
preFixLocationProcess(preResult) {
const params = getParams(preResult)
Expand Down
134 changes: 134 additions & 0 deletions test/parser-options-project.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
"use strict"

const assert = require("assert")
const { parseForESLint } = require("../src")
const espree = require("espree")

describe("use `project: undefined` when parsing template script-let", () => {
it("should be the project option is defined only once in Simple SFC.", () => {
let projectCount = 0
parseForESLint(
`<template>
<div v-bind:class="{}">
<template v-for="item in items">
{{ 'str' }}
<button v-on:click="handler()"></button>
</template>
<MyComponent>
<template v-slot="{a}">
<div v-if="a">A</div>
</template>
</MyComponent>
</div>
</template>
<script>
export default {}
</script>
`,
{
project: true,
sourceType: "module",
ecmaVersion: 2018,
parser: {
parseForESLint(code, options) {
if (options.project) {
projectCount++
}

return {
ast: espree.parse(code, options),
}
},
},
},
)
assert.strictEqual(projectCount, 1)
})
it("should be the project option is defined only once in <script setup>.", () => {
let projectCount = 0
parseForESLint(
`<script setup>
let items = ["foo"]
</script>
<template>
<div v-bind:class="{}">
<template v-for="item in items">
{{ 'str' }}
<button v-on:click="handler()"></button>
</template>
<MyComponent>
<template v-slot="{a}">
<div v-if="a">A</div>
</template>
</MyComponent>
</div>
</template>
<style scoped>
.a {
color: v-bind(color)
}
</style>
`,
{
project: true,
sourceType: "module",
ecmaVersion: 2018,
parser: {
parseForESLint(code, options) {
if (options.project) {
projectCount++
}

return {
ast: espree.parse(code, options),
}
},
},
},
)
assert.strictEqual(projectCount, 1)
})

it("should be the project option is defined only once in <script setup> with <script>.", () => {
let projectCount = 0
parseForESLint(
`<script>
import { ref } from 'vue'
</script>
<script setup>
let items = ref(["foo"])
</script>
<template>
<div v-bind:class="{}">
<template v-for="item in items">
{{ 'str' }}
<button v-on:click="handler()"></button>
</template>
<MyComponent>
<template v-slot="{a}">
<div v-if="a">A</div>
</template>
</MyComponent>
</div>
</template>
`,
{
project: true,
sourceType: "module",
ecmaVersion: 2018,
parser: {
parseForESLint(code, options) {
if (options.project) {
projectCount++
}

return {
ast: espree.parse(code, options),
}
},
},
},
)
assert.strictEqual(projectCount, 1)
})
})

0 comments on commit aca17d7

Please sign in to comment.