Path: blob/main/src/rules/no-named-as-default-member.js
829 views
/**1* @fileoverview Rule to warn about potentially confused use of name exports2* @author Desmond Brand3* @copyright 2016 Desmond Brand. All rights reserved.4* See LICENSE in root directory for full license.5*/6import Exports from '../ExportMap';7import importDeclaration from '../importDeclaration';8import docsUrl from '../docsUrl';910//------------------------------------------------------------------------------11// Rule Definition12//------------------------------------------------------------------------------1314module.exports = {15meta: {16type: 'suggestion',17docs: {18url: docsUrl('no-named-as-default-member'),19},20schema: [],21},2223create(context) {2425const fileImports = new Map();26const allPropertyLookups = new Map();2728function handleImportDefault(node) {29const declaration = importDeclaration(context);30const exportMap = Exports.get(declaration.source.value, context);31if (exportMap == null) return;3233if (exportMap.errors.length) {34exportMap.reportErrors(context, declaration);35return;36}3738fileImports.set(node.local.name, {39exportMap,40sourcePath: declaration.source.value,41});42}4344function storePropertyLookup(objectName, propName, node) {45const lookups = allPropertyLookups.get(objectName) || [];46lookups.push({ node, propName });47allPropertyLookups.set(objectName, lookups);48}4950function handlePropLookup(node) {51const objectName = node.object.name;52const propName = node.property.name;53storePropertyLookup(objectName, propName, node);54}5556function handleDestructuringAssignment(node) {57const isDestructure = (58node.id.type === 'ObjectPattern' &&59node.init != null &&60node.init.type === 'Identifier'61);62if (!isDestructure) return;6364const objectName = node.init.name;65for (const { key } of node.id.properties) {66if (key == null) continue; // true for rest properties67storePropertyLookup(objectName, key.name, key);68}69}7071function handleProgramExit() {72allPropertyLookups.forEach((lookups, objectName) => {73const fileImport = fileImports.get(objectName);74if (fileImport == null) return;7576for (const { propName, node } of lookups) {77// the default import can have a "default" property78if (propName === 'default') continue;79if (!fileImport.exportMap.namespace.has(propName)) continue;8081context.report({82node,83message: (84`Caution: \`${objectName}\` also has a named export ` +85`\`${propName}\`. Check if you meant to write ` +86`\`import {${propName}} from '${fileImport.sourcePath}'\` ` +87'instead.'88),89});90}91});92}9394return {95'ImportDefaultSpecifier': handleImportDefault,96'MemberExpression': handlePropLookup,97'VariableDeclarator': handleDestructuringAssignment,98'Program:exit': handleProgramExit,99};100},101};102103104