From 20a7dcc808a39cd447d6e52fc5a1e1373d7122e9 Mon Sep 17 00:00:00 2001 From: Gabriel Cangussu Date: Thu, 3 Sep 2020 03:22:09 -0300 Subject: [PATCH] fix(scope-manager): fallback to lib 'esnext' or 'es5' when ecma version is unsupported (#2474) --- packages/scope-manager/src/analyze.ts | 9 ++-- .../eslint-scope/map-ecma-version.test.ts | 45 +++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 packages/scope-manager/tests/eslint-scope/map-ecma-version.test.ts diff --git a/packages/scope-manager/src/analyze.ts b/packages/scope-manager/src/analyze.ts index 2c7e3949176..ee3ac77de96 100644 --- a/packages/scope-manager/src/analyze.ts +++ b/packages/scope-manager/src/analyze.ts @@ -2,6 +2,7 @@ import { TSESTree, EcmaVersion, Lib } from '@typescript-eslint/types'; import { visitorKeys } from '@typescript-eslint/visitor-keys'; import { Referencer, ReferencerOptions } from './referencer'; import { ScopeManager } from './ScopeManager'; +import { lib as TSLibraries } from './lib'; //////////////////////////////////////////////////// // MAKE SURE THIS IS KEPT IN SYNC WITH THE README // @@ -61,12 +62,10 @@ function mapEcmaVersion(version: EcmaVersion | undefined): Lib { return 'es5'; } - if (version > 2000) { - return `es${version}` as Lib; - } + const year = version > 2000 ? version : 2015 + (version - 6); + const lib = `es${year}`; - const year = 2015 + (version - 6); - return `es${year}` as Lib; + return lib in TSLibraries ? (lib as Lib) : year > 2020 ? 'esnext' : 'es5'; } /** diff --git a/packages/scope-manager/tests/eslint-scope/map-ecma-version.test.ts b/packages/scope-manager/tests/eslint-scope/map-ecma-version.test.ts new file mode 100644 index 00000000000..3a5957b7003 --- /dev/null +++ b/packages/scope-manager/tests/eslint-scope/map-ecma-version.test.ts @@ -0,0 +1,45 @@ +import { analyze } from '../../src/analyze'; +import { Referencer } from '../../src/referencer'; +import { TSESTree, EcmaVersion, Lib } from '@typescript-eslint/types'; + +jest.mock('../../src/referencer'); +jest.mock('../../src/ScopeManager'); + +describe('ecma version mapping', () => { + it("should map to 'esnext' when unsuported and new", () => { + expectMapping(2042, 'esnext'); + expectMapping(42, 'esnext'); + }); + + it("should map to 'es5' when unsuported and old", () => { + expectMapping(2002, 'es5'); + expectMapping(2, 'es5'); + }); + + it("should map to 'es{year}' when supported and >= 6", () => { + expectMapping(2015, 'es2015'); + expectMapping(6, 'es2015'); + expectMapping(2020, 'es2020'); + expectMapping(11, 'es2020'); + }); + + it("should map to 'es5' when 5 or 3", () => { + expectMapping(5, 'es5'); + expectMapping(3, 'es5'); + }); + + it("should map to 'es2018' when undefined", () => { + expectMapping(undefined, 'es2018'); + }); +}); + +const fakeNode = ({} as unknown) as TSESTree.Node; + +function expectMapping(ecmaVersion: number | undefined, lib: Lib): void { + (Referencer as jest.Mock).mockClear(); + analyze(fakeNode, { ecmaVersion: ecmaVersion as EcmaVersion }); + expect(Referencer).toHaveBeenCalledWith( + expect.objectContaining({ lib: [lib] }), + expect.any(Object), + ); +}