diff --git a/lib/scope.js b/lib/scope.js index c88ce8fc..e1127c9d 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -320,6 +320,15 @@ function next_mangled_name(scope, options, def) { var in_use = names_in_use(scope, options); var holes = scope.cname_holes; var names = Object.create(null); + // #179, #326 + // in Safari strict mode, something like (function x(x){...}) is a syntax error; + // a function expression's argument cannot shadow the function expression's name + if (options.ie8 && (def.init instanceof AST_Function && def.init.argnames.length > 0)) { + for (var i = 0, len = def.init.argnames.length; i < len; i++) { + var arg = def.init.argnames[i]; + names[arg.definition().mangled_name] = true; + } + } var scopes = [ scope ]; def.references.forEach(function(sym) { var scope = sym.scope; diff --git a/test/mocha/safari9.js b/test/mocha/safari9.js new file mode 100644 index 00000000..278bd181 --- /dev/null +++ b/test/mocha/safari9.js @@ -0,0 +1,26 @@ +var assert = require('assert'); +var UglifyJS = require('../..'); + +describe('legacy safari', function() { + it('Should make sure mangled function name is different from its argument names', function () { + assert.strictEqual( + UglifyJS.minify([ + 'function main() {', + ' "use strict";', + ' ', + ' function n(a,b,c) {', + ' console.log(c)', + ' }', + ' E.on = function f2() {', + ' E.on(function(e) {', + ' return n(this,e)', + ' })', + ' }', + '}' + ].join('\n'), { + ie8: true + }).code, + 'function main(){"use strict";E.on=function(){E.on(function(n){return function c(n,o,t){console.log(t)}()})}}' + ) + }) +})