fix reduce_vars on AST_Defun (#2708)
This commit is contained in:
parent
446fb0198b
commit
14778e049b
|
|
@ -316,7 +316,7 @@ merge(Compressor.prototype, {
|
||||||
if (def.scope.uses_eval || def.scope.uses_with) {
|
if (def.scope.uses_eval || def.scope.uses_with) {
|
||||||
def.fixed = false;
|
def.fixed = false;
|
||||||
} else if (!compressor.exposed(def)) {
|
} else if (!compressor.exposed(def)) {
|
||||||
def.fixed = undefined;
|
def.fixed = def.init;
|
||||||
} else {
|
} else {
|
||||||
def.fixed = false;
|
def.fixed = false;
|
||||||
}
|
}
|
||||||
|
|
@ -329,10 +329,12 @@ merge(Compressor.prototype, {
|
||||||
function reset_variables(tw, compressor, node) {
|
function reset_variables(tw, compressor, node) {
|
||||||
node.variables.each(function(def) {
|
node.variables.each(function(def) {
|
||||||
reset_def(compressor, def);
|
reset_def(compressor, def);
|
||||||
if (def.fixed === undefined && def.orig[0].TYPE == "SymbolVar") {
|
if (def.fixed === null) {
|
||||||
def.fixed = null;
|
|
||||||
def.safe_ids = tw.safe_ids;
|
def.safe_ids = tw.safe_ids;
|
||||||
mark(tw, def, true);
|
mark(tw, def, true);
|
||||||
|
} else if (def.fixed) {
|
||||||
|
tw.loop_ids[def.id] = tw.in_loop;
|
||||||
|
mark(tw, def, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -504,15 +506,6 @@ merge(Compressor.prototype, {
|
||||||
});
|
});
|
||||||
def(AST_Defun, function(tw, descend, compressor) {
|
def(AST_Defun, function(tw, descend, compressor) {
|
||||||
this.inlined = false;
|
this.inlined = false;
|
||||||
var d = this.name.definition();
|
|
||||||
if (compressor.exposed(d) || safe_to_read(tw, d)) {
|
|
||||||
d.fixed = false;
|
|
||||||
} else {
|
|
||||||
d.fixed = this;
|
|
||||||
d.single_use = ref_once(tw, compressor, d);
|
|
||||||
tw.loop_ids[d.id] = tw.in_loop;
|
|
||||||
mark(tw, d, true);
|
|
||||||
}
|
|
||||||
var save_ids = tw.safe_ids;
|
var save_ids = tw.safe_ids;
|
||||||
tw.safe_ids = Object.create(null);
|
tw.safe_ids = Object.create(null);
|
||||||
reset_variables(tw, compressor, this);
|
reset_variables(tw, compressor, this);
|
||||||
|
|
|
||||||
25
lib/scope.js
25
lib/scope.js
|
|
@ -43,9 +43,10 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function SymbolDef(scope, orig) {
|
function SymbolDef(scope, orig, init) {
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
|
this.init = init;
|
||||||
this.eliminated = 0;
|
this.eliminated = 0;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.references = [];
|
this.references = [];
|
||||||
|
|
@ -158,10 +159,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||||
// scope when we encounter the AST_Defun node (which is
|
// scope when we encounter the AST_Defun node (which is
|
||||||
// instanceof AST_Scope) but we get to the symbol a bit
|
// instanceof AST_Scope) but we get to the symbol a bit
|
||||||
// later.
|
// later.
|
||||||
(node.scope = defun.parent_scope).def_function(node);
|
(node.scope = defun.parent_scope).def_function(node, defun);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolVar) {
|
else if (node instanceof AST_SymbolVar) {
|
||||||
defun.def_variable(node);
|
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||||
if (defun !== scope) {
|
if (defun !== scope) {
|
||||||
node.mark_enclosed(options);
|
node.mark_enclosed(options);
|
||||||
var def = scope.find_variable(node);
|
var def = scope.find_variable(node);
|
||||||
|
|
@ -306,21 +307,21 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
AST_Scope.DEFMETHOD("def_function", function(symbol, init){
|
||||||
var def = this.def_variable(symbol);
|
var def = this.def_variable(symbol, init);
|
||||||
|
if (!def.init) def.init = init;
|
||||||
this.functions.set(symbol.name, def);
|
this.functions.set(symbol.name, def);
|
||||||
return def;
|
return def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
|
||||||
var def;
|
var def = this.variables.get(symbol.name);
|
||||||
if (!this.variables.has(symbol.name)) {
|
if (def) {
|
||||||
def = new SymbolDef(this, symbol);
|
def.orig.push(symbol);
|
||||||
|
} else {
|
||||||
|
def = new SymbolDef(this, symbol, init);
|
||||||
this.variables.set(symbol.name, def);
|
this.variables.set(symbol.name, def);
|
||||||
def.global = !this.parent_scope;
|
def.global = !this.parent_scope;
|
||||||
} else {
|
|
||||||
def = this.variables.get(symbol.name);
|
|
||||||
def.orig.push(symbol);
|
|
||||||
}
|
}
|
||||||
return symbol.thedef = def;
|
return symbol.thedef = def;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4999,3 +4999,241 @@ var_if: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defun_assign: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof a);
|
||||||
|
a = 42;
|
||||||
|
console.log(typeof a);
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof a);
|
||||||
|
a = 42;
|
||||||
|
console.log(typeof a);
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"function",
|
||||||
|
"number",
|
||||||
|
"number",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42, b;
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
}
|
||||||
|
expect_stdout: "number function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
var a = 42, b;
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {}
|
||||||
|
var a = 42;
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
}
|
||||||
|
expect_stdout: "number function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
var a = 42, b;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
var a = 42;
|
||||||
|
}
|
||||||
|
expect_stdout: "function function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
function a() {}
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
function a() {}
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_4: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
function a() {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
function a() {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_5: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_6: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ typeof_defun_1: {
|
||||||
g = 42;
|
g = 42;
|
||||||
console.log("YES");
|
console.log("YES");
|
||||||
"function" == typeof g && g();
|
"function" == typeof g && g();
|
||||||
h();
|
"function" == typeof h && h();
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"YES",
|
"YES",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user