From 6df94aa651b3b9e71aa87b50ce0a2f5bca6f29b0 Mon Sep 17 00:00:00 2001
From: Richard Harris <richard.a.harris@gmail.com>
Date: Sun, 3 Feb 2019 20:00:18 -0500
Subject: [PATCH] remove unnecessary dupe check - fixes #2036

---
 src/compile/Component.ts                      | 19 +++++++++-----
 .../samples/duplicate-globals/_config.js      |  5 ++++
 .../samples/duplicate-globals/input.html      |  7 +++++
 .../duplicate-non-hoistable/_config.js        | 16 ++++++++++++
 .../duplicate-non-hoistable/input.html        |  9 +++++++
 test/stats/samples/duplicate-vars/_config.js  | 26 +++++++++++++++++++
 test/stats/samples/duplicate-vars/input.html  |  9 +++++++
 7 files changed, 84 insertions(+), 7 deletions(-)
 create mode 100644 test/stats/samples/duplicate-globals/_config.js
 create mode 100644 test/stats/samples/duplicate-globals/input.html
 create mode 100644 test/stats/samples/duplicate-non-hoistable/_config.js
 create mode 100644 test/stats/samples/duplicate-non-hoistable/input.html
 create mode 100644 test/stats/samples/duplicate-vars/_config.js
 create mode 100644 test/stats/samples/duplicate-vars/input.html

diff --git a/src/compile/Component.ts b/src/compile/Component.ts
index c9304ee54a..73756e4c1d 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'
 				});
 			}
 		});
@@ -840,7 +836,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