From ab767b125d7c3fdbf07839b8105448dc49ed79e5 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 6 Feb 2016 18:37:04 -0500 Subject: [PATCH 1/9] warn on empty exports, dont fail (closes #486) --- src/Module.js | 40 +++++++++++++------------- test/function/empty-exports/_config.js | 17 +++++++++++ test/function/empty-exports/main.js | 1 + 3 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 test/function/empty-exports/_config.js create mode 100644 test/function/empty-exports/main.js diff --git a/src/Module.js b/src/Module.js index 7764a08..4b2e7d4 100644 --- a/src/Module.js +++ b/src/Module.js @@ -102,37 +102,37 @@ export default class Module { this.declarations.default = new SyntheticDefaultDeclaration( node, statement, identifier || this.basename() ); } - // export { foo, bar, baz } // export var { foo, bar } = ... // export var foo = 42; // export var a = 1, b = 2, c = 3; // export function foo () {} - else if ( node.type === 'ExportNamedDeclaration' ) { + else if ( node.declaration ) { + let declaration = node.declaration; + + if ( declaration.type === 'VariableDeclaration' ) { + declaration.declarations.forEach( decl => { + extractNames( decl.id ).forEach( localName => { + this.exports[ localName ] = { localName }; + }); + }); + } else { + // export function foo () {} + const localName = declaration.id.name; + this.exports[ localName ] = { localName }; + } + } + + // export { foo, bar, baz } + else { if ( node.specifiers.length ) { - // export { foo, bar, baz } node.specifiers.forEach( specifier => { const localName = specifier.local.name; const exportedName = specifier.exported.name; this.exports[ exportedName ] = { localName }; }); - } - - else { - let declaration = node.declaration; - - if ( declaration.type === 'VariableDeclaration' ) { - declaration.declarations.forEach( decl => { - extractNames( decl.id ).forEach( localName => { - this.exports[ localName ] = { localName }; - }); - }); - } - else { - // export function foo () {} - const localName = declaration.id.name; - this.exports[ localName ] = { localName }; - } + } else { + this.bundle.onwarn( `Module ${this.id} has an empty export declaration` ); } } } diff --git a/test/function/empty-exports/_config.js b/test/function/empty-exports/_config.js new file mode 100644 index 0000000..65b2185 --- /dev/null +++ b/test/function/empty-exports/_config.js @@ -0,0 +1,17 @@ +var assert = require( 'assert' ); + +var warned = false; + +module.exports = { + description: 'warns on export {}, but does not fail', + options: { + onwarn: function ( msg ) { + warned = true; + assert.ok( /main\.js has an empty export declaration/.test( msg ) ); + } + }, + exports: function ( exports ) { + assert.equal( Object.keys( exports ).length, 0 ); + assert.ok( warned, 'did not warn' ); + } +}; diff --git a/test/function/empty-exports/main.js b/test/function/empty-exports/main.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/test/function/empty-exports/main.js @@ -0,0 +1 @@ +export {}; From 57a3c574f6db3715c9bfb2715d5e9662e957e4b8 Mon Sep 17 00:00:00 2001 From: Mateusz Krzeszowiak Date: Sun, 7 Feb 2016 23:06:06 +0100 Subject: [PATCH 2/9] Fixes rollup/rollup#493 --- src/finalisers/iife.js | 2 +- src/finalisers/umd.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 95c6d65..1d4dfb2 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -31,7 +31,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString } } if ( exportMode === 'named' ) { - dependencies.unshift( `(this.${name} = {})` ); + dependencies.unshift( `(this.${name} = this.${name} || {})` ); args.unshift( 'exports' ); } diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 3e8e813..e0d18e1 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -31,7 +31,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, if ( exportMode === 'named' ) { amdDeps.unshift( `'exports'` ); cjsDeps.unshift( `exports` ); - globalDeps.unshift( `(${setupNamespace(options.moduleName)} = {})` ); + globalDeps.unshift( `(${setupNamespace(options.moduleName)} = global.${options.moduleName} || {})` ); args.unshift( 'exports' ); } From afed9d4d437187d2973df1119f049e081a2fb9ad Mon Sep 17 00:00:00 2001 From: Mateusz Krzeszowiak Date: Sun, 7 Feb 2016 23:06:22 +0100 Subject: [PATCH 3/9] Test fixes rollup/rollup#493 --- test/form/computed-properties/_expected/iife.js | 2 +- test/form/computed-properties/_expected/umd.js | 4 ++-- test/form/dedupes-external-imports/_expected/iife.js | 2 +- test/form/dedupes-external-imports/_expected/umd.js | 4 ++-- test/form/export-all-from-internal/_expected/iife.js | 2 +- test/form/export-all-from-internal/_expected/umd.js | 4 ++-- test/form/exports-at-end-if-possible/_expected/iife.js | 2 +- test/form/exports-at-end-if-possible/_expected/umd.js | 4 ++-- test/form/multiple-exports/_expected/iife.js | 2 +- test/form/multiple-exports/_expected/umd.js | 4 ++-- test/form/namespaced-named-exports/_expected/iife.js | 2 +- test/form/namespaced-named-exports/_expected/umd.js | 4 ++-- test/form/preserves-comments-after-imports/_expected/iife.js | 2 +- test/form/preserves-comments-after-imports/_expected/umd.js | 4 ++-- 14 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/form/computed-properties/_expected/iife.js b/test/form/computed-properties/_expected/iife.js index 35b80af..963508a 100644 --- a/test/form/computed-properties/_expected/iife.js +++ b/test/form/computed-properties/_expected/iife.js @@ -7,4 +7,4 @@ exports.x = x; -}((this.computedProperties = {}))); \ No newline at end of file +}((this.computedProperties = this.computedProperties || {}))); diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index 5f7d146..1414460 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.computedProperties = {}))); + (factory((global.computedProperties = global.computedProperties || {}))); }(this, function (exports) { 'use strict'; var foo = 'foo'; @@ -10,4 +10,4 @@ exports.x = x; -})); \ No newline at end of file +})); diff --git a/test/form/dedupes-external-imports/_expected/iife.js b/test/form/dedupes-external-imports/_expected/iife.js index 17ed0b7..57e6649 100644 --- a/test/form/dedupes-external-imports/_expected/iife.js +++ b/test/form/dedupes-external-imports/_expected/iife.js @@ -30,4 +30,4 @@ exports.bar = bar; exports.baz = baz; -}((this.myBundle = {}),external)); +}((this.myBundle = this.myBundle || {}),external)); diff --git a/test/form/dedupes-external-imports/_expected/umd.js b/test/form/dedupes-external-imports/_expected/umd.js index 70bc301..e33aca8 100644 --- a/test/form/dedupes-external-imports/_expected/umd.js +++ b/test/form/dedupes-external-imports/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('external')) : typeof define === 'function' && define.amd ? define(['exports', 'external'], factory) : - (factory((global.myBundle = {}),global.external)); + (factory((global.myBundle = global.myBundle || {}),global.external)); }(this, function (exports,external) { 'use strict'; class Foo extends external.Component { @@ -33,4 +33,4 @@ exports.bar = bar; exports.baz = baz; -})); \ No newline at end of file +})); diff --git a/test/form/export-all-from-internal/_expected/iife.js b/test/form/export-all-from-internal/_expected/iife.js index b5dad56..8a3cd17 100644 --- a/test/form/export-all-from-internal/_expected/iife.js +++ b/test/form/export-all-from-internal/_expected/iife.js @@ -7,4 +7,4 @@ exports.a = a; exports.b = b; -}((this.exposedInternals = {}))); +}((this.exposedInternals = this.exposedInternals || {}))); diff --git a/test/form/export-all-from-internal/_expected/umd.js b/test/form/export-all-from-internal/_expected/umd.js index 74613b4..c1bf8a9 100644 --- a/test/form/export-all-from-internal/_expected/umd.js +++ b/test/form/export-all-from-internal/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.exposedInternals = {}))); + (factory((global.exposedInternals = global.exposedInternals || {}))); }(this, function (exports) { 'use strict'; const a = 1; @@ -10,4 +10,4 @@ exports.a = a; exports.b = b; -})); \ No newline at end of file +})); diff --git a/test/form/exports-at-end-if-possible/_expected/iife.js b/test/form/exports-at-end-if-possible/_expected/iife.js index a0ce6a9..1c5c67b 100644 --- a/test/form/exports-at-end-if-possible/_expected/iife.js +++ b/test/form/exports-at-end-if-possible/_expected/iife.js @@ -9,4 +9,4 @@ exports.FOO = FOO; -}((this.myBundle = {}))); +}((this.myBundle = this.myBundle || {}))); diff --git a/test/form/exports-at-end-if-possible/_expected/umd.js b/test/form/exports-at-end-if-possible/_expected/umd.js index 20d0d2a..09b2ea6 100644 --- a/test/form/exports-at-end-if-possible/_expected/umd.js +++ b/test/form/exports-at-end-if-possible/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.myBundle = {}))); + (factory((global.myBundle = global.myBundle || {}))); }(this, function (exports) { 'use strict'; var FOO = 'foo'; @@ -12,4 +12,4 @@ exports.FOO = FOO; -})); \ No newline at end of file +})); diff --git a/test/form/multiple-exports/_expected/iife.js b/test/form/multiple-exports/_expected/iife.js index 3a3975d..d2da90f 100644 --- a/test/form/multiple-exports/_expected/iife.js +++ b/test/form/multiple-exports/_expected/iife.js @@ -7,4 +7,4 @@ exports.foo = foo; exports.bar = bar; -}((this.myBundle = {}))); +}((this.myBundle = this.myBundle || {}))); diff --git a/test/form/multiple-exports/_expected/umd.js b/test/form/multiple-exports/_expected/umd.js index 485e381..32d762a 100644 --- a/test/form/multiple-exports/_expected/umd.js +++ b/test/form/multiple-exports/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.myBundle = {}))); + (factory((global.myBundle = global.myBundle || {}))); }(this, function (exports) { 'use strict'; var foo = 1; @@ -10,4 +10,4 @@ exports.foo = foo; exports.bar = bar; -})); \ No newline at end of file +})); diff --git a/test/form/namespaced-named-exports/_expected/iife.js b/test/form/namespaced-named-exports/_expected/iife.js index 2fc75df..69637e9 100644 --- a/test/form/namespaced-named-exports/_expected/iife.js +++ b/test/form/namespaced-named-exports/_expected/iife.js @@ -7,4 +7,4 @@ this.foo.bar = this.foo.bar || {}; exports.answer = answer; -}((this.foo.bar.baz = {}))); +}((this.foo.bar.baz = this.foo.bar.baz || {}))); diff --git a/test/form/namespaced-named-exports/_expected/umd.js b/test/form/namespaced-named-exports/_expected/umd.js index aeb7775..3717913 100644 --- a/test/form/namespaced-named-exports/_expected/umd.js +++ b/test/form/namespaced-named-exports/_expected/umd.js @@ -1,11 +1,11 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.foo = global.foo || {}, global.foo.bar = global.foo.bar || {}, global.foo.bar.baz = {}))); + (factory((global.foo = global.foo || {}, global.foo.bar = global.foo.bar || {}, global.foo.bar.baz = global.foo.bar.baz || {}))); }(this, function (exports) { 'use strict'; var answer = 42; exports.answer = answer; -})); \ No newline at end of file +})); diff --git a/test/form/preserves-comments-after-imports/_expected/iife.js b/test/form/preserves-comments-after-imports/_expected/iife.js index e9338dc..ee4c000 100644 --- a/test/form/preserves-comments-after-imports/_expected/iife.js +++ b/test/form/preserves-comments-after-imports/_expected/iife.js @@ -9,4 +9,4 @@ exports.obj = obj; -}((this.myBundle = {}))); +}((this.myBundle = this.myBundle || {}))); diff --git a/test/form/preserves-comments-after-imports/_expected/umd.js b/test/form/preserves-comments-after-imports/_expected/umd.js index ac58856..4d34fef 100644 --- a/test/form/preserves-comments-after-imports/_expected/umd.js +++ b/test/form/preserves-comments-after-imports/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.myBundle = {}))); + (factory((global.myBundle = global.myBundle || {}))); }(this, function (exports) { 'use strict'; /** A comment for a number */ @@ -12,4 +12,4 @@ exports.obj = obj; -})); \ No newline at end of file +})); From 92703bf46db0e18536cfc6817fed2498b3be10e2 Mon Sep 17 00:00:00 2001 From: Mateusz Krzeszowiak Date: Mon, 8 Feb 2016 11:31:01 +0100 Subject: [PATCH 4/9] Remove empty lines at the end of files added by Atom --- test/form/computed-properties/_expected/iife.js | 2 +- test/form/computed-properties/_expected/umd.js | 2 +- test/form/dedupes-external-imports/_expected/umd.js | 2 +- test/form/export-all-from-internal/_expected/umd.js | 2 +- test/form/exports-at-end-if-possible/_expected/umd.js | 2 +- test/form/multiple-exports/_expected/umd.js | 2 +- test/form/namespaced-named-exports/_expected/umd.js | 2 +- test/form/preserves-comments-after-imports/_expected/umd.js | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/form/computed-properties/_expected/iife.js b/test/form/computed-properties/_expected/iife.js index 963508a..5e8b95c 100644 --- a/test/form/computed-properties/_expected/iife.js +++ b/test/form/computed-properties/_expected/iife.js @@ -7,4 +7,4 @@ exports.x = x; -}((this.computedProperties = this.computedProperties || {}))); +}((this.computedProperties = this.computedProperties || {}))); \ No newline at end of file diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index 1414460..dde36f1 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -10,4 +10,4 @@ exports.x = x; -})); +})); \ No newline at end of file diff --git a/test/form/dedupes-external-imports/_expected/umd.js b/test/form/dedupes-external-imports/_expected/umd.js index e33aca8..06be0e7 100644 --- a/test/form/dedupes-external-imports/_expected/umd.js +++ b/test/form/dedupes-external-imports/_expected/umd.js @@ -33,4 +33,4 @@ exports.bar = bar; exports.baz = baz; -})); +})); \ No newline at end of file diff --git a/test/form/export-all-from-internal/_expected/umd.js b/test/form/export-all-from-internal/_expected/umd.js index c1bf8a9..b249cc6 100644 --- a/test/form/export-all-from-internal/_expected/umd.js +++ b/test/form/export-all-from-internal/_expected/umd.js @@ -10,4 +10,4 @@ exports.a = a; exports.b = b; -})); +})); \ No newline at end of file diff --git a/test/form/exports-at-end-if-possible/_expected/umd.js b/test/form/exports-at-end-if-possible/_expected/umd.js index 09b2ea6..e9cbc8d 100644 --- a/test/form/exports-at-end-if-possible/_expected/umd.js +++ b/test/form/exports-at-end-if-possible/_expected/umd.js @@ -12,4 +12,4 @@ exports.FOO = FOO; -})); +})); \ No newline at end of file diff --git a/test/form/multiple-exports/_expected/umd.js b/test/form/multiple-exports/_expected/umd.js index 32d762a..30a54d6 100644 --- a/test/form/multiple-exports/_expected/umd.js +++ b/test/form/multiple-exports/_expected/umd.js @@ -10,4 +10,4 @@ exports.foo = foo; exports.bar = bar; -})); +})); \ No newline at end of file diff --git a/test/form/namespaced-named-exports/_expected/umd.js b/test/form/namespaced-named-exports/_expected/umd.js index 3717913..9a0f47d 100644 --- a/test/form/namespaced-named-exports/_expected/umd.js +++ b/test/form/namespaced-named-exports/_expected/umd.js @@ -8,4 +8,4 @@ exports.answer = answer; -})); +})); \ No newline at end of file diff --git a/test/form/preserves-comments-after-imports/_expected/umd.js b/test/form/preserves-comments-after-imports/_expected/umd.js index 4d34fef..13a54bf 100644 --- a/test/form/preserves-comments-after-imports/_expected/umd.js +++ b/test/form/preserves-comments-after-imports/_expected/umd.js @@ -12,4 +12,4 @@ exports.obj = obj; -})); +})); \ No newline at end of file From 2a29d4bde346e7b4c7f376838b0e73e86ddc2e2f Mon Sep 17 00:00:00 2001 From: Olivier Chafik Date: Tue, 9 Feb 2016 14:41:08 +0000 Subject: [PATCH 5/9] Retain symbols of computed properties defined on classes. (fixes #504, similar fix as #439) --- src/ast/isReference.js | 5 +++- .../form/computed-properties/_expected/amd.js | 18 ++++++++++---- .../form/computed-properties/_expected/cjs.js | 12 +++++++++- .../form/computed-properties/_expected/es6.js | 11 ++++++++- .../computed-properties/_expected/iife.js | 20 ++++++++++++---- .../form/computed-properties/_expected/umd.js | 24 +++++++++++++------ test/form/computed-properties/main.js | 9 +++++++ 7 files changed, 80 insertions(+), 19 deletions(-) diff --git a/src/ast/isReference.js b/src/ast/isReference.js index 0c9a9d7..661b865 100644 --- a/src/ast/isReference.js +++ b/src/ast/isReference.js @@ -10,7 +10,10 @@ export default function isReference ( node, parent ) { if ( !parent ) return true; // TODO is this right? - if ( parent.type === 'MemberExpression' ) return parent.computed || node === parent.object; + if ( parent.type === 'MemberExpression' || + parent.type === 'MethodDefinition' ) { + return parent.computed || node === parent.object; + } // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }` if ( parent.type === 'Property' ) return parent.computed || node === parent.value; diff --git a/test/form/computed-properties/_expected/amd.js b/test/form/computed-properties/_expected/amd.js index 4fd933f..d055e21 100644 --- a/test/form/computed-properties/_expected/amd.js +++ b/test/form/computed-properties/_expected/amd.js @@ -1,9 +1,19 @@ define(['exports'], function (exports) { 'use strict'; - var foo = 'foo'; + var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = {[foo]: 'bar'}; - exports.x = x; + class X { + [bar]() {} + get [baz]() {} + set [bam](value) {} + } -}); \ No newline at end of file + exports.x = x; + exports.X = X; + +}); diff --git a/test/form/computed-properties/_expected/cjs.js b/test/form/computed-properties/_expected/cjs.js index 22126d8..b4ad690 100644 --- a/test/form/computed-properties/_expected/cjs.js +++ b/test/form/computed-properties/_expected/cjs.js @@ -1,7 +1,17 @@ 'use strict'; var foo = 'foo'; +var bar = 'bar'; +var baz = 'baz'; +var bam = 'bam'; var x = {[foo]: 'bar'}; -exports.x = x; \ No newline at end of file +class X { + [bar]() {} + get [baz]() {} + set [bam](value) {} +} + +exports.x = x; +exports.X = X; diff --git a/test/form/computed-properties/_expected/es6.js b/test/form/computed-properties/_expected/es6.js index 6dc09ca..9f9ad6f 100644 --- a/test/form/computed-properties/_expected/es6.js +++ b/test/form/computed-properties/_expected/es6.js @@ -1,5 +1,14 @@ var foo = 'foo'; +var bar = 'bar'; +var baz = 'baz'; +var bam = 'bam'; var x = {[foo]: 'bar'}; -export { x }; \ No newline at end of file +class X { + [bar]() {} + get [baz]() {} + set [bam](value) {} +} + +export { x, X }; diff --git a/test/form/computed-properties/_expected/iife.js b/test/form/computed-properties/_expected/iife.js index 35b80af..8e1363a 100644 --- a/test/form/computed-properties/_expected/iife.js +++ b/test/form/computed-properties/_expected/iife.js @@ -1,10 +1,20 @@ (function (exports) { - 'use strict'; + 'use strict'; - var foo = 'foo'; + var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = {[foo]: 'bar'}; - exports.x = x; + class X { + [bar]() {} + get [baz]() {} + set [bam](value) {} + } -}((this.computedProperties = {}))); \ No newline at end of file + exports.x = x; + exports.X = X; + +}((this.computedProperties = {}))); diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index 5f7d146..8564446 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -1,13 +1,23 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.computedProperties = {}))); + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.computedProperties = {}))); }(this, function (exports) { 'use strict'; - var foo = 'foo'; + var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = {[foo]: 'bar'}; - exports.x = x; + class X { + [bar]() {} + get [baz]() {} + set [bam](value) {} + } -})); \ No newline at end of file + exports.x = x; + exports.X = X; + +})); diff --git a/test/form/computed-properties/main.js b/test/form/computed-properties/main.js index 65bb97c..6c18a1f 100644 --- a/test/form/computed-properties/main.js +++ b/test/form/computed-properties/main.js @@ -1,3 +1,12 @@ var foo = 'foo'; +var bar = 'bar'; +var baz = 'baz'; +var bam = 'bam'; export var x = {[foo]: 'bar'}; + +export class X { + [bar]() {} + get [baz]() {} + set [bam](value) {} +} From b748464f711f0b81da287c83ed2c02716853efab Mon Sep 17 00:00:00 2001 From: kzc Date: Fri, 12 Feb 2016 11:51:43 -0500 Subject: [PATCH 6/9] Detect side effect in member expression assignment when not top level. Fixes #476. --- src/utils/run.js | 2 ++ .../_config.js | 10 ++++++++++ .../member-expression-assignment-in-function/main.js | 9 +++++++++ 3 files changed, 21 insertions(+) create mode 100644 test/function/member-expression-assignment-in-function/_config.js create mode 100644 test/function/member-expression-assignment-in-function/main.js diff --git a/src/utils/run.js b/src/utils/run.js index 4470305..b57149d 100644 --- a/src/utils/run.js +++ b/src/utils/run.js @@ -95,6 +95,8 @@ export default function run ( node, scope, statement, strongDependencies, force if ( declaration ) { if ( declaration.isParam ) hasSideEffect = true; + } else if ( !scope.isTopLevel ) { + hasSideEffect = true; } else { declaration = statement.module.trace( subject.name ); diff --git a/test/function/member-expression-assignment-in-function/_config.js b/test/function/member-expression-assignment-in-function/_config.js new file mode 100644 index 0000000..bf7e6fc --- /dev/null +++ b/test/function/member-expression-assignment-in-function/_config.js @@ -0,0 +1,10 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'detect side effect in member expression assignment when not top level', + code: function ( code ) { + assert.equal( code.indexOf( 'function set(key, value) { foo[key] = value; }' ) >= 0, true, code ); + assert.equal( code.indexOf( 'set("bar", 2);' ) >= 0, true, code ); + assert.equal( code.indexOf( 'set("qux", 3);' ) >= 0, true, code ); + } +} diff --git a/test/function/member-expression-assignment-in-function/main.js b/test/function/member-expression-assignment-in-function/main.js new file mode 100644 index 0000000..f627721 --- /dev/null +++ b/test/function/member-expression-assignment-in-function/main.js @@ -0,0 +1,9 @@ +var foo = {}; + +function set(key, value) { foo[key] = value; } + +set("bar", 2); +set("qux", 3); + +console.log(foo); + From fe21dc85c87b875188f63eb0c2c68a308f4b9d73 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 14 Feb 2016 08:36:22 -0500 Subject: [PATCH 7/9] linting, consistency --- src/ast/isReference.js | 3 +- .../form/computed-properties/_expected/amd.js | 26 +++++++-------- .../form/computed-properties/_expected/cjs.js | 10 +++--- .../form/computed-properties/_expected/es6.js | 10 +++--- .../computed-properties/_expected/iife.js | 28 ++++++++-------- .../form/computed-properties/_expected/umd.js | 32 +++++++++---------- test/form/computed-properties/main.js | 8 ++--- 7 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/ast/isReference.js b/src/ast/isReference.js index 661b865..c2e6c89 100644 --- a/src/ast/isReference.js +++ b/src/ast/isReference.js @@ -10,8 +10,7 @@ export default function isReference ( node, parent ) { if ( !parent ) return true; // TODO is this right? - if ( parent.type === 'MemberExpression' || - parent.type === 'MethodDefinition' ) { + if ( parent.type === 'MemberExpression' || parent.type === 'MethodDefinition' ) { return parent.computed || node === parent.object; } diff --git a/test/form/computed-properties/_expected/amd.js b/test/form/computed-properties/_expected/amd.js index d055e21..0ccd4d8 100644 --- a/test/form/computed-properties/_expected/amd.js +++ b/test/form/computed-properties/_expected/amd.js @@ -1,19 +1,19 @@ define(['exports'], function (exports) { 'use strict'; - var foo = 'foo'; - var bar = 'bar'; - var baz = 'baz'; - var bam = 'bam'; + var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = { [foo]: 'bar' }; - class X { - [bar]() {} - get [baz]() {} - set [bam](value) {} - } + class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} + } - exports.x = x; - exports.X = X; + exports.x = x; + exports.X = X; -}); +}); \ No newline at end of file diff --git a/test/form/computed-properties/_expected/cjs.js b/test/form/computed-properties/_expected/cjs.js index b4ad690..443bab3 100644 --- a/test/form/computed-properties/_expected/cjs.js +++ b/test/form/computed-properties/_expected/cjs.js @@ -5,13 +5,13 @@ var bar = 'bar'; var baz = 'baz'; var bam = 'bam'; -var x = {[foo]: 'bar'}; +var x = { [foo]: 'bar' }; class X { - [bar]() {} - get [baz]() {} - set [bam](value) {} + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} } exports.x = x; -exports.X = X; +exports.X = X; \ No newline at end of file diff --git a/test/form/computed-properties/_expected/es6.js b/test/form/computed-properties/_expected/es6.js index 9f9ad6f..d818b11 100644 --- a/test/form/computed-properties/_expected/es6.js +++ b/test/form/computed-properties/_expected/es6.js @@ -3,12 +3,12 @@ var bar = 'bar'; var baz = 'baz'; var bam = 'bam'; -var x = {[foo]: 'bar'}; +var x = { [foo]: 'bar' }; class X { - [bar]() {} - get [baz]() {} - set [bam](value) {} + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} } -export { x, X }; +export { x, X }; \ No newline at end of file diff --git a/test/form/computed-properties/_expected/iife.js b/test/form/computed-properties/_expected/iife.js index 8e1363a..512a498 100644 --- a/test/form/computed-properties/_expected/iife.js +++ b/test/form/computed-properties/_expected/iife.js @@ -1,20 +1,20 @@ (function (exports) { - 'use strict'; + 'use strict'; - var foo = 'foo'; - var bar = 'bar'; - var baz = 'baz'; - var bam = 'bam'; + var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = { [foo]: 'bar' }; - class X { - [bar]() {} - get [baz]() {} - set [bam](value) {} - } + class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} + } - exports.x = x; - exports.X = X; + exports.x = x; + exports.X = X; -}((this.computedProperties = {}))); +}((this.computedProperties = {}))); \ No newline at end of file diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index 8564446..97a29ea 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -1,23 +1,23 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.computedProperties = {}))); + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.computedProperties = {}))); }(this, function (exports) { 'use strict'; - var foo = 'foo'; - var bar = 'bar'; - var baz = 'baz'; - var bam = 'bam'; + var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = { [foo]: 'bar' }; - class X { - [bar]() {} - get [baz]() {} - set [bam](value) {} - } + class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} + } - exports.x = x; - exports.X = X; + exports.x = x; + exports.X = X; -})); +})); \ No newline at end of file diff --git a/test/form/computed-properties/main.js b/test/form/computed-properties/main.js index 6c18a1f..6cfc64a 100644 --- a/test/form/computed-properties/main.js +++ b/test/form/computed-properties/main.js @@ -3,10 +3,10 @@ var bar = 'bar'; var baz = 'baz'; var bam = 'bam'; -export var x = {[foo]: 'bar'}; +export var x = { [foo]: 'bar' }; export class X { - [bar]() {} - get [baz]() {} - set [bam](value) {} + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} } From 884803d1f419259085c44bf733f7d93ba151ee1b Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 14 Feb 2016 09:05:39 -0500 Subject: [PATCH 8/9] ensure external modules stay in sequence --- src/Bundle.js | 5 ++--- src/utils/promise.js | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 src/utils/promise.js diff --git a/src/Bundle.js b/src/Bundle.js index b0ef4ac..dcddf13 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -10,6 +10,7 @@ import { load, makeOnwarn, resolveId } from './utils/defaults.js'; import getExportMode from './utils/getExportMode.js'; import getIndentString from './utils/getIndentString.js'; import { unixizePath } from './utils/normalizePlatform.js'; +import { mapSequence } from './utils/promise.js'; import transform from './utils/transform.js'; import transformBundle from './utils/transformBundle.js'; import collapseSourcemaps from './utils/collapseSourcemaps.js'; @@ -175,7 +176,7 @@ export default class Bundle { } fetchAllDependencies ( module ) { - const promises = module.sources.map( source => { + return mapSequence( module.sources, source => { return this.resolveId( source, module.id ) .then( resolvedId => { // If the `resolvedId` is supposed to be external, make it so. @@ -205,8 +206,6 @@ export default class Bundle { } }); }); - - return Promise.all( promises ); } render ( options = {} ) { diff --git a/src/utils/promise.js b/src/utils/promise.js new file mode 100644 index 0000000..1730de8 --- /dev/null +++ b/src/utils/promise.js @@ -0,0 +1,16 @@ +import Promise from 'es6-promise/lib/es6-promise/promise.js'; + +export function mapSequence ( array, fn ) { + let results = []; + let promise = Promise.resolve(); + + function next ( member, i ) { + return fn( member ).then( value => results[i] = value ); + } + + for ( let i = 0; i < array.length; i += 1 ) { + promise = promise.then( () => next( array[i], i ) ); + } + + return promise.then( () => results ); +} From 6b80842dedfdbdf9c22f848a93ad714dde6e0bb5 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 14 Feb 2016 09:07:20 -0500 Subject: [PATCH 9/9] linting --- src/Bundle.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bundle.js b/src/Bundle.js index dcddf13..bdb7da8 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -1,4 +1,3 @@ -import Promise from 'es6-promise/lib/es6-promise/promise.js'; import MagicString from 'magic-string'; import first from './utils/first.js'; import { blank, forOwn, keys } from './utils/object.js';