From f89759984a0b0c3ab39b572dfb065b3661452d3a Mon Sep 17 00:00:00 2001 From: ExE Boss <3889017+ExE-Boss@users.noreply.github.com> Date: Sun, 4 Oct 2020 19:20:00 +0200 Subject: [PATCH] =?UTF-8?q?[New]=20`first`/TypeScript:=20Add=C2=A0support?= =?UTF-8?q?=20for=C2=A0`import=C2=A0=3D`=C2=A0expressions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 +++ src/rules/first.js | 38 +++++++++++++++++++++++ tests/src/rules/first.js | 66 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b47aaa55..eade81ac0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] +### Added +- [`first`]/TypeScript: Add support for `import =` expressions ([#1917], thanks [@ExE-Boss]) ### Fixed - [`export`]/TypeScript: properly detect export specifiers as children of a TS module block ([#1889], thanks [@andreubotella]) @@ -735,6 +737,7 @@ for info on changes for earlier releases. [`memo-parser`]: ./memo-parser/README.md +[#1917]: https://github.com/benmosher/eslint-plugin-import/pull/1917 [#1889]: https://github.com/benmosher/eslint-plugin-import/pull/1889 [#1878]: https://github.com/benmosher/eslint-plugin-import/pull/1878 [#1854]: https://github.com/benmosher/eslint-plugin-import/issues/1854 @@ -1281,3 +1284,4 @@ for info on changes for earlier releases. [@tomprats]: https://github.com/tomprats [@straub]: https://github.com/straub [@andreubotella]: https://github.com/andreubotella +[@ExE-Boss]: https://github.com/ExE-Boss diff --git a/src/rules/first.js b/src/rules/first.js index c1422cdb0..f365f7652 100644 --- a/src/rules/first.js +++ b/src/rules/first.js @@ -75,6 +75,44 @@ module.exports = { } else { lastLegalImp = node } + } else if (node.type === 'TSImportEqualsDeclaration') { + const moduleReference = node.moduleReference + if (moduleReference.type !== 'TSExternalModuleReference') { + nonImportCount++ + } else { + if (absoluteFirst) { + const source = moduleReference.expression + if (/^\./.test(source.value)) { + anyRelative = true + } else if (anyRelative) { + context.report({ + node: source, + message: 'Absolute imports should come before relative imports.', + }) + } + } + if (nonImportCount > 0) { + for (let variable of context.getDeclaredVariables(node)) { + if (!shouldSort) break + const references = variable.references + if (references.length) { + for (let reference of references) { + if (reference.identifier.range[0] < node.range[1]) { + shouldSort = false + break + } + } + } + } + shouldSort && (lastSortNodesIndex = errorInfos.length) + errorInfos.push({ + node, + range: [body[index - 1].range[1], node.range[1]], + }) + } else { + lastLegalImp = node + } + } } else { nonImportCount++ } diff --git a/tests/src/rules/first.js b/tests/src/rules/first.js index 8c5d72a34..640cadbd0 100644 --- a/tests/src/rules/first.js +++ b/tests/src/rules/first.js @@ -1,8 +1,9 @@ -import { test } from '../utils' +import { test, getTSParsers } from '../utils' import { RuleTester } from 'eslint' +import flatMap from 'array.prototype.flatmap' -const ruleTester = new RuleTester() +const ruleTester = new RuleTester({ parserOptions: { sourceType: 'module' } }) , rule = require('rules/first') ruleTester.run('first', rule, { @@ -16,7 +17,42 @@ ruleTester.run('first', rule, { }) , test({ code: "'use directive';\ import { x } from 'foo';" }) - , + , ...flatMap(getTSParsers(), parser => [ + test({ + parser, + code: ` + import fs = require('fs'); + import { x } from './foo'; + import { y } from './bar'; + `, + }), + test({ + parser, + code: ` + import fs = require('fs'); + import { x } from './foo'; + import { y } from './bar'; + `, + options: ['absolute-first'], + }), + test({ + parser, + code: ` + import { x } from './foo'; + import fs = require('fs'); + import { y } from './bar'; + `, + }), + test({ + parser, + code: ` + import { x } from './foo'; + import fs = require('fs'); + import { y } from './bar'; + `, + options: ['disable-absolute-first'], + }), + ]), ], invalid: [ test({ code: "import { x } from './foo';\ @@ -65,6 +101,28 @@ ruleTester.run('first', rule, { , errors: 1 , output: "import a from 'b'\nif (true) { console.log(1) }", }) - , + , ...flatMap(getTSParsers(), parser => [ + { + parser, + code: ` + import { x } from './foo'; + import fs = require('fs'); + `, + options: ['absolute-first'], + errors: 1, + }, + { + parser, + code: ` + var a = 1; + import fs = require('fs'); + `, + errors: 1, + output: ` + import fs = require('fs'); + var a = 1; + `, + }, + ]), ], })