diff --git a/src/ast/nodes/VariableDeclarator.js b/src/ast/nodes/VariableDeclarator.js index 61ca51b..dc35bff 100644 --- a/src/ast/nodes/VariableDeclarator.js +++ b/src/ast/nodes/VariableDeclarator.js @@ -11,12 +11,14 @@ class DeclaratorProxy { this.isReassigned = false; this.exportName = null; + this.duplicates = []; this.possibleValues = new Set( init ? [ init ] : null ); } activate () { this.activated = true; this.declarator.activate(); + this.duplicates.forEach( dupe => dupe.activate() ); } addReference () { diff --git a/src/ast/scopes/Scope.js b/src/ast/scopes/Scope.js index c77e6d2..25512b7 100644 --- a/src/ast/scopes/Scope.js +++ b/src/ast/scopes/Scope.js @@ -1,3 +1,5 @@ +import getLocation from '../../utils/getLocation.js'; +import error from '../../utils/error.js'; import { blank, keys } from '../../utils/object.js'; import { UNKNOWN } from '../values.js'; @@ -49,7 +51,14 @@ export default class Scope { if ( isVar && this.isBlockScope ) { this.parent.addDeclaration( name, declaration, isVar, isParam ); } else { - this.declarations[ name ] = isParam ? new Parameter( name ) : declaration; + const existingDeclaration = this.declarations[ name ]; + + if ( existingDeclaration && existingDeclaration.duplicates ) { + // TODO warn/throw on duplicates? + existingDeclaration.duplicates.push( declaration ); + } else { + this.declarations[ name ] = isParam ? new Parameter( name ) : declaration; + } } } diff --git a/test/form/duplicated-var-declarations/_config.js b/test/form/duplicated-var-declarations/_config.js index 1dd69da..4c3038c 100644 --- a/test/form/duplicated-var-declarations/_config.js +++ b/test/form/duplicated-var-declarations/_config.js @@ -1,4 +1,3 @@ module.exports = { - skip: true, description: 'does not remove duplicated var declarations (#716)' }; diff --git a/test/form/duplicated-var-declarations/_expected/amd.js b/test/form/duplicated-var-declarations/_expected/amd.js new file mode 100644 index 0000000..b43e2a4 --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/amd.js @@ -0,0 +1,17 @@ +define(function () { 'use strict'; + + var a = 1; + var b = 2; + + assert.equal( a, 1 ); + assert.equal( b, 2 ); + + var a = 3; + var b = 4; + var c = 5; + + assert.equal( a, 3 ); + assert.equal( b, 4 ); + assert.equal( c, 5 ); + +}); diff --git a/test/form/duplicated-var-declarations/_expected/cjs.js b/test/form/duplicated-var-declarations/_expected/cjs.js new file mode 100644 index 0000000..e47b61a --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/cjs.js @@ -0,0 +1,15 @@ +'use strict'; + +var a = 1; +var b = 2; + +assert.equal( a, 1 ); +assert.equal( b, 2 ); + +var a = 3; +var b = 4; +var c = 5; + +assert.equal( a, 3 ); +assert.equal( b, 4 ); +assert.equal( c, 5 ); diff --git a/test/form/duplicated-var-declarations/_expected/es.js b/test/form/duplicated-var-declarations/_expected/es.js new file mode 100644 index 0000000..cacf6d2 --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/es.js @@ -0,0 +1,13 @@ +var a = 1; +var b = 2; + +assert.equal( a, 1 ); +assert.equal( b, 2 ); + +var a = 3; +var b = 4; +var c = 5; + +assert.equal( a, 3 ); +assert.equal( b, 4 ); +assert.equal( c, 5 ); diff --git a/test/form/duplicated-var-declarations/_expected/iife.js b/test/form/duplicated-var-declarations/_expected/iife.js new file mode 100644 index 0000000..106066a --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/iife.js @@ -0,0 +1,18 @@ +(function () { + 'use strict'; + + var a = 1; + var b = 2; + + assert.equal( a, 1 ); + assert.equal( b, 2 ); + + var a = 3; + var b = 4; + var c = 5; + + assert.equal( a, 3 ); + assert.equal( b, 4 ); + assert.equal( c, 5 ); + +}()); diff --git a/test/form/duplicated-var-declarations/_expected/umd.js b/test/form/duplicated-var-declarations/_expected/umd.js new file mode 100644 index 0000000..4574799 --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/umd.js @@ -0,0 +1,21 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + var a = 1; + var b = 2; + + assert.equal( a, 1 ); + assert.equal( b, 2 ); + + var a = 3; + var b = 4; + var c = 5; + + assert.equal( a, 3 ); + assert.equal( b, 4 ); + assert.equal( c, 5 ); + +})));