-
-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathespree.ts
137 lines (126 loc) · 3.7 KB
/
espree.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import type { ParserOptions } from "../common/parser-options"
import { getLinterRequire } from "./linter-require"
// @ts-expect-error -- ignore
import * as dependencyEspree from "espree"
import { lte, lt } from "semver"
import { createRequire } from "./create-require"
import path from "path"
import type { BasicParserObject } from "./parser-object"
type Espree = BasicParserObject & {
latestEcmaVersion?: number
version: string
}
let espreeCache: Espree | null = null
/**
* Gets the espree that the given ecmaVersion can parse.
*/
export function getEspreeFromEcmaVersion(
ecmaVersion: ParserOptions["ecmaVersion"],
): Espree {
const linterEspree = getEspreeFromLinter()
if (ecmaVersion == null) {
return linterEspree
}
if (ecmaVersion === "latest") {
return getNewestEspree()
}
if (
normalizeEcmaVersion(ecmaVersion) <= getLatestEcmaVersion(linterEspree)
) {
return linterEspree
}
const userEspree = getEspreeFromUser()
if (normalizeEcmaVersion(ecmaVersion) <= getLatestEcmaVersion(userEspree)) {
return userEspree
}
return linterEspree
}
/**
* Load `espree` from the user dir.
*/
export function getEspreeFromUser(): Espree {
try {
const cwd = process.cwd()
const relativeTo = path.join(cwd, "__placeholder__.js")
return createRequire(relativeTo)("espree")
} catch {
return getEspreeFromLinter()
}
}
/**
* Load `espree` from the loaded ESLint.
* If the loaded ESLint was not found, just returns `require("espree")`.
*/
export function getEspreeFromLinter(): Espree {
if (!espreeCache) {
espreeCache = getLinterRequire()?.("espree")
if (!espreeCache) {
espreeCache = dependencyEspree
}
}
return espreeCache!
}
/**
* Load the newest `espree` from the loaded ESLint or dependency.
*/
function getNewestEspree(): Espree {
let newest = dependencyEspree
const linterEspree = getEspreeFromLinter()
if (
linterEspree.version != null &&
lte(newest.version, linterEspree.version)
) {
newest = linterEspree
}
const userEspree = getEspreeFromUser()
if (userEspree.version != null && lte(newest.version, userEspree.version)) {
newest = userEspree
}
return newest
}
export function getEcmaVersionIfUseEspree(
parserOptions: ParserOptions,
getDefault?: (defaultVer: number) => number,
): number | undefined {
if (parserOptions.parser != null && parserOptions.parser !== "espree") {
return undefined
}
if (parserOptions.ecmaVersion === "latest") {
return normalizeEcmaVersion(getLatestEcmaVersion(getNewestEspree()))
}
if (parserOptions.ecmaVersion == null) {
const defVer = getDefaultEcmaVersion()
return getDefault?.(defVer) ?? defVer
}
return normalizeEcmaVersion(parserOptions.ecmaVersion)
}
function getDefaultEcmaVersion(): number {
if (lt(getEspreeFromLinter().version, "9.0.0")) {
return 5
}
// Perhaps the version 9 will change the default to "latest".
return normalizeEcmaVersion(getLatestEcmaVersion(getNewestEspree()))
}
/**
* Normalize ECMAScript version
*/
function normalizeEcmaVersion(version: number) {
if (version > 5 && version < 2015) {
return version + 2009
}
return version
}
function getLatestEcmaVersion(espree: Espree) {
if (espree.latestEcmaVersion == null) {
for (const { v, latest } of [
{ v: "6.1.0", latest: 2020 },
{ v: "4.0.0", latest: 2019 },
]) {
if (lte(v, espree.version)) {
return latest
}
}
return 2018
}
return normalizeEcmaVersion(espree.latestEcmaVersion)
}