@@ -1375,6 +1375,11 @@ Compressor.prototype.compress = function(node) {
|
||||
var d = this.definition();
|
||||
if (!d.first_decl && d.references.length == 0) d.first_decl = this;
|
||||
});
|
||||
def(AST_SymbolDefun, function() {
|
||||
var d = this.definition();
|
||||
if (!d.first_decl && d.references.length == 0) d.first_decl = this;
|
||||
if (d.orig.length > 1 && d.scope.resolve() !== this.scope) d.fixed = false;
|
||||
});
|
||||
def(AST_SymbolImport, function() {
|
||||
var d = this.definition();
|
||||
d.first_decl = this;
|
||||
@@ -1893,6 +1898,7 @@ Compressor.prototype.compress = function(node) {
|
||||
if (stat instanceof AST_LambdaDefinition) {
|
||||
var def = stat.name.definition();
|
||||
var scope = stat.name.scope;
|
||||
if (def.orig.length > 1 && def.scope.resolve() !== scope) return false;
|
||||
return def.scope === scope || all(def.references, function(ref) {
|
||||
var s = ref.scope;
|
||||
do {
|
||||
@@ -2405,6 +2411,7 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
var read_toplevel = false;
|
||||
var modify_toplevel = false;
|
||||
var defun_scopes = get_defun_scopes(lhs);
|
||||
// Locate symbols which may execute code outside of scanning range
|
||||
var enclosed = new Dictionary();
|
||||
var well_defined = true;
|
||||
@@ -2535,8 +2542,11 @@ Compressor.prototype.compress = function(node) {
|
||||
if (parent instanceof AST_For) {
|
||||
if (node !== parent.init) return true;
|
||||
}
|
||||
if (node instanceof AST_Assign) {
|
||||
return node.operator != "=" && lhs.equals(node.left);
|
||||
if (node instanceof AST_Assign) return node.operator != "=" && lhs.equals(node.left);
|
||||
if (node instanceof AST_BlockStatement) {
|
||||
return defun_scopes && !all(defun_scopes, function(scope) {
|
||||
return node !== scope;
|
||||
});
|
||||
}
|
||||
if (node instanceof AST_Call) {
|
||||
if (!(lhs instanceof AST_PropAccess)) return false;
|
||||
@@ -3437,6 +3447,33 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
}
|
||||
|
||||
function get_defun_scopes(lhs) {
|
||||
if (!(lhs instanceof AST_SymbolDeclaration
|
||||
|| lhs instanceof AST_SymbolRef
|
||||
|| lhs instanceof AST_Destructured)) return;
|
||||
var scopes = [];
|
||||
lhs.mark_symbol(function(node) {
|
||||
if (node instanceof AST_Symbol) {
|
||||
var def = node.definition();
|
||||
var scope = def.scope.resolve();
|
||||
var found = false;
|
||||
var avoid = def.orig.reduce(function(scopes, sym) {
|
||||
if (sym instanceof AST_SymbolDefun) {
|
||||
if (sym.scope !== scope) push_uniq(scopes, sym.scope);
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
return scopes;
|
||||
}, []);
|
||||
if (found) avoid.forEach(function(scope) {
|
||||
push_uniq(scopes, scope);
|
||||
});
|
||||
}
|
||||
});
|
||||
if (scopes.length == 0) return;
|
||||
return scopes;
|
||||
}
|
||||
|
||||
function is_lhs_local(lhs) {
|
||||
var sym = root_expr(lhs);
|
||||
if (!(sym instanceof AST_SymbolRef)) return false;
|
||||
|
||||
@@ -47,3 +47,45 @@ keep_some_blocks: {
|
||||
} else stuff();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1666: {
|
||||
input: {
|
||||
var a = 42;
|
||||
{
|
||||
function a() {}
|
||||
a();
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
{
|
||||
function a() {}
|
||||
a();
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_strict: {
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 42;
|
||||
{
|
||||
function a() {}
|
||||
a();
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = 42;
|
||||
{
|
||||
function a() {}
|
||||
a();
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -10172,3 +10172,115 @@ issue_5779: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_1666: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect: {
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_undefined: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect: {
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_undefined_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -8222,3 +8222,127 @@ issue_5777_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_1666: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect: {
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_strict: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_undefined: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect: {
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_undefined_strict: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user