Browse Source

passing foo to a function cannot rebind foo

contingency-plan
Rich-Harris 10 years ago
parent
commit
01444c971e
  1. 26
      src/Statement.js
  2. 3
      test/form/unmodified-default-exports-function-argument/_config.js
  3. 14
      test/form/unmodified-default-exports-function-argument/_expected/amd.js
  4. 12
      test/form/unmodified-default-exports-function-argument/_expected/cjs.js
  5. 10
      test/form/unmodified-default-exports-function-argument/_expected/es6.js
  6. 14
      test/form/unmodified-default-exports-function-argument/_expected/iife.js
  7. 18
      test/form/unmodified-default-exports-function-argument/_expected/umd.js
  8. 9
      test/form/unmodified-default-exports-function-argument/foo.js
  9. 4
      test/form/unmodified-default-exports-function-argument/main.js
  10. 3
      test/form/unmodified-default-exports/_config.js

26
src/Statement.js

@ -146,7 +146,7 @@ export default class Statement {
} }
checkForWrites ( scope, node ) { checkForWrites ( scope, node ) {
const addNode = ( node, disallowImportReassignments ) => { const addNode = ( node, isAssignment ) => {
let depth = 0; // determine whether we're illegally modifying a binding or namespace let depth = 0; // determine whether we're illegally modifying a binding or namespace
while ( node.type === 'MemberExpression' ) { while ( node.type === 'MemberExpression' ) {
@ -155,7 +155,7 @@ export default class Statement {
} }
// disallow assignments/updates to imported bindings and namespaces // disallow assignments/updates to imported bindings and namespaces
if ( disallowImportReassignments ) { if ( isAssignment ) {
const importSpecifier = this.module.imports[ node.name ]; const importSpecifier = this.module.imports[ node.name ];
if ( importSpecifier && !scope.contains( node.name ) ) { if ( importSpecifier && !scope.contains( node.name ) ) {
@ -170,22 +170,22 @@ export default class Statement {
throw err; throw err;
} }
} }
// special case = `export default foo; foo += 1;` - we'll
// need to assign a new variable so that the exported
// value is not updated by the second statement
if ( this.module.exports.default && depth === 0 && this.module.exports.default.identifier === node.name ) {
// but only if this is a) inside a function body or
// b) after the export declaration
if ( !!scope.parent || node.start > this.module.exports.default.statement.node.start ) {
this.module.exports.default.isModified = true;
}
}
} }
if ( node.type === 'Identifier' ) { if ( node.type === 'Identifier' ) {
this.modifies[ node.name ] = true; this.modifies[ node.name ] = true;
} }
// special case = `export default foo; foo += 1;` - we'll
// need to assign a new variable so that the exported
// value is not updated by the second statement
if ( this.module.exports.default && depth === 0 && this.module.exports.default.identifier === node.name ) {
// but only if this is a) inside a function body or
// b) after the export declaration
if ( !!scope.parent || node.start > this.module.exports.default.statement.node.start ) {
this.module.exports.default.isModified = true;
}
}
}; };
if ( node.type === 'AssignmentExpression' ) { if ( node.type === 'AssignmentExpression' ) {

3
test/form/unmodified-default-exports-function-argument/_config.js

@ -0,0 +1,3 @@
module.exports = {
description: 'passing unbound default export to function cannot rebind it'
};

14
test/form/unmodified-default-exports-function-argument/_expected/amd.js

@ -0,0 +1,14 @@
define(function () { 'use strict';
var foo = function () {
return 42;
};
function bar () {
return contrivedExample( foo );
}
var answer = foo();
var somethingElse = bar();
});

12
test/form/unmodified-default-exports-function-argument/_expected/cjs.js

@ -0,0 +1,12 @@
'use strict';
var foo = function () {
return 42;
};
function bar () {
return contrivedExample( foo );
}
var answer = foo();
var somethingElse = bar();

10
test/form/unmodified-default-exports-function-argument/_expected/es6.js

@ -0,0 +1,10 @@
var foo = function () {
return 42;
};
function bar () {
return contrivedExample( foo );
}
var answer = foo();
var somethingElse = bar();

14
test/form/unmodified-default-exports-function-argument/_expected/iife.js

@ -0,0 +1,14 @@
(function () { 'use strict';
var foo = function () {
return 42;
};
function bar () {
return contrivedExample( foo );
}
var answer = foo();
var somethingElse = bar();
})();

18
test/form/unmodified-default-exports-function-argument/_expected/umd.js

@ -0,0 +1,18 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
typeof define === 'function' && define.amd ? define(factory) :
factory();
}(this, function () { 'use strict';
var foo = function () {
return 42;
};
function bar () {
return contrivedExample( foo );
}
var answer = foo();
var somethingElse = bar();
}));

9
test/form/unmodified-default-exports-function-argument/foo.js

@ -0,0 +1,9 @@
var foo = function () {
return 42;
};
export default foo;
export function bar () {
return contrivedExample( foo );
}

4
test/form/unmodified-default-exports-function-argument/main.js

@ -0,0 +1,4 @@
import foo, { bar } from './foo';
var answer = foo();
var somethingElse = bar();

3
test/form/unmodified-default-exports/_config.js

@ -1,4 +1,3 @@
module.exports = { module.exports = {
description: 'does not treat property assignment as rebinding for sake of unbound default exports', description: 'does not treat property assignment as rebinding for sake of unbound default exports'
// solo: true
}; };

Loading…
Cancel
Save