Skip to content

Commit

Permalink
Revert "remove support for const (#1910)"
Browse files Browse the repository at this point in the history
This reverts commit c391576.
  • Loading branch information
alexlamsl committed May 15, 2017
1 parent ff526be commit cd6e849
Show file tree
Hide file tree
Showing 20 changed files with 591 additions and 36 deletions.
16 changes: 12 additions & 4 deletions lib/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,10 +495,10 @@ var AST_Finally = DEFNODE("Finally", null, {
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
}, AST_Block);

/* -----[ VAR ]----- */
/* -----[ VAR/CONST ]----- */

var AST_Definitions = DEFNODE("Definitions", "definitions", {
$documentation: "Base class for `var` nodes (variable declarations/initializations)",
$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
$propdoc: {
definitions: "[AST_VarDef*] array of variable definitions"
},
Expand All @@ -516,10 +516,14 @@ var AST_Var = DEFNODE("Var", null, {
$documentation: "A `var` statement"
}, AST_Definitions);

var AST_Const = DEFNODE("Const", null, {
$documentation: "A `const` statement"
}, AST_Definitions);

var AST_VarDef = DEFNODE("VarDef", "name value", {
$documentation: "A variable declaration; only appears in a AST_Definitions node",
$propdoc: {
name: "[AST_SymbolVar] name of the variable",
name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",
value: "[AST_Node?] initializer, or null of there's no initializer"
},
_walk: function(visitor) {
Expand Down Expand Up @@ -724,13 +728,17 @@ var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
}, AST_Symbol);

var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
$documentation: "A declaration symbol (symbol in var, function name or argument, symbol in catch)",
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
}, AST_Symbol);

var AST_SymbolVar = DEFNODE("SymbolVar", null, {
$documentation: "Symbol defining a variable",
}, AST_SymbolDeclaration);

var AST_SymbolConst = DEFNODE("SymbolConst", null, {
$documentation: "A constant declaration"
}, AST_SymbolDeclaration);

var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
$documentation: "Symbol naming a function argument",
}, AST_SymbolVar);
Expand Down
19 changes: 15 additions & 4 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ merge(Compressor.prototype, {
if (def.fixed === false) return false;
if (def.fixed != null && (!value || def.references.length > 0)) return false;
return !def.orig.some(function(sym) {
return sym instanceof AST_SymbolDefun
return sym instanceof AST_SymbolConst
|| sym instanceof AST_SymbolDefun
|| sym instanceof AST_SymbolLambda;
});
}
Expand All @@ -503,7 +504,7 @@ merge(Compressor.prototype, {
def.escaped = false;
if (def.scope.uses_eval) {
def.fixed = false;
} else if (!def.global || compressor.toplevel(def)) {
} else if (!def.global || def.orig[0] instanceof AST_SymbolConst || compressor.toplevel(def)) {
def.fixed = undefined;
} else {
def.fixed = false;
Expand Down Expand Up @@ -537,6 +538,14 @@ merge(Compressor.prototype, {
return lhs instanceof AST_SymbolRef && lhs.definition().orig[0] instanceof AST_SymbolLambda;
}

function is_reference_const(ref) {
if (!(ref instanceof AST_SymbolRef)) return false;
var orig = ref.definition().orig;
for (var i = orig.length; --i >= 0;) {
if (orig[i] instanceof AST_SymbolConst) return true;
}
}

function find_variable(compressor, name) {
var scope, i = 0;
while (scope = compressor.parent(i++)) {
Expand Down Expand Up @@ -802,7 +811,8 @@ merge(Compressor.prototype, {
return make_node(AST_SymbolRef, expr.name, expr.name);
}
} else {
return expr[expr instanceof AST_Assign ? "left" : "expression"];
var lhs = expr[expr instanceof AST_Assign ? "left" : "expression"];
return !is_reference_const(lhs) && lhs;
}
}

Expand Down Expand Up @@ -1990,6 +2000,7 @@ merge(Compressor.prototype, {
&& node instanceof AST_Assign
&& node.operator == "="
&& node.left instanceof AST_SymbolRef
&& !is_reference_const(node.left)
&& scope === self) {
node.right.walk(tw);
return true;
Expand Down Expand Up @@ -3196,7 +3207,7 @@ merge(Compressor.prototype, {
&& (left.operator == "++" || left.operator == "--")) {
left = left.expression;
} else left = null;
if (!left || is_lhs_read_only(left)) {
if (!left || is_lhs_read_only(left) || is_reference_const(left)) {
expressions[++i] = cdr;
continue;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/mozilla-ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
});
},
VariableDeclaration: function(M) {
return new AST_Var({
return new (M.kind === "const" ? AST_Const : AST_Var)({
start : my_start_token(M),
end : my_end_token(M),
definitions : M.declarations.map(from_moz)
Expand Down Expand Up @@ -204,7 +204,7 @@
Identifier: function(M) {
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
return new ( p.type == "LabeledStatement" ? AST_Label
: p.type == "VariableDeclarator" && p.id === M ? AST_SymbolVar
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar)
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
: p.type == "CatchClause" ? AST_SymbolCatch
Expand Down Expand Up @@ -324,7 +324,7 @@
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
return {
type: "VariableDeclaration",
kind: "var",
kind: M instanceof AST_Const ? "const" : "var",
declarations: M.definitions.map(to_moz)
};
});
Expand Down
3 changes: 3 additions & 0 deletions lib/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,9 @@ function OutputStream(options) {
DEFPRINT(AST_Var, function(self, output){
self._do_print(output, "var");
});
DEFPRINT(AST_Const, function(self, output){
self._do_print(output, "const");
});

function parenthesize_for_noin(node, output, noin) {
if (!noin) node.print(output);
Expand Down
22 changes: 18 additions & 4 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,9 @@ function parse($TEXT, options) {
case "var":
return tmp = var_(), semicolon(), tmp;

case "const":
return tmp = const_(), semicolon(), tmp;

case "with":
if (S.input.has_directive("use strict")) {
croak("Strict mode may not include a with statement");
Expand Down Expand Up @@ -1146,13 +1149,16 @@ function parse($TEXT, options) {
});
};

function vardefs(no_in) {
function vardefs(no_in, in_const) {
var a = [];
for (;;) {
a.push(new AST_VarDef({
start : S.token,
name : as_symbol(AST_SymbolVar),
value : is("operator", "=") ? (next(), expression(false, no_in)) : null,
name : as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar),
value : is("operator", "=")
? (next(), expression(false, no_in))
: in_const && S.input.has_directive("use strict")
? croak("Missing initializer in const declaration") : null,
end : prev()
}));
if (!is("punc", ","))
Expand All @@ -1165,7 +1171,15 @@ function parse($TEXT, options) {
var var_ = function(no_in) {
return new AST_Var({
start : prev(),
definitions : vardefs(no_in),
definitions : vardefs(no_in, false),
end : prev()
});
};

var const_ = function() {
return new AST_Const({
start : prev(),
definitions : vardefs(false, true),
end : prev()
});
};
Expand Down
7 changes: 5 additions & 2 deletions lib/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
// later.
(node.scope = defun.parent_scope).def_function(node);
}
else if (node instanceof AST_SymbolVar) {
else if (node instanceof AST_SymbolVar
|| node instanceof AST_SymbolConst) {
defun.def_variable(node);
if (defun !== scope) {
node.mark_enclosed(options);
Expand Down Expand Up @@ -267,7 +268,7 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
this.uses_arguments = false;
this.def_variable(new AST_SymbolFunarg({
this.def_variable(new AST_SymbolConst({
name: "arguments",
start: this.start,
end: this.end
Expand Down Expand Up @@ -485,6 +486,8 @@ AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
}
else if (node instanceof AST_Var)
base54.consider("var");
else if (node instanceof AST_Const)
base54.consider("const");
else if (node instanceof AST_Lambda)
base54.consider("function");
else if (node instanceof AST_For)
Expand Down
56 changes: 51 additions & 5 deletions test/compress/collapse_vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,8 @@ collapse_vars_assignment: {
return a = a;
}
function f1(c) {
var a = 3 / c;
var b = 1 - a;
const a = 3 / c;
const b = 1 - a;
return b;
}
function f2(c) {
Expand Down Expand Up @@ -724,10 +724,10 @@ collapse_vars_misc1: {
return t;
}
function f1(x) { var y = 5 - x; return y; }
function f2(x) { var z = foo(), y = z / (5 - x); return y; }
function f2(x) { const z = foo(), y = z / (5 - x); return y; }
function f3(x) { var z = foo(), y = (5 - x) / z; return y; }
function f4(x) { var z = foo(), y = (5 - u) / z; return y; }
function f5(x) { var z = foo(), y = (5 - window.x) / z; return y; }
function f5(x) { const z = foo(), y = (5 - window.x) / z; return y; }
function f6() { var b = window.a * window.z; return b && zap(); }
function f7() { var b = window.a * window.z; return b + b; }
function f8() { var b = window.a * window.z; var c = b + 5; return b + c; }
Expand All @@ -744,7 +744,7 @@ collapse_vars_misc1: {
function f2(x) { return foo() / (5 - x) }
function f3(x) { return (5 - x) / foo() }
function f4(x) { var z = foo(); return (5 - u) / z }
function f5(x) { var z = foo(); return (5 - window.x) / z }
function f5(x) { const z = foo(); return (5 - window.x) / z }
function f6() { return window.a * window.z && zap() }
function f7() { var b = window.a * window.z; return b + b }
function f8() { var b = window.a * window.z; return b + (b + 5) }
Expand Down Expand Up @@ -2186,3 +2186,49 @@ compound_assignment: {
}
expect_stdout: "4"
}

reassign_const_1: {
options = {
collapse_vars: true,
}
input: {
function f() {
const a = 1;
a = 2;
return a;
}
console.log(f());
}
expect: {
function f() {
const a = 1;
a = 2;
return a;
}
console.log(f());
}
expect_stdout: true
}

reassign_const_2: {
options = {
collapse_vars: true,
}
input: {
function f() {
const a = 1;
++a;
return a;
}
console.log(f());
}
expect: {
function f() {
const a = 1;
++a;
return a;
}
console.log(f());
}
expect_stdout: true
}
Loading

0 comments on commit cd6e849

Please sign in to comment.