diff --git a/CHANGELOG.md b/CHANGELOG.md index da83f13868..9151d8ccc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] +- [`no-unused-modules`]: fix usage of `import/extensions` settings ([#___], thanks [@stekycz]) ## [2.19.1] - 2019-12-08 ### Fixed @@ -1037,3 +1038,4 @@ for info on changes for earlier releases. [@christophercurrie]: https://github.com/christophercurrie [@randallreedjr]: https://github.com/randallreedjr [@Pessimistress]: https://github.com/Pessimistress +[@stekycz]: https://github.com/stekycz diff --git a/src/rules/no-unused-modules.js b/src/rules/no-unused-modules.js index 9bbafe99db..0176c87a10 100644 --- a/src/rules/no-unused-modules.js +++ b/src/rules/no-unused-modules.js @@ -5,6 +5,7 @@ */ import Exports from '../ExportMap' +import { getFileExtensions } from 'eslint-module-utils/ignore' import resolve from 'eslint-module-utils/resolve' import docsUrl from '../docsUrl' import { dirname, join } from 'path' @@ -17,18 +18,27 @@ import includes from 'array-includes' let listFilesToProcess try { var FileEnumerator = require('eslint/lib/cli-engine/file-enumerator').FileEnumerator - listFilesToProcess = function (src) { - var e = new FileEnumerator() + listFilesToProcess = function (src, extensions) { + var e = new FileEnumerator({ + extensions: extensions, + }) return Array.from(e.iterateFiles(src), ({ filePath, ignored }) => ({ ignored, filename: filePath, })) } } catch (e1) { + let originalListFilesToProcess try { - listFilesToProcess = require('eslint/lib/util/glob-utils').listFilesToProcess + originalListFilesToProcess = require('eslint/lib/util/glob-utils').listFilesToProcess } catch (e2) { - listFilesToProcess = require('eslint/lib/util/glob-util').listFilesToProcess + originalListFilesToProcess = require('eslint/lib/util/glob-util').listFilesToProcess + } + // Prevent passing invalid options (extensions array) to old versions of the function. + // https://github.com/eslint/eslint/blob/v5.16.0/lib/util/glob-utils.js#L178-L280 + // https://github.com/eslint/eslint/blob/v5.2.0/lib/util/glob-util.js#L174-L269 + listFilesToProcess = function (src) { + return originalListFilesToProcess(src) } } @@ -59,12 +69,14 @@ const isNodeModule = path => { * * return all files matching src pattern, which are not matching the ignoreExports pattern */ -const resolveFiles = (src, ignoreExports) => { +const resolveFiles = (src, ignoreExports, context) => { + const extensions = Array.from(getFileExtensions(context.settings)) + const srcFiles = new Set() - const srcFileList = listFilesToProcess(src) + const srcFileList = listFilesToProcess(src, extensions) // prepare list of ignored files - const ignoredFilesList = listFilesToProcess(ignoreExports) + const ignoredFilesList = listFilesToProcess(ignoreExports, extensions) ignoredFilesList.forEach(({ filename }) => ignoredFiles.add(filename)) // prepare list of source files, don't consider files from node_modules @@ -201,7 +213,7 @@ const getSrc = src => { */ let srcFiles const doPreparation = (src, ignoreExports, context) => { - srcFiles = resolveFiles(getSrc(src), ignoreExports) + srcFiles = resolveFiles(getSrc(src), ignoreExports, context) prepareImportsAndExports(srcFiles, context) determineUsage() preparationDone = true @@ -389,7 +401,7 @@ module.exports = { // make sure file to be linted is included in source files if (!srcFiles.has(file)) { - srcFiles = resolveFiles(getSrc(src), ignoreExports) + srcFiles = resolveFiles(getSrc(src), ignoreExports, context) if (!srcFiles.has(file)) { filesOutsideSrc.add(file) return diff --git a/tests/files/no-unused-modules/typescript/file-ts-a.ts b/tests/files/no-unused-modules/typescript/file-ts-a.ts new file mode 100644 index 0000000000..a4272256e6 --- /dev/null +++ b/tests/files/no-unused-modules/typescript/file-ts-a.ts @@ -0,0 +1,3 @@ +import {b} from './file-ts-b'; + +export const a = b + 1; diff --git a/tests/files/no-unused-modules/typescript/file-ts-b.ts b/tests/files/no-unused-modules/typescript/file-ts-b.ts new file mode 100644 index 0000000000..202103085c --- /dev/null +++ b/tests/files/no-unused-modules/typescript/file-ts-b.ts @@ -0,0 +1 @@ +export const b = 2; diff --git a/tests/src/rules/no-unused-modules.typescript.js b/tests/src/rules/no-unused-modules.typescript.js new file mode 100644 index 0000000000..eb21308235 --- /dev/null +++ b/tests/src/rules/no-unused-modules.typescript.js @@ -0,0 +1,42 @@ +import { test, testFilePath } from '../utils' +import typescriptConfig from '../../../config/typescript' + +import { RuleTester } from 'eslint' + +// We need to clear the cache to reinitialize the rule for Typescript only +delete require.cache[require.resolve('rules/no-unused-modules')] + +const ruleTester = new RuleTester(typescriptConfig) + , rule = require('rules/no-unused-modules') + +const error = message => ({ ruleId: 'no-unused-modules', message }) + +const unusedExportsTypescriptOptions = [{ + unusedExports: true, + src: [testFilePath('./no-unused-modules/typescript')], + ignoreExports: undefined, +}] + +describe('correctly work with Typescript only files', () => { + ruleTester.run('no-unused-modules', rule, { + valid: [ + test({ + options: unusedExportsTypescriptOptions, + code: 'import a from "file-a";', + parser: require.resolve('@typescript-eslint/parser'), + filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'), + }), + ], + invalid: [ + test({ + options: unusedExportsTypescriptOptions, + code: `export const b = 2;`, + parser: require.resolve('@typescript-eslint/parser'), + filename: testFilePath('./no-unused-modules/typescript/file-ts-b.ts'), + errors: [ + error(`exported declaration 'b' not used within other modules`), + ], + }), + ], + }) +})