diff --git a/src/compile/Component.ts b/src/compile/Component.ts index 74c0b2b54c..8ca4852df5 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -142,11 +142,6 @@ export default class Component { } add_var(variable: Var) { - // TODO remove this - if (this.var_lookup.has(variable.name)) { - throw new Error(`dupe: ${variable.name}`); - } - this.vars.push(variable); this.var_lookup.set(variable.name, variable); } @@ -530,7 +525,8 @@ export default class Component { this.add_var({ name, module: true, - hoistable: true + hoistable: true, + writable: kind === 'var' || kind === 'let' }); } }); @@ -845,7 +841,16 @@ export default class Component { this.ast.instance.content.body.forEach(node => { if (node.type === 'VariableDeclaration') { - if (node.declarations.every(d => d.init && d.init.type === 'Literal' && !this.var_lookup.get(d.id.name).reassigned)) { + const all_hoistable = node.declarations.every(d => { + if (!d.init) return false; + if (d.init.type !== 'Literal') return false; + if (this.var_lookup.get(d.id.name).reassigned) return false; + if (this.vars.find(variable => variable.name === d.id.name && variable.module)) return false; + + return true; + }); + + if (all_hoistable) { node.declarations.forEach(d => { const variable = this.var_lookup.get(d.id.name); variable.hoistable = true; diff --git a/test/stats/samples/duplicate-globals/_config.js b/test/stats/samples/duplicate-globals/_config.js new file mode 100644 index 0000000000..71c255d54b --- /dev/null +++ b/test/stats/samples/duplicate-globals/_config.js @@ -0,0 +1,5 @@ +export default { + test(assert, stats) { + assert.deepEqual(stats.vars, []); + }, +}; diff --git a/test/stats/samples/duplicate-globals/input.html b/test/stats/samples/duplicate-globals/input.html new file mode 100644 index 0000000000..e7c004f54a --- /dev/null +++ b/test/stats/samples/duplicate-globals/input.html @@ -0,0 +1,7 @@ +<script context="module"> + console.log(1); +</script> + +<script> + console.log(2); +</script> \ No newline at end of file diff --git a/test/stats/samples/duplicate-non-hoistable/_config.js b/test/stats/samples/duplicate-non-hoistable/_config.js new file mode 100644 index 0000000000..4b598412a9 --- /dev/null +++ b/test/stats/samples/duplicate-non-hoistable/_config.js @@ -0,0 +1,16 @@ +export default { + test(assert, stats) { + assert.deepEqual(stats.vars, [ + { + name: 'console', + injected: false, + export_name: null, + module: false, + mutated: false, + reassigned: false, + referenced: true, + writable: true + } + ]); + }, +}; diff --git a/test/stats/samples/duplicate-non-hoistable/input.html b/test/stats/samples/duplicate-non-hoistable/input.html new file mode 100644 index 0000000000..90f7734008 --- /dev/null +++ b/test/stats/samples/duplicate-non-hoistable/input.html @@ -0,0 +1,9 @@ +<script context="module"> + console.log(1); +</script> + +<script> + var console = 42; +</script> + +<p>{console}</p> \ No newline at end of file diff --git a/test/stats/samples/duplicate-vars/_config.js b/test/stats/samples/duplicate-vars/_config.js new file mode 100644 index 0000000000..f4f71fe021 --- /dev/null +++ b/test/stats/samples/duplicate-vars/_config.js @@ -0,0 +1,26 @@ +export default { + test(assert, stats) { + assert.deepEqual(stats.vars, [ + { + name: 'foo', + injected: false, + export_name: null, + module: true, + mutated: false, + reassigned: false, + referenced: false, + writable: true + }, + { + name: 'foo', + injected: false, + export_name: null, + module: false, + mutated: false, + reassigned: false, + referenced: true, + writable: true + } + ]); + }, +}; diff --git a/test/stats/samples/duplicate-vars/input.html b/test/stats/samples/duplicate-vars/input.html new file mode 100644 index 0000000000..20c48738db --- /dev/null +++ b/test/stats/samples/duplicate-vars/input.html @@ -0,0 +1,9 @@ +<script context="module"> + var foo = 1; +</script> + +<script> + var foo = 2; +</script> + +<p>{foo}</p> \ No newline at end of file