Skip to content

Commit

Permalink
[Refactor] namespace: try to improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Feb 22, 2022
1 parent 00a4ede commit b0e6f7f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 40 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
- [Tests] `no-nodejs-modules`: add tests for node protocol URL ([#2367], thanks [@sosukesuzuki])
- [Tests] `default`, `no-anonymous-default-export`, `no-mutable-exports`, `no-named-as-default-member`, `no-named-as-default`: add tests for arbitrary module namespace names ([#2358], thanks [@sosukesuzuki])
- [Docs] [`no-unresolved`]: Fix RegExp escaping in readme ([#2332], thanks [@stephtr])
- [Refactor] `namespace`: try to improve performance ([#2340], thanks [@ljharb])

## [2.25.4] - 2022-01-02

Expand Down Expand Up @@ -1255,6 +1256,7 @@ for info on changes for earlier releases.
[#211]: https://github.com/import-js/eslint-plugin-import/pull/211
[#164]: https://github.com/import-js/eslint-plugin-import/pull/164
[#157]: https://github.com/import-js/eslint-plugin-import/pull/157
[#2340]: https://github.com/import-js/eslint-plugin-import/issues/2340
[#2255]: https://github.com/import-js/eslint-plugin-import/issues/2255
[#2210]: https://github.com/import-js/eslint-plugin-import/issues/2210
[#2201]: https://github.com/import-js/eslint-plugin-import/issues/2201
Expand Down
79 changes: 39 additions & 40 deletions src/rules/namespace.js
Expand Up @@ -3,6 +3,44 @@ import Exports from '../ExportMap';
import importDeclaration from '../importDeclaration';
import docsUrl from '../docsUrl';

function processBodyStatement(context, namespaces, declaration) {
if (declaration.type !== 'ImportDeclaration') return;

if (declaration.specifiers.length === 0) return;

const imports = Exports.get(declaration.source.value, context);
if (imports == null) return null;

if (imports.errors.length > 0) {
imports.reportErrors(context, declaration);
return;
}

declaration.specifiers.forEach((specifier) => {
switch (specifier.type) {
case 'ImportNamespaceSpecifier':
if (!imports.size) {
context.report(
specifier,
`No exported names found in module '${declaration.source.value}'.`,
);
}
namespaces.set(specifier.local.name, imports);
break;
case 'ImportDefaultSpecifier':
case 'ImportSpecifier': {
const meta = imports.get(
// default to 'default' for default https://i.imgur.com/nj6qAWy.jpg
specifier.imported ? (specifier.imported.name || specifier.imported.value) : 'default',
);
if (!meta || !meta.namespace) { break; }
namespaces.set(specifier.local.name, meta.namespace);
break;
}
}
});
}

module.exports = {
meta: {
type: 'problem',
Expand Down Expand Up @@ -41,44 +79,7 @@ module.exports = {
return {
// pick up all imports at body entry time, to properly respect hoisting
Program({ body }) {
function processBodyStatement(declaration) {
if (declaration.type !== 'ImportDeclaration') return;

if (declaration.specifiers.length === 0) return;

const imports = Exports.get(declaration.source.value, context);
if (imports == null) return null;

if (imports.errors.length) {
imports.reportErrors(context, declaration);
return;
}

for (const specifier of declaration.specifiers) {
switch (specifier.type) {
case 'ImportNamespaceSpecifier':
if (!imports.size) {
context.report(
specifier,
`No exported names found in module '${declaration.source.value}'.`,
);
}
namespaces.set(specifier.local.name, imports);
break;
case 'ImportDefaultSpecifier':
case 'ImportSpecifier': {
const meta = imports.get(
// default to 'default' for default https://i.imgur.com/nj6qAWy.jpg
specifier.imported ? (specifier.imported.name || specifier.imported.value) : 'default',
);
if (!meta || !meta.namespace) { break; }
namespaces.set(specifier.local.name, meta.namespace);
break;
}
}
}
}
body.forEach(processBodyStatement);
body.forEach(x => processBodyStatement(context, namespaces, x));
},

// same as above, but does not add names to local map
Expand Down Expand Up @@ -120,7 +121,6 @@ module.exports = {
const namepath = [dereference.object.name];
// while property is namespace and parent is member expression, keep validating
while (namespace instanceof Exports && dereference.type === 'MemberExpression') {

if (dereference.computed) {
if (!allowComputed) {
context.report(
Expand All @@ -147,7 +147,6 @@ module.exports = {
namespace = exported.namespace;
dereference = dereference.parent;
}

},

VariableDeclarator({ id, init }) {
Expand Down

0 comments on commit b0e6f7f

Please sign in to comment.