diff --git a/src/Statement.js b/src/Statement.js index 94d43a2..042d939 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -156,16 +156,29 @@ export default class Statement { checkForWrites ( scope, node ) { const addNode = ( node, disallowImportReassignments ) => { + let depth = 0; // determine whether we're illegally modifying a binding or namespace + while ( node.type === 'MemberExpression' ) { node = node.object; + depth += 1; } // disallow assignments/updates to imported bindings and namespaces - if ( disallowImportReassignments && has( this.module.imports, node.name ) && !scope.contains( node.name ) ) { - const err = new Error( `Illegal reassignment to import '${node.name}'` ); - err.file = this.module.path; - err.loc = getLocation( this.module.magicString.toString(), node.start ); - throw err; + if ( disallowImportReassignments ) { + const importSpecifier = this.module.imports[ node.name ]; + + if ( importSpecifier && !scope.contains( node.name ) ) { + const minDepth = importSpecifier.name === '*' ? + 2 : // cannot do e.g. `namespace.foo = bar` + 1; // cannot do e.g. `foo = bar`, but `foo.bar = bar` is fine + + if ( depth < minDepth ) { + const err = new Error( `Illegal reassignment to import '${node.name}'` ); + err.file = this.module.path; + err.loc = getLocation( this.module.magicString.toString(), node.start ); + throw err; + } + } } if ( node.type !== 'Identifier' ) { diff --git a/test/function/legal-import-modification/_config.js b/test/function/legal-import-modification/_config.js new file mode 100644 index 0000000..3792857 --- /dev/null +++ b/test/function/legal-import-modification/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'assigning to properties of imported bindings is permitted' +}; diff --git a/test/function/legal-import-modification/foo.js b/test/function/legal-import-modification/foo.js new file mode 100644 index 0000000..ff8b4c5 --- /dev/null +++ b/test/function/legal-import-modification/foo.js @@ -0,0 +1 @@ +export default {}; diff --git a/test/function/legal-import-modification/main.js b/test/function/legal-import-modification/main.js new file mode 100644 index 0000000..455d804 --- /dev/null +++ b/test/function/legal-import-modification/main.js @@ -0,0 +1,5 @@ +import foo from './foo'; + +foo.modified = true; + +export default foo;