From 513a488ea7b5fdbd6b5b42386307ef9110a1bc00 Mon Sep 17 00:00:00 2001 From: Daniele Zanni Date: Fri, 18 May 2018 12:32:33 +1000 Subject: [PATCH 01/17] Fixed flow types imports --- src/rules/named.js | 3 +++ tests/files/flowtypes.js | 3 +++ tests/src/rules/named.js | 8 ++++++++ 3 files changed, 14 insertions(+) diff --git a/src/rules/named.js b/src/rules/named.js index 8c2acd714e..f0151a89d8 100644 --- a/src/rules/named.js +++ b/src/rules/named.js @@ -30,6 +30,9 @@ module.exports = { node.specifiers.forEach(function (im) { if (im.type !== type) return + // ignore type imports + if(im.importKind === 'type') return + const deepLookup = imports.hasDeep(im[key].name) if (!deepLookup.found) { diff --git a/tests/files/flowtypes.js b/tests/files/flowtypes.js index 7ada3482b1..2df2471475 100644 --- a/tests/files/flowtypes.js +++ b/tests/files/flowtypes.js @@ -10,3 +10,6 @@ export type MyType = { export interface MyInterface {} export class MyClass {} + +export opaque type MyOpaqueType: string = string; + diff --git a/tests/src/rules/named.js b/tests/src/rules/named.js index 4fdd3434f9..fce5230933 100644 --- a/tests/src/rules/named.js +++ b/tests/src/rules/named.js @@ -72,6 +72,14 @@ ruleTester.run('named', rule, { code: 'import type { MissingType } from "./flowtypes"', parser: 'babel-eslint', }), + test({ + code: 'import type { MyOpaqueType } from "./flowtypes"', + parser: 'babel-eslint', + }), + test({ + code: 'import { type MyOpaqueType, MyClass } from "./flowtypes"', + parser: 'babel-eslint', + }), // TypeScript test({ From 96500b84518f2e2802a79f673da35e5625bb8c3a Mon Sep 17 00:00:00 2001 From: Daniele Zanni Date: Fri, 18 May 2018 18:39:01 +1000 Subject: [PATCH 02/17] Added missing space --- src/rules/named.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/named.js b/src/rules/named.js index f0151a89d8..57e4f1d9ef 100644 --- a/src/rules/named.js +++ b/src/rules/named.js @@ -31,7 +31,7 @@ module.exports = { if (im.type !== type) return // ignore type imports - if(im.importKind === 'type') return + if (im.importKind === 'type') return const deepLookup = imports.hasDeep(im[key].name) From 1d9ae51f9f305ed54c9b36d1c6a883392ea94d8e Mon Sep 17 00:00:00 2001 From: syymza Date: Fri, 18 May 2018 22:34:05 +1000 Subject: [PATCH 03/17] Added test for mixed flow imports --- tests/src/rules/named.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/src/rules/named.js b/tests/src/rules/named.js index fce5230933..cb1a5b843b 100644 --- a/tests/src/rules/named.js +++ b/tests/src/rules/named.js @@ -270,6 +270,12 @@ ruleTester.run('named', rule, { }], }), + test({ + code: 'import { type MyOpaqueType, MyMissingClass } from "./flowtypes"', + parser: 'babel-eslint', + errors: ["MyMissingClass not found in './flowtypes'"], + }), + // jsnext test({ code: '/*jsnext*/ import { createSnorlax } from "redux"', From 3b04d5fab6c095e7f0f99488665d90e285872271 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 25 Jun 2018 14:33:43 -0700 Subject: [PATCH 04/17] [Refactor] add explicit support for RestElement alongside ExperimentalRestProperty --- src/rules/namespace.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/rules/namespace.js b/src/rules/namespace.js index 93e5891594..a1d5b6d813 100644 --- a/src/rules/namespace.js +++ b/src/rules/namespace.js @@ -58,7 +58,7 @@ module.exports = { return } - for (let specifier of declaration.specifiers) { + for (const specifier of declaration.specifiers) { switch (specifier.type) { case 'ImportNamespaceSpecifier': if (!imports.size) { @@ -160,8 +160,12 @@ module.exports = { if (pattern.type !== 'ObjectPattern') return - for (let property of pattern.properties) { - if (property.type === 'ExperimentalRestProperty' || !property.key) { + for (const property of pattern.properties) { + if ( + property.type === 'ExperimentalRestProperty' + || property.type === 'RestElement' + || !property.key + ) { continue } From 7abb1e1c9ec95dcad44bf4882e05b094b7f67400 Mon Sep 17 00:00:00 2001 From: Gajus Kuizinas Date: Tue, 26 Jun 2018 18:33:44 +0100 Subject: [PATCH 05/17] feat: make no-cycle ignore Flow imports --- src/rules/no-cycle.js | 4 ++++ tests/src/rules/no-cycle.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/rules/no-cycle.js b/src/rules/no-cycle.js index bbc251e388..ccf77dcf2e 100644 --- a/src/rules/no-cycle.js +++ b/src/rules/no-cycle.js @@ -30,6 +30,10 @@ module.exports = { function checkSourceValue(sourceNode, importer) { const imported = Exports.get(sourceNode.value, context) + if (sourceNode.parent.importKind === 'type') { + return // no Flow import resolution + } + if (imported == null) { return // no-unresolved territory } diff --git a/tests/src/rules/no-cycle.js b/tests/src/rules/no-cycle.js index ae45ba36ec..4ee4daacb6 100644 --- a/tests/src/rules/no-cycle.js +++ b/tests/src/rules/no-cycle.js @@ -36,6 +36,10 @@ ruleTester.run('no-cycle', rule, { code: 'import { foo } from "./depth-two"', options: [{ maxDepth: 1 }], }), + test({ + code: 'import type { FooType } from "./depth-one"', + parser: 'babel-eslint', + }), ], invalid: [ test({ From 60f65979fae29fc38d11cd79ade6336037a789ea Mon Sep 17 00:00:00 2001 From: Gajus Kuizinas Date: Tue, 26 Jun 2018 19:30:36 +0100 Subject: [PATCH 06/17] fix: handly possible undefined parent --- src/rules/no-cycle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/no-cycle.js b/src/rules/no-cycle.js index ccf77dcf2e..a925f98713 100644 --- a/src/rules/no-cycle.js +++ b/src/rules/no-cycle.js @@ -30,7 +30,7 @@ module.exports = { function checkSourceValue(sourceNode, importer) { const imported = Exports.get(sourceNode.value, context) - if (sourceNode.parent.importKind === 'type') { + if (sourceNode.parent && sourceNode.parent.importKind === 'type') { return // no Flow import resolution } From 2c1886e0094159beefc7c6571db83872590b1590 Mon Sep 17 00:00:00 2001 From: Pirasis <1pete@users.noreply.github.com> Date: Fri, 29 Jun 2018 21:13:58 +0700 Subject: [PATCH 07/17] make rule `no-useless-path-segments` work with commonjs --- src/rules/no-useless-path-segments.js | 10 +++++ tests/src/rules/no-useless-path-segments.js | 47 +++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/rules/no-useless-path-segments.js b/src/rules/no-useless-path-segments.js index b9c4eedda0..5872b2d1c3 100644 --- a/src/rules/no-useless-path-segments.js +++ b/src/rules/no-useless-path-segments.js @@ -39,6 +39,16 @@ module.exports = { url: docsUrl('no-useless-path-segments'), }, + schema: [ + { + type: 'object', + properties: { + commonjs: { type: 'boolean' }, + }, + additionalProperties: false, + }, + ], + fixable: 'code', }, diff --git a/tests/src/rules/no-useless-path-segments.js b/tests/src/rules/no-useless-path-segments.js index 1f4229f5ee..ed20440012 100644 --- a/tests/src/rules/no-useless-path-segments.js +++ b/tests/src/rules/no-useless-path-segments.js @@ -7,6 +7,10 @@ const rule = require('rules/no-useless-path-segments') function runResolverTests(resolver) { ruleTester.run(`no-useless-path-segments (${resolver})`, rule, { valid: [ + // commonjs with default options + test({ code: 'require("./../files/malformed.js")' }), + + // esmodule test({ code: 'import "./malformed.js"' }), test({ code: 'import "./test-module"' }), test({ code: 'import "./bar/"' }), @@ -16,6 +20,49 @@ function runResolverTests(resolver) { ], invalid: [ + // commonjs + test({ + code: 'require("./../files/malformed.js")', + options: [{ commonjs: true }], + errors: [ 'Useless path segments for "./../files/malformed.js", should be "../files/malformed.js"'], + }), + test({ + code: 'require("./../files/malformed")', + options: [{ commonjs: true }], + errors: [ 'Useless path segments for "./../files/malformed", should be "../files/malformed"'], + }), + test({ + code: 'require("../files/malformed.js")', + options: [{ commonjs: true }], + errors: [ 'Useless path segments for "../files/malformed.js", should be "./malformed.js"'], + }), + test({ + code: 'require("../files/malformed")', + options: [{ commonjs: true }], + errors: [ 'Useless path segments for "../files/malformed", should be "./malformed"'], + }), + test({ + code: 'require("./test-module/")', + options: [{ commonjs: true }], + errors: [ 'Useless path segments for "./test-module/", should be "./test-module"'], + }), + test({ + code: 'require("./")', + options: [{ commonjs: true }], + errors: [ 'Useless path segments for "./", should be "."'], + }), + test({ + code: 'require("../")', + options: [{ commonjs: true }], + errors: [ 'Useless path segments for "../", should be ".."'], + }), + test({ + code: 'require("./deep//a")', + options: [{ commonjs: true }], + errors: [ 'Useless path segments for "./deep//a", should be "./deep/a"'], + }), + + // esmodule test({ code: 'import "./../files/malformed.js"', errors: [ 'Useless path segments for "./../files/malformed.js", should be "../files/malformed.js"'], From ce4b1af7c02aeb6097766786a1025d817663a54b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Berm=C3=BAdez=20Schettino?= Date: Wed, 11 Jul 2018 11:26:14 +0200 Subject: [PATCH 08/17] Fix format of changelog Updated version links. --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d384d5c390..2a7254bc70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -619,7 +619,8 @@ for info on changes for earlier releases. [#119]: https://github.com/benmosher/eslint-plugin-import/issues/119 [#89]: https://github.com/benmosher/eslint-plugin-import/issues/89 -[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.12.0...HEAD +[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.13.0...HEAD +[2.13.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.12.0...v2.13.0 [2.12.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.11.0...v2.12.0 [2.11.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.10.0...v2.11.0 [2.10.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.9.0...v2.10.0 From 81bf977ffc47980ed597e8bcba1315ccc5968226 Mon Sep 17 00:00:00 2001 From: Chris Lloyd Date: Wed, 11 Jul 2018 09:50:27 -0700 Subject: [PATCH 09/17] [no-relative-parent-imports] Resolve paths This changes the rule to resolve paths before emitting an error. While this means the error will trigger less often (before we could report an error even if the file didn't exist on disk yet) I think it's a fine tradeoff so that it can be useful in more situations. --- src/rules/no-relative-parent-imports.js | 20 ++++++++++++--- tests/src/rules/no-relative-parent-imports.js | 25 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/rules/no-relative-parent-imports.js b/src/rules/no-relative-parent-imports.js index 3153eeb784..6b58c97f5a 100644 --- a/src/rules/no-relative-parent-imports.js +++ b/src/rules/no-relative-parent-imports.js @@ -1,6 +1,7 @@ import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor' import docsUrl from '../docsUrl' -import { basename } from 'path' +import { basename, dirname, relative } from 'path' +import resolve from 'eslint-module-utils/resolve' import importType from '../core/importType' @@ -14,11 +15,24 @@ module.exports = { create: function noRelativePackages(context) { const myPath = context.getFilename() - if (myPath === '') return {} // can't cycle-check a non-file + if (myPath === '') return {} // can't check a non-file function checkSourceValue(sourceNode) { const depPath = sourceNode.value - if (importType(depPath, context) === 'parent') { + + if (importType(depPath, context) === 'external') { // ignore packages + return + } + + const absDepPath = resolve(depPath, context) + + if (!absDepPath) { // unable to resolve path + return + } + + const relDepPath = relative(dirname(myPath), absDepPath) + + if (importType(relDepPath, context) === 'parent') { context.report({ node: sourceNode, message: 'Relative imports from parent directories are not allowed. ' + diff --git a/tests/src/rules/no-relative-parent-imports.js b/tests/src/rules/no-relative-parent-imports.js index 6d7a2c2fae..8978230904 100644 --- a/tests/src/rules/no-relative-parent-imports.js +++ b/tests/src/rules/no-relative-parent-imports.js @@ -38,9 +38,18 @@ ruleTester.run('no-relative-parent-imports', rule, { test({ code: 'import("./app/index.js")', }), + test({ + code: 'import(".")', + }), + test({ + code: 'import("path")', + }), test({ code: 'import("package")', }), + test({ + code: 'import("@scope/package")', + }), ], invalid: [ @@ -69,5 +78,21 @@ ruleTester.run('no-relative-parent-imports', rule, { column: 8, } ], }), + test({ + code: 'import foo from "./../plugin.js"', + errors: [ { + message: 'Relative imports from parent directories are not allowed. Please either pass what you\'re importing through at runtime (dependency injection), move `index.js` to same directory as `./../plugin.js` or consider making `./../plugin.js` a package.', + line: 1, + column: 17 + }] + }), + test({ + code: 'import foo from "../../api/service"', + errors: [ { + message: 'Relative imports from parent directories are not allowed. Please either pass what you\'re importing through at runtime (dependency injection), move `index.js` to same directory as `../../api/service` or consider making `../../api/service` a package.', + line: 1, + column: 17 + }] + }) ], }) From 3b1a806c066832e43c5e86d8b506451c358fb4c5 Mon Sep 17 00:00:00 2001 From: Justin Anastos Date: Thu, 12 Jul 2018 16:54:35 -0400 Subject: [PATCH 10/17] test(order): Add failing test for typescript-eslint-parser --- tests/src/rules/order.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/src/rules/order.js b/tests/src/rules/order.js index fb3b788448..23487dac91 100644 --- a/tests/src/rules/order.js +++ b/tests/src/rules/order.js @@ -1260,5 +1260,21 @@ ruleTester.run('order', rule, { message: '`fs` import should occur before import of `async`', }], })), + // fix incorrect order with typescript-eslint-parser + test({ + code: ` + var async = require('async'); + var fs = require('fs'); + `, + output: ` + var fs = require('fs'); + var async = require('async'); + `, + parser: 'typescript-eslint-parser', + errors: [{ + ruleId: 'order', + message: '`fs` import should occur before import of `async`', + }], + }), ], }) From 8d02f323b6b828aed1e33fa303e9600c96b79d74 Mon Sep 17 00:00:00 2001 From: Justin Anastos Date: Thu, 12 Jul 2018 16:55:47 -0400 Subject: [PATCH 11/17] fix(rules/order): Use `.range` instead of `.start` and `.end` for autofixer `typescript-eslint-parser` does not add `.start` and `.end` to nodes like `babel-eslint`. They both include a `range` that can be used isntead. --- src/rules/order.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rules/order.js b/src/rules/order.js index 81babd7fde..f925a20eb4 100644 --- a/src/rules/order.js +++ b/src/rules/order.js @@ -97,8 +97,8 @@ function findRootNode(node) { function findEndOfLineWithComments(sourceCode, node) { const tokensToEndOfLine = takeTokensAfterWhile(sourceCode, node, commentOnSameLineAs(node)) let endOfTokens = tokensToEndOfLine.length > 0 - ? tokensToEndOfLine[tokensToEndOfLine.length - 1].end - : node.end + ? tokensToEndOfLine[tokensToEndOfLine.length - 1].range[1] + : node.range[1] let result = endOfTokens for (let i = endOfTokens; i < sourceCode.text.length; i++) { if (sourceCode.text[i] === '\n') { @@ -121,7 +121,7 @@ function commentOnSameLineAs(node) { function findStartOfLineWithComments(sourceCode, node) { const tokensToEndOfLine = takeTokensBeforeWhile(sourceCode, node, commentOnSameLineAs(node)) - let startOfTokens = tokensToEndOfLine.length > 0 ? tokensToEndOfLine[0].start : node.start + let startOfTokens = tokensToEndOfLine.length > 0 ? tokensToEndOfLine[0].range[0] : node.range[0] let result = startOfTokens for (let i = startOfTokens - 1; i > 0; i--) { if (sourceCode.text[i] !== ' ' && sourceCode.text[i] !== '\t') { @@ -296,11 +296,11 @@ function fixNewLineAfterImport(context, previousImport) { const tokensToEndOfLine = takeTokensAfterWhile( context.getSourceCode(), prevRoot, commentOnSameLineAs(prevRoot)) - let endOfLine = prevRoot.end + let endOfLine = prevRoot.range[1] if (tokensToEndOfLine.length > 0) { - endOfLine = tokensToEndOfLine[tokensToEndOfLine.length - 1].end + endOfLine = tokensToEndOfLine[tokensToEndOfLine.length - 1].range[1] } - return (fixer) => fixer.insertTextAfterRange([prevRoot.start, endOfLine], '\n') + return (fixer) => fixer.insertTextAfterRange([prevRoot.range[0], endOfLine], '\n') } function removeNewLineAfterImport(context, currentImport, previousImport) { From 3feb54cfa20db3ed39b8a32e430b4ea3508eda8a Mon Sep 17 00:00:00 2001 From: Gajus Kuizinas Date: Sun, 29 Jul 2018 12:50:40 +0100 Subject: [PATCH 12/17] fix: add a workaround for ESLint < v5 --- src/rules/no-cycle.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rules/no-cycle.js b/src/rules/no-cycle.js index a925f98713..1a70db2c70 100644 --- a/src/rules/no-cycle.js +++ b/src/rules/no-cycle.js @@ -34,6 +34,10 @@ module.exports = { return // no Flow import resolution } + if (sourceNode._babelType === 'Literal') { + return // no Flow import resolution, workaround for ESLint < 5.x + } + if (imported == null) { return // no-unresolved territory } From 2d4f651d6e2759e56e2826d874c697e008deaa9c Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 1 Aug 2018 23:13:23 -0700 Subject: [PATCH 13/17] [eslint-module-utils]: when parser settings are not an array, throw a better error message Fixes #1149. --- utils/ignore.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/utils/ignore.js b/utils/ignore.js index 88e4080dda..91cc731a81 100644 --- a/utils/ignore.js +++ b/utils/ignore.js @@ -24,8 +24,11 @@ function makeValidExtensionSet(settings) { // all alternate parser extensions are also valid if ('import/parsers' in settings) { for (let parser in settings['import/parsers']) { - settings['import/parsers'][parser] - .forEach(ext => exts.add(ext)) + const parserSettings = settings['import/parsers'][parser] + if (!Array.isArray(parserSettings)) { + throw new TypeError('"settings" for ' + parser + ' must be an array') + } + parserSettings.forEach(ext => exts.add(ext)) } } From f5bff7b14c52fdd91afe76865ecec955b1f96539 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 9 Aug 2018 23:17:21 -0700 Subject: [PATCH 14/17] [fix] repeat fix from #797 for #717, in another place --- src/ExportMap.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ExportMap.js b/src/ExportMap.js index 1cb5dc3e9c..66b212a211 100644 --- a/src/ExportMap.js +++ b/src/ExportMap.js @@ -38,7 +38,12 @@ export default class ExportMap { get size() { let size = this.namespace.size + this.reexports.size - this.dependencies.forEach(dep => size += dep().size) + this.dependencies.forEach(dep => { + const d = dep() + // CJS / ignored dependencies won't exist (#717) + if (d == null) return + size += d.size + }) return size } From 825234402a3dbe58138781c2f44c3933c59babfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Czap=20Bal=C3=A1zs?= Date: Tue, 31 Jul 2018 10:47:36 +0200 Subject: [PATCH 15/17] Add error to output when module loaded as resolver has invalid API --- tests/files/foo-bar-resolver-invalid.js | 1 + tests/src/core/resolve.js | 17 ++++++++++++++++- utils/resolve.js | 13 ++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/files/foo-bar-resolver-invalid.js diff --git a/tests/files/foo-bar-resolver-invalid.js b/tests/files/foo-bar-resolver-invalid.js new file mode 100644 index 0000000000..a6213d6678 --- /dev/null +++ b/tests/files/foo-bar-resolver-invalid.js @@ -0,0 +1 @@ +exports = {}; diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index 3c15303edf..b9a9063243 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -110,6 +110,22 @@ describe('resolve', function () { expect(testContextReports[0].loc).to.eql({ line: 1, column: 0 }) }) + it('reports loaded resolver with invalid interface', function () { + const resolverName = './foo-bar-resolver-invalid'; + const testContext = utils.testContext({ 'import/resolver': resolverName }); + const testContextReports = [] + testContext.report = function (reportInfo) { + testContextReports.push(reportInfo) + } + testContextReports.length = 0 + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) + )).to.equal(undefined) + expect(testContextReports[0]).to.be.an('object') + expect(testContextReports[0].message).to.equal(`Resolve error: ${resolverName} with invalid interface loaded as resolver`) + expect(testContextReports[0].loc).to.eql({ line: 1, column: 0 }) + }) + it('respects import/resolve extensions', function () { const testContext = utils.testContext({ 'import/resolve': { 'extensions': ['.jsx'] }}) @@ -119,7 +135,6 @@ describe('resolve', function () { }) it('reports load exception in a user resolver', function () { - const testContext = utils.testContext({ 'import/resolver': './load-error-resolver' }) const testContextReports = [] testContext.report = function (reportInfo) { diff --git a/utils/resolve.js b/utils/resolve.js index b280ca2cfa..87a1eaea81 100644 --- a/utils/resolve.js +++ b/utils/resolve.js @@ -160,8 +160,19 @@ function requireResolver(name, sourceFile) { if (!resolver) { throw new Error(`unable to load resolver "${name}".`) + } + if (!isResolverValid(resolver)) { + throw new Error(`${name} with invalid interface loaded as resolver`) + } + + return resolver +} + +function isResolverValid(resolver) { + if (resolver.interfaceVersion === 2) { + return resolver.resolve && typeof resolver.resolve === 'function' } else { - return resolver; + return resolver.resolveImport && typeof resolver.resolveImport === 'function' } } From e30a7577bf46f8c44bb12118563e833fd1b69d06 Mon Sep 17 00:00:00 2001 From: Joshua Freedman Date: Thu, 2 Aug 2018 09:00:36 -0700 Subject: [PATCH 16/17] Add JSX check to namespace rule --- src/rules/namespace.js | 19 +++++++++++++++---- tests/src/rules/namespace.js | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/rules/namespace.js b/src/rules/namespace.js index a1d5b6d813..bbba2ce2ef 100644 --- a/src/rules/namespace.js +++ b/src/rules/namespace.js @@ -44,7 +44,7 @@ module.exports = { return { // pick up all imports at body entry time, to properly respect hoisting - 'Program': function ({ body }) { + Program: function ({ body }) { function processBodyStatement(declaration) { if (declaration.type !== 'ImportDeclaration') return @@ -83,7 +83,7 @@ module.exports = { }, // same as above, but does not add names to local map - 'ExportNamespaceSpecifier': function (namespace) { + ExportNamespaceSpecifier: function (namespace) { var declaration = importDeclaration(context) var imports = Exports.get(declaration.source.value, context) @@ -102,7 +102,7 @@ module.exports = { // todo: check for possible redefinition - 'MemberExpression': function (dereference) { + MemberExpression: function (dereference) { if (dereference.object.type !== 'Identifier') return if (!namespaces.has(dereference.object.name)) return @@ -146,7 +146,7 @@ module.exports = { }, - 'VariableDeclarator': function ({ id, init }) { + VariableDeclarator: function ({ id, init }) { if (init == null) return if (init.type !== 'Identifier') return if (!namespaces.has(init.name)) return @@ -193,6 +193,17 @@ module.exports = { testKey(id, namespaces.get(init.name)) }, + + JSXMemberExpression: function({object, property}) { + if (!namespaces.has(object.name)) return + var namespace = namespaces.get(object.name) + if (!namespace.has(property.name)) { + context.report({ + node: property, + message: makeMessage(property, [object.name]), + }) + } + }, } }, } diff --git a/tests/src/rules/namespace.js b/tests/src/rules/namespace.js index 1cfee2b54d..7fa8cfcdb9 100644 --- a/tests/src/rules/namespace.js +++ b/tests/src/rules/namespace.js @@ -104,6 +104,16 @@ const valid = [ parser: 'babel-eslint', }), + // JSX + test({ + code: 'import * as Names from "./named-exports"; const Foo = ', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }), + ...SYNTAX_CASES, ] @@ -185,6 +195,17 @@ const invalid = [ errors: [`'default' not found in imported namespace 'ree'.`], }), + // JSX + test({ + code: 'import * as Names from "./named-exports"; const Foo = ', + errors: [error('e', 'Names')], + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }), + ] /////////////////////// From 59311419f0546a1f14929a6889a86ec4859486ae Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 13 Aug 2018 00:28:41 -0700 Subject: [PATCH 17/17] Changelog/package bumps --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a7254bc70..3969ea3aac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,26 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## [Unreleased] +## [2.14.0] - 2018-08-13 +* 69e0187 (HEAD -> master, source/master, origin/master, origin/HEAD) Merge pull request #1151 from jf248/jsx +|\ +| * e30a757 (source/pr/1151, fork/jsx) Add JSX check to namespace rule +|/ +* 8252344 (source/pr/1148) Add error to output when module loaded as resolver has invalid API +### Added +- [`no-useless-path-segments`]: add commonJS (CJS) support ([#1128], thanks [@1pete]) +- [`namespace`]: add JSX check ([#1151], thanks [@jf248]) + +### Fixed +- [`no-cycle`]: ignore Flow imports ([#1126], thanks [@gajus]) +- fix Flow type imports ([#1106], thanks [@syymza]) +- [`no-relative-parent-imports`]: resolve paths ([#1135], thanks [@chrislloyd]) +- [`import/order`]: fix autofixer when using typescript-eslint-parser ([#1137], thanks [@justinanastos]) +- repeat fix from [#797] for [#717], in another place (thanks [@ljharb]) + +### Refactors +- add explicit support for RestElement alongside ExperimentalRestProperty (thanks [@ljharb]) + ## [2.13.0] - 2018-06-24 ### Added - Add ESLint 5 support ([#1122], thanks [@ai] and [@ljharb]) @@ -473,7 +493,13 @@ for info on changes for earlier releases. [`memo-parser`]: ./memo-parser/README.md +[#1151]: https://github.com/benmosher/eslint-plugin-import/pull/1151 +[#1137]: https://github.com/benmosher/eslint-plugin-import/pull/1137 +[#1135]: https://github.com/benmosher/eslint-plugin-import/pull/1135 +[#1128]: https://github.com/benmosher/eslint-plugin-import/pull/1128 +[#1126]: https://github.com/benmosher/eslint-plugin-import/pull/1126 [#1122]: https://github.com/benmosher/eslint-plugin-import/pull/1122 +[#1106]: https://github.com/benmosher/eslint-plugin-import/pull/1106 [#1093]: https://github.com/benmosher/eslint-plugin-import/pull/1093 [#1085]: https://github.com/benmosher/eslint-plugin-import/pull/1085 [#1068]: https://github.com/benmosher/eslint-plugin-import/pull/1068 @@ -486,6 +512,7 @@ for info on changes for earlier releases. [#858]: https://github.com/benmosher/eslint-plugin-import/pull/858 [#843]: https://github.com/benmosher/eslint-plugin-import/pull/843 [#871]: https://github.com/benmosher/eslint-plugin-import/pull/871 +[#797]: https://github.com/benmosher/eslint-plugin-import/pull/797 [#744]: https://github.com/benmosher/eslint-plugin-import/pull/744 [#742]: https://github.com/benmosher/eslint-plugin-import/pull/742 [#737]: https://github.com/benmosher/eslint-plugin-import/pull/737 @@ -558,6 +585,7 @@ for info on changes for earlier releases. [#842]: https://github.com/benmosher/eslint-plugin-import/issues/842 [#839]: https://github.com/benmosher/eslint-plugin-import/issues/839 [#720]: https://github.com/benmosher/eslint-plugin-import/issues/720 +[#717]: https://github.com/benmosher/eslint-plugin-import/issues/717 [#686]: https://github.com/benmosher/eslint-plugin-import/issues/686 [#671]: https://github.com/benmosher/eslint-plugin-import/issues/671 [#660]: https://github.com/benmosher/eslint-plugin-import/issues/660 @@ -734,3 +762,8 @@ for info on changes for earlier releases. [@hulkish]: https://github.com/hulkish [@chrislloyd]: https://github.com/chrislloyd [@ai]: https://github.com/ai +[@syymza]: https://github.com/syymza +[@justinanastos]: https://github.com/justinanastos +[@1pete]: https://github.com/1pete +[@gajus]: https://github.com/gajus +[@jf248]: https://github.com/jf248 diff --git a/package.json b/package.json index 7d39395a76..810084436e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-import", - "version": "2.13.0", + "version": "2.14.0", "description": "Import with sanity.", "engines": { "node": ">=4"