@@ -2,8 +2,10 @@ import type { ESLintExtendedProgram, ESLintProgram } from "../ast"
22import type { ParserOptions } from "../common/parser-options"
33import { getLinterRequire } from "./linter-require"
44// @ts -expect-error -- ignore
5- import * as espree from "espree"
5+ import * as dependencyEspree from "espree"
66import { lte , lt } from "semver"
7+ import { createRequire } from "./create-require"
8+ import path from "path"
79
810/**
911 * The interface of a result of ESLint custom parser.
@@ -17,66 +19,59 @@ export interface ESLintCustomParser {
1719 parse ( code : string , options : any ) : ESLintCustomParserResult
1820 parseForESLint ?( code : string , options : any ) : ESLintCustomParserResult
1921}
20- type OldEspree = ESLintCustomParser & {
21- latestEcmaVersion ?: number
22- version : string
23- }
2422type Espree = ESLintCustomParser & {
25- latestEcmaVersion : number
23+ latestEcmaVersion ? : number
2624 version : string
2725}
28- let espreeCache : OldEspree | Espree | null = null
26+ let espreeCache : Espree | null = null
2927
3028/**
3129 * Gets the espree that the given ecmaVersion can parse.
3230 */
3331export function getEspreeFromEcmaVersion (
3432 ecmaVersion : ParserOptions [ "ecmaVersion" ] ,
35- ) : OldEspree | Espree {
33+ ) : Espree {
3634 const linterEspree = getEspreeFromLinter ( )
37- if (
38- linterEspree . version != null &&
39- lte ( espree . version , linterEspree . version )
40- ) {
41- // linterEspree is newest
42- return linterEspree
43- }
4435 if ( ecmaVersion == null ) {
4536 return linterEspree
4637 }
4738 if ( ecmaVersion === "latest" ) {
48- return espree
39+ return getNewestEspree ( )
4940 }
50- if ( normalizeEcmaVersion ( ecmaVersion ) <= getLinterLatestEcmaVersion ( ) ) {
41+ if (
42+ normalizeEcmaVersion ( ecmaVersion ) <= getLatestEcmaVersion ( linterEspree )
43+ ) {
5144 return linterEspree
5245 }
53- return espree
46+ const userEspree = getEspreeFromUser ( )
47+ if ( normalizeEcmaVersion ( ecmaVersion ) <= getLatestEcmaVersion ( userEspree ) ) {
48+ return userEspree
49+ }
50+ return linterEspree
51+ }
5452
55- function getLinterLatestEcmaVersion ( ) {
56- if ( linterEspree . latestEcmaVersion == null ) {
57- for ( const { v, latest } of [
58- { v : "6.1.0" , latest : 2020 } ,
59- { v : "4.0.0" , latest : 2019 } ,
60- ] ) {
61- if ( lte ( v , linterEspree . version ) ) {
62- return latest
63- }
64- }
65- return 2018
66- }
67- return normalizeEcmaVersion ( linterEspree . latestEcmaVersion )
53+ /**
54+ * Load `espree` from the user dir.
55+ */
56+ export function getEspreeFromUser ( ) : Espree {
57+ try {
58+ const cwd = process . cwd ( )
59+ const relativeTo = path . join ( cwd , "__placeholder__.js" )
60+ return createRequire ( relativeTo ) ( "espree" )
61+ } catch {
62+ return getEspreeFromLinter ( )
6863 }
6964}
7065
7166/**
7267 * Load `espree` from the loaded ESLint.
7368 * If the loaded ESLint was not found, just returns `require("espree")`.
7469 */
75- export function getEspreeFromLinter ( ) : Espree | OldEspree {
70+ export function getEspreeFromLinter ( ) : Espree {
7671 if ( ! espreeCache ) {
7772 espreeCache = getLinterRequire ( ) ?.( "espree" )
7873 if ( ! espreeCache ) {
79- espreeCache = espree
74+ espreeCache = dependencyEspree
8075 }
8176 }
8277
@@ -87,14 +82,19 @@ export function getEspreeFromLinter(): Espree | OldEspree {
8782 * Load the newest `espree` from the loaded ESLint or dependency.
8883 */
8984function getNewestEspree ( ) : Espree {
85+ let newest = dependencyEspree
9086 const linterEspree = getEspreeFromLinter ( )
9187 if (
92- linterEspree . version == null ||
93- lte ( linterEspree . version , espree . version )
88+ linterEspree . version != null &&
89+ lte ( newest . version , linterEspree . version )
9490 ) {
95- return espree
91+ newest = linterEspree
9692 }
97- return linterEspree as Espree
93+ const userEspree = getEspreeFromUser ( )
94+ if ( userEspree . version != null && lte ( newest . version , userEspree . version ) ) {
95+ newest = userEspree
96+ }
97+ return newest
9898}
9999
100100export function getEcmaVersionIfUseEspree (
@@ -106,7 +106,7 @@ export function getEcmaVersionIfUseEspree(
106106 }
107107
108108 if ( parserOptions . ecmaVersion === "latest" ) {
109- return normalizeEcmaVersion ( getNewestEspree ( ) . latestEcmaVersion )
109+ return normalizeEcmaVersion ( getLatestEcmaVersion ( getNewestEspree ( ) ) )
110110 }
111111 if ( parserOptions . ecmaVersion == null ) {
112112 const defVer = getDefaultEcmaVersion ( )
@@ -120,7 +120,7 @@ function getDefaultEcmaVersion(): number {
120120 return 5
121121 }
122122 // Perhaps the version 9 will change the default to "latest".
123- return normalizeEcmaVersion ( getNewestEspree ( ) . latestEcmaVersion )
123+ return normalizeEcmaVersion ( getLatestEcmaVersion ( getNewestEspree ( ) ) )
124124}
125125
126126/**
@@ -132,3 +132,18 @@ function normalizeEcmaVersion(version: number) {
132132 }
133133 return version
134134}
135+
136+ function getLatestEcmaVersion ( espree : Espree ) {
137+ if ( espree . latestEcmaVersion == null ) {
138+ for ( const { v, latest } of [
139+ { v : "6.1.0" , latest : 2020 } ,
140+ { v : "4.0.0" , latest : 2019 } ,
141+ ] ) {
142+ if ( lte ( v , espree . version ) ) {
143+ return latest
144+ }
145+ }
146+ return 2018
147+ }
148+ return normalizeEcmaVersion ( espree . latestEcmaVersion )
149+ }
0 commit comments