Refactoring
step 1
This commit is contained in:
parent
ba3a59843a
commit
10db7a5ef4
32
demo.cola
Normal file
32
demo.cola
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
function main(){
|
||||
console.log(`
|
||||
|
||||
Hello!
|
||||
My name is ColaScript, and i know who you are }:->
|
||||
@{navigator.userAgent}
|
||||
|
||||
`);
|
||||
|
||||
console.log("pow:", 5 ** 2, "; modulo:", 5 %% 3, ";");
|
||||
|
||||
var a = 3.14, b = 584;
|
||||
|
||||
a ?= b; console.log(a);
|
||||
a = undefined;
|
||||
a ?= b; console.log(a);
|
||||
|
||||
console.log(`is:`, location.href is String, `; isnt:`, 123 isnt Number, ";");
|
||||
|
||||
if(yes === true && on === true && no === false && off === false) console.log('Boolean alternatives');
|
||||
|
||||
console.log('Raw string:', r`@test \n \t \r`);
|
||||
var isEmail = /
|
||||
([\w-\.]+)
|
||||
@
|
||||
((?:[\w]+\.)+)
|
||||
([a-zA-Z]{2,4})
|
||||
/, email = r'danon0404@gmail.com';
|
||||
console.log("@email is email:", isEmail.test(email));
|
||||
}
|
||||
|
||||
main();
|
||||
421
lib/ast.js
421
lib/ast.js
|
|
@ -45,9 +45,10 @@
|
|||
***********************************************************************/
|
||||
|
||||
"use strict";
|
||||
!window.Cola && (window.Cola = {});
|
||||
|
||||
function DEFNODE(type, props, methods, base) {
|
||||
if (arguments.length < 4) base = AST_Node;
|
||||
Cola.DEFNODE = function (type, props, methods, base) {
|
||||
if (arguments.length < 4) base = Cola.AST_Node;
|
||||
if (!props) props = [];
|
||||
else props = props.split(/\s+/);
|
||||
var self_props = props;
|
||||
|
|
@ -87,10 +88,10 @@ function DEFNODE(type, props, methods, base) {
|
|||
return ctor;
|
||||
};
|
||||
|
||||
var AST_Token = DEFNODE("Token", "type value line col pos endpos nlb comments_before file" /* ColaScropt + " endcol endline"*/, {
|
||||
Cola.AST_Token = Cola.DEFNODE("Token", "type value line col pos endpos nlb comments_before file", {
|
||||
}, null);
|
||||
|
||||
var AST_Node = DEFNODE("Node", "start end", {
|
||||
Cola.AST_Node = Cola.DEFNODE("Node", "start end", {
|
||||
clone: function() {
|
||||
return new this.CTOR(this);
|
||||
},
|
||||
|
|
@ -107,44 +108,44 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||
}
|
||||
}, null);
|
||||
|
||||
AST_Node.warn_function = null;
|
||||
AST_Node.warn = function(txt, props) {
|
||||
if (AST_Node.warn_function)
|
||||
AST_Node.warn_function(string_template(txt, props));
|
||||
Cola.AST_Node.warn_function = null;
|
||||
Cola.AST_Node.warn = function(txt, props) {
|
||||
if (Cola.AST_Node.warn_function)
|
||||
Cola.AST_Node.warn_function(Cola.string_template(txt, props));
|
||||
};
|
||||
|
||||
/* -----[ statements ]----- */
|
||||
|
||||
var AST_Statement = DEFNODE("Statement", null, {
|
||||
Cola.AST_Statement = Cola.DEFNODE("Statement", null, {
|
||||
$documentation: "Base class of all statements",
|
||||
});
|
||||
|
||||
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||
Cola.AST_Debugger = Cola.DEFNODE("Debugger", null, {
|
||||
$documentation: "Represents a debugger statement",
|
||||
}, AST_Statement);
|
||||
}, Cola.AST_Statement);
|
||||
|
||||
var AST_Directive = DEFNODE("Directive", "value scope", {
|
||||
Cola.AST_Directive = Cola.DEFNODE("Directive", "value scope", {
|
||||
$documentation: "Represents a directive, like \"use strict\";",
|
||||
$propdoc: {
|
||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||
scope: "[AST_Scope/S] The scope that this directive affects"
|
||||
},
|
||||
}, AST_Statement);
|
||||
}, Cola.AST_Statement);
|
||||
|
||||
var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
Cola.AST_SimpleStatement = Cola.DEFNODE("SimpleStatement", "body", {
|
||||
$documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
|
||||
$propdoc: {
|
||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
|
||||
body: "[AST_Node] an expression node (should not be instanceof Cola.AST_Statement)"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
}, Cola.AST_Statement);
|
||||
|
||||
function walk_body(node, visitor) {
|
||||
if (node.body instanceof AST_Statement) {
|
||||
Cola.walk_body = function (node, visitor) {
|
||||
if (node.body instanceof Cola.AST_Statement) {
|
||||
node.body._walk(visitor);
|
||||
}
|
||||
else node.body.forEach(function(stat){
|
||||
|
|
@ -152,30 +153,30 @@ function walk_body(node, visitor) {
|
|||
});
|
||||
};
|
||||
|
||||
var AST_Block = DEFNODE("Block", "body", {
|
||||
Cola.AST_Block = Cola.DEFNODE("Block", "body", {
|
||||
$documentation: "A body of statements (usually bracketed)",
|
||||
$propdoc: {
|
||||
body: "[AST_Statement*] an array of statements"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
walk_body(this, visitor);
|
||||
Cola.walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
}, Cola.AST_Statement);
|
||||
|
||||
var AST_BlockStatement = DEFNODE("BlockStatement", null, {
|
||||
Cola.AST_BlockStatement = Cola.DEFNODE("BlockStatement", null, {
|
||||
$documentation: "A block statement",
|
||||
}, AST_Block);
|
||||
}, Cola.AST_Block);
|
||||
|
||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||
Cola.AST_EmptyStatement = Cola.DEFNODE("EmptyStatement", null, {
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this);
|
||||
}
|
||||
}, AST_Statement);
|
||||
}, Cola.AST_Statement);
|
||||
|
||||
var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
||||
Cola.AST_StatementWithBody = Cola.DEFNODE("StatementWithBody", "body", {
|
||||
$documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
|
||||
$propdoc: {
|
||||
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
||||
|
|
@ -185,9 +186,9 @@ var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
|||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
}, Cola.AST_Statement);
|
||||
|
||||
var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
Cola.AST_LabeledStatement = Cola.DEFNODE("LabeledStatement", "label", {
|
||||
$documentation: "Statement with a label",
|
||||
$propdoc: {
|
||||
label: "[AST_Label] a label definition"
|
||||
|
|
@ -198,16 +199,16 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_StatementWithBody);
|
||||
}, Cola.AST_StatementWithBody);
|
||||
|
||||
var AST_IterationStatement = DEFNODE("IterationStatement", null, {
|
||||
Cola.AST_IterationStatement = Cola.DEFNODE("IterationStatement", null, {
|
||||
$documentation: "Internal class. All loops inherit from it."
|
||||
}, AST_StatementWithBody);
|
||||
}, Cola.AST_StatementWithBody);
|
||||
|
||||
var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
||||
Cola.AST_DWLoop = Cola.DEFNODE("DWLoop", "condition", {
|
||||
$documentation: "Base class for do/while statements",
|
||||
$propdoc: {
|
||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||
condition: "[AST_Node] the loop condition. Should not be instanceof Cola.AST_Statement"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
|
|
@ -215,17 +216,17 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
|||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_IterationStatement);
|
||||
}, Cola.AST_IterationStatement);
|
||||
|
||||
var AST_Do = DEFNODE("Do", null, {
|
||||
Cola.AST_Do = Cola.DEFNODE("Do", null, {
|
||||
$documentation: "A `do` statement",
|
||||
}, AST_DWLoop);
|
||||
}, Cola.AST_DWLoop);
|
||||
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
Cola.AST_While = Cola.DEFNODE("While", null, {
|
||||
$documentation: "A `while` statement",
|
||||
}, AST_DWLoop);
|
||||
}, Cola.AST_DWLoop);
|
||||
|
||||
var AST_For = DEFNODE("For", "init condition step", {
|
||||
Cola.AST_For = Cola.DEFNODE("For", "init condition step", {
|
||||
$documentation: "A `for` statement",
|
||||
$propdoc: {
|
||||
init: "[AST_Node?] the `for` initialization code, or null if empty",
|
||||
|
|
@ -240,9 +241,9 @@ var AST_For = DEFNODE("For", "init condition step", {
|
|||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_IterationStatement);
|
||||
}, Cola.AST_IterationStatement);
|
||||
|
||||
var AST_ForIn = DEFNODE("ForIn", "init name object", {
|
||||
Cola.AST_ForIn = Cola.DEFNODE("ForIn", "init name object", {
|
||||
$documentation: "A `for ... in` statement",
|
||||
$propdoc: {
|
||||
init: "[AST_Node] the `for/in` initialization code",
|
||||
|
|
@ -256,9 +257,9 @@ var AST_ForIn = DEFNODE("ForIn", "init name object", {
|
|||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_IterationStatement);
|
||||
}, Cola.AST_IterationStatement);
|
||||
|
||||
var AST_With = DEFNODE("With", "expression", {
|
||||
Cola.AST_With = Cola.DEFNODE("With", "expression", {
|
||||
$documentation: "A `with` statement",
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `with` expression"
|
||||
|
|
@ -269,11 +270,11 @@ var AST_With = DEFNODE("With", "expression", {
|
|||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_StatementWithBody);
|
||||
}, Cola.AST_StatementWithBody);
|
||||
|
||||
/* -----[ scope and functions ]----- */
|
||||
|
||||
var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||
Cola.AST_Scope = Cola.DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||
$documentation: "Base class for all statements introducing a lexical scope",
|
||||
$propdoc: {
|
||||
directives: "[string*/S] an array of directives declared in this scope",
|
||||
|
|
@ -285,9 +286,9 @@ var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_
|
|||
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
||||
cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
|
||||
},
|
||||
}, AST_Block);
|
||||
}, Cola.AST_Block);
|
||||
|
||||
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals", {
|
||||
$documentation: "The toplevel scope",
|
||||
$propdoc: {
|
||||
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
||||
|
|
@ -305,10 +306,10 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||
});
|
||||
|
||||
var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")";
|
||||
wrapped_tl = parse(wrapped_tl);
|
||||
wrapped_tl = Cola.parse(wrapped_tl);
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||
return MAP.splice(self.body);
|
||||
if (node instanceof Cola.AST_Directive && node.value == "$ORIG") {
|
||||
return Cola.MAP.splice(self.body);
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
|
|
@ -319,43 +320,43 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||
if (export_all) {
|
||||
self.figure_out_scope();
|
||||
self.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_SymbolDeclaration && node.definition().global) {
|
||||
if (!find_if(function(n){ return n.name == node.name }, to_export))
|
||||
if (node instanceof Cola.AST_SymbolDeclaration && node.definition().global) {
|
||||
if (!Cola.find_if(function(n){ return n.name == node.name }, to_export))
|
||||
to_export.push(node);
|
||||
}
|
||||
}));
|
||||
}
|
||||
var wrapped_tl = "(function(exports, global){ global['" + name + "'] = exports; '$ORIG'; '$EXPORTS'; }({}, (function(){return this}())))";
|
||||
wrapped_tl = parse(wrapped_tl);
|
||||
wrapped_tl = Cola.parse(wrapped_tl);
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||
if (node instanceof AST_SimpleStatement) {
|
||||
if (node instanceof Cola.AST_SimpleStatement) {
|
||||
node = node.body;
|
||||
if (node instanceof AST_String) switch (node.getValue()) {
|
||||
if (node instanceof Cola.AST_String) switch (node.getValue()) {
|
||||
case "$ORIG":
|
||||
return MAP.splice(self.body);
|
||||
return Cola.MAP.splice(self.body);
|
||||
case "$EXPORTS":
|
||||
var body = [];
|
||||
to_export.forEach(function(sym){
|
||||
body.push(new AST_SimpleStatement({
|
||||
body: new AST_Assign({
|
||||
left: new AST_Sub({
|
||||
expression: new AST_SymbolRef({ name: "exports" }),
|
||||
property: new AST_String({ value: sym.name }),
|
||||
body.push(new Cola.AST_SimpleStatement({
|
||||
body: new Cola.AST_Assign({
|
||||
left: new Cola.AST_Sub({
|
||||
expression: new Cola.AST_SymbolRef({ name: "exports" }),
|
||||
property: new Cola.AST_String({ value: sym.name }),
|
||||
}),
|
||||
operator: "=",
|
||||
right: new AST_SymbolRef(sym),
|
||||
right: new Cola.AST_SymbolRef(sym),
|
||||
}),
|
||||
}));
|
||||
});
|
||||
return MAP.splice(body);
|
||||
return Cola.MAP.splice(body);
|
||||
}
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
}
|
||||
}, AST_Scope);
|
||||
}, Cola.AST_Scope);
|
||||
|
||||
var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
Cola.AST_Lambda = Cola.DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
$documentation: "Base class for functions",
|
||||
$propdoc: {
|
||||
name: "[AST_SymbolDeclaration?] the name of this function",
|
||||
|
|
@ -368,30 +369,30 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
|||
this.argnames.forEach(function(arg){
|
||||
arg._walk(visitor);
|
||||
});
|
||||
walk_body(this, visitor);
|
||||
Cola.walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Scope);
|
||||
}, Cola.AST_Scope);
|
||||
|
||||
var AST_Accessor = DEFNODE("Accessor", null, {
|
||||
Cola.AST_Accessor = Cola.DEFNODE("Accessor", null, {
|
||||
$documentation: "A setter/getter function. The `name` property is always null."
|
||||
}, AST_Lambda);
|
||||
}, Cola.AST_Lambda);
|
||||
|
||||
var AST_Function = DEFNODE("Function", null, {
|
||||
Cola.AST_Function = Cola.DEFNODE("Function", null, {
|
||||
$documentation: "A function expression"
|
||||
}, AST_Lambda);
|
||||
}, Cola.AST_Lambda);
|
||||
|
||||
var AST_Defun = DEFNODE("Defun", null, {
|
||||
Cola.AST_Defun = Cola.DEFNODE("Defun", null, {
|
||||
$documentation: "A function definition"
|
||||
}, AST_Lambda);
|
||||
}, Cola.AST_Lambda);
|
||||
|
||||
/* -----[ JUMPS ]----- */
|
||||
|
||||
var AST_Jump = DEFNODE("Jump", null, {
|
||||
Cola.AST_Jump = Cola.DEFNODE("Jump", null, {
|
||||
$documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
|
||||
}, AST_Statement);
|
||||
}, Cola.AST_Statement);
|
||||
|
||||
var AST_Exit = DEFNODE("Exit", "value", {
|
||||
Cola.AST_Exit = Cola.DEFNODE("Exit", "value", {
|
||||
$documentation: "Base class for “exits” (`return` and `throw`)",
|
||||
$propdoc: {
|
||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||
|
|
@ -401,17 +402,17 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
|||
this.value._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Jump);
|
||||
}, Cola.AST_Jump);
|
||||
|
||||
var AST_Return = DEFNODE("Return", null, {
|
||||
Cola.AST_Return = Cola.DEFNODE("Return", null, {
|
||||
$documentation: "A `return` statement"
|
||||
}, AST_Exit);
|
||||
}, Cola.AST_Exit);
|
||||
|
||||
var AST_Throw = DEFNODE("Throw", null, {
|
||||
Cola.AST_Throw = Cola.DEFNODE("Throw", null, {
|
||||
$documentation: "A `throw` statement"
|
||||
}, AST_Exit);
|
||||
}, Cola.AST_Exit);
|
||||
|
||||
var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
||||
Cola.AST_LoopControl = Cola.DEFNODE("LoopControl", "label", {
|
||||
$documentation: "Base class for loop control statements (`break` and `continue`)",
|
||||
$propdoc: {
|
||||
label: "[AST_LabelRef?] the label, or null if none",
|
||||
|
|
@ -421,19 +422,19 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
|||
this.label._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Jump);
|
||||
}, Cola.AST_Jump);
|
||||
|
||||
var AST_Break = DEFNODE("Break", null, {
|
||||
Cola.AST_Break = Cola.DEFNODE("Break", null, {
|
||||
$documentation: "A `break` statement"
|
||||
}, AST_LoopControl);
|
||||
}, Cola.AST_LoopControl);
|
||||
|
||||
var AST_Continue = DEFNODE("Continue", null, {
|
||||
Cola.AST_Continue = Cola.DEFNODE("Continue", null, {
|
||||
$documentation: "A `continue` statement"
|
||||
}, AST_LoopControl);
|
||||
}, Cola.AST_LoopControl);
|
||||
|
||||
/* -----[ IF ]----- */
|
||||
|
||||
var AST_If = DEFNODE("If", "condition alternative", {
|
||||
Cola.AST_If = Cola.DEFNODE("If", "condition alternative", {
|
||||
$documentation: "A `if` statement",
|
||||
$propdoc: {
|
||||
condition: "[AST_Node] the `if` condition",
|
||||
|
|
@ -446,11 +447,11 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
|||
if (this.alternative) this.alternative._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_StatementWithBody);
|
||||
}, Cola.AST_StatementWithBody);
|
||||
|
||||
/* -----[ SWITCH ]----- */
|
||||
|
||||
var AST_Switch = DEFNODE("Switch", "expression", {
|
||||
Cola.AST_Switch = Cola.DEFNODE("Switch", "expression", {
|
||||
$documentation: "A `switch` statement",
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `switch` “discriminant”"
|
||||
|
|
@ -458,20 +459,20 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
|||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.expression._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
Cola.walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Block);
|
||||
}, Cola.AST_Block);
|
||||
|
||||
var AST_SwitchBranch = DEFNODE("SwitchBranch", null, {
|
||||
Cola.AST_SwitchBranch = Cola.DEFNODE("SwitchBranch", null, {
|
||||
$documentation: "Base class for `switch` branches",
|
||||
}, AST_Block);
|
||||
}, Cola.AST_Block);
|
||||
|
||||
var AST_Default = DEFNODE("Default", null, {
|
||||
Cola.AST_Default = Cola.DEFNODE("Default", null, {
|
||||
$documentation: "A `default` switch branch",
|
||||
}, AST_SwitchBranch);
|
||||
}, Cola.AST_SwitchBranch);
|
||||
|
||||
var AST_Case = DEFNODE("Case", "expression", {
|
||||
Cola.AST_Case = Cola.DEFNODE("Case", "expression", {
|
||||
$documentation: "A `case` switch branch",
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `case` expression"
|
||||
|
|
@ -479,14 +480,14 @@ var AST_Case = DEFNODE("Case", "expression", {
|
|||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.expression._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
Cola.walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
}, AST_SwitchBranch);
|
||||
}, Cola.AST_SwitchBranch);
|
||||
|
||||
/* -----[ EXCEPTIONS ]----- */
|
||||
|
||||
var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
||||
Cola.AST_Try = Cola.DEFNODE("Try", "bcatch bfinally", {
|
||||
$documentation: "A `try` statement",
|
||||
$propdoc: {
|
||||
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||
|
|
@ -494,14 +495,14 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
|||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
walk_body(this, visitor);
|
||||
Cola.walk_body(this, visitor);
|
||||
if (this.bcatch) this.bcatch._walk(visitor);
|
||||
if (this.bfinally) this.bfinally._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Block);
|
||||
}, Cola.AST_Block);
|
||||
|
||||
var AST_Catch = DEFNODE("Catch", "argname", {
|
||||
Cola.AST_Catch = Cola.DEFNODE("Catch", "argname", {
|
||||
$documentation: "A `catch` node; only makes sense as part of a `try` statement",
|
||||
$propdoc: {
|
||||
argname: "[AST_SymbolCatch] symbol for the exception"
|
||||
|
|
@ -509,18 +510,18 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
|||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.argname._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
Cola.walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
}, AST_Block);
|
||||
}, Cola.AST_Block);
|
||||
|
||||
var AST_Finally = DEFNODE("Finally", null, {
|
||||
Cola.AST_Finally = Cola.DEFNODE("Finally", null, {
|
||||
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
|
||||
}, AST_Block);
|
||||
}, Cola.AST_Block);
|
||||
|
||||
/* -----[ VAR/CONST ]----- */
|
||||
|
||||
var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||
Cola.AST_Definitions = Cola.DEFNODE("Definitions", "definitions", {
|
||||
$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
|
||||
$propdoc: {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
|
|
@ -532,17 +533,17 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
|||
});
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
}, Cola.AST_Statement);
|
||||
|
||||
var AST_Var = DEFNODE("Var", null, {
|
||||
Cola.AST_Var = Cola.DEFNODE("Var", null, {
|
||||
$documentation: "A `var` statement"
|
||||
}, AST_Definitions);
|
||||
}, Cola.AST_Definitions);
|
||||
|
||||
var AST_Const = DEFNODE("Const", null, {
|
||||
Cola.AST_Const = Cola.DEFNODE("Const", null, {
|
||||
$documentation: "A `const` statement"
|
||||
}, AST_Definitions);
|
||||
}, Cola.AST_Definitions);
|
||||
|
||||
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
Cola.AST_VarDef = Cola.DEFNODE("VarDef", "name value", {
|
||||
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
||||
$propdoc: {
|
||||
name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",
|
||||
|
|
@ -558,7 +559,7 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
|||
|
||||
/* -----[ OTHER ]----- */
|
||||
|
||||
var AST_Call = DEFNODE("Call", "expression args", {
|
||||
Cola.AST_Call = Cola.DEFNODE("Call", "expression args", {
|
||||
$documentation: "A function call expression",
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] expression to invoke as function",
|
||||
|
|
@ -574,18 +575,18 @@ var AST_Call = DEFNODE("Call", "expression args", {
|
|||
}
|
||||
});
|
||||
|
||||
var AST_New = DEFNODE("New", null, {
|
||||
Cola.AST_New = Cola.DEFNODE("New", null, {
|
||||
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
|
||||
}, AST_Call);
|
||||
}, Cola.AST_Call);
|
||||
|
||||
var AST_Seq = DEFNODE("Seq", "car cdr", {
|
||||
Cola.AST_Seq = Cola.DEFNODE("Seq", "car cdr", {
|
||||
$documentation: "A sequence expression (two comma-separated expressions)",
|
||||
$propdoc: {
|
||||
car: "[AST_Node] first element in sequence",
|
||||
cdr: "[AST_Node] second element in sequence"
|
||||
},
|
||||
$cons: function(x, y) {
|
||||
var seq = new AST_Seq(x);
|
||||
var seq = new Cola.AST_Seq(x);
|
||||
seq.car = x;
|
||||
seq.cdr = y;
|
||||
return seq;
|
||||
|
|
@ -595,7 +596,7 @@ var AST_Seq = DEFNODE("Seq", "car cdr", {
|
|||
if (array.length == 1) return array[0].clone();
|
||||
var list = null;
|
||||
for (var i = array.length; --i >= 0;) {
|
||||
list = AST_Seq.cons(array[i], list);
|
||||
list = Cola.AST_Seq.cons(array[i], list);
|
||||
}
|
||||
var p = list;
|
||||
while (p) {
|
||||
|
|
@ -611,7 +612,7 @@ var AST_Seq = DEFNODE("Seq", "car cdr", {
|
|||
var p = this, a = [];
|
||||
while (p) {
|
||||
a.push(p.car);
|
||||
if (p.cdr && !(p.cdr instanceof AST_Seq)) {
|
||||
if (p.cdr && !(p.cdr instanceof Cola.AST_Seq)) {
|
||||
a.push(p.cdr);
|
||||
break;
|
||||
}
|
||||
|
|
@ -622,8 +623,8 @@ var AST_Seq = DEFNODE("Seq", "car cdr", {
|
|||
add: function(node) {
|
||||
var p = this;
|
||||
while (p) {
|
||||
if (!(p.cdr instanceof AST_Seq)) {
|
||||
var cell = AST_Seq.cons(p.cdr, node);
|
||||
if (!(p.cdr instanceof Cola.AST_Seq)) {
|
||||
var cell = Cola.AST_Seq.cons(p.cdr, node);
|
||||
return p.cdr = cell;
|
||||
}
|
||||
p = p.cdr;
|
||||
|
|
@ -637,7 +638,7 @@ var AST_Seq = DEFNODE("Seq", "car cdr", {
|
|||
}
|
||||
});
|
||||
|
||||
var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
||||
Cola.AST_PropAccess = Cola.DEFNODE("PropAccess", "expression property", {
|
||||
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the “container” expression",
|
||||
|
|
@ -645,16 +646,16 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
|||
}
|
||||
});
|
||||
|
||||
var AST_Dot = DEFNODE("Dot", null, {
|
||||
Cola.AST_Dot = Cola.DEFNODE("Dot", null, {
|
||||
$documentation: "A dotted property access expression",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
this.expression._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_PropAccess);
|
||||
}, Cola.AST_PropAccess);
|
||||
|
||||
var AST_Sub = DEFNODE("Sub", null, {
|
||||
Cola.AST_Sub = Cola.DEFNODE("Sub", null, {
|
||||
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
|
|
@ -662,9 +663,9 @@ var AST_Sub = DEFNODE("Sub", null, {
|
|||
this.property._walk(visitor);
|
||||
});
|
||||
}
|
||||
}, AST_PropAccess);
|
||||
}, Cola.AST_PropAccess);
|
||||
|
||||
var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||
Cola.AST_Unary = Cola.DEFNODE("Unary", "operator expression", {
|
||||
$documentation: "Base class for unary expressions",
|
||||
$propdoc: {
|
||||
operator: "[string] the operator",
|
||||
|
|
@ -677,15 +678,15 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
|||
}
|
||||
});
|
||||
|
||||
var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, {
|
||||
Cola.AST_UnaryPrefix = Cola.DEFNODE("UnaryPrefix", null, {
|
||||
$documentation: "Unary prefix expression, i.e. `typeof i` or `++i`"
|
||||
}, AST_Unary);
|
||||
}, Cola.AST_Unary);
|
||||
|
||||
var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {
|
||||
Cola.AST_UnaryPostfix = Cola.DEFNODE("UnaryPostfix", null, {
|
||||
$documentation: "Unary postfix expression, i.e. `i++`"
|
||||
}, AST_Unary);
|
||||
}, Cola.AST_Unary);
|
||||
|
||||
var AST_Binary = DEFNODE("Binary", "left operator right", {
|
||||
Cola.AST_Binary = Cola.DEFNODE("Binary", "left operator right", {
|
||||
$documentation: "Binary expression, i.e. `a + b`",
|
||||
$propdoc: {
|
||||
left: "[AST_Node] left-hand side expression",
|
||||
|
|
@ -700,7 +701,7 @@ var AST_Binary = DEFNODE("Binary", "left operator right", {
|
|||
}
|
||||
});
|
||||
|
||||
var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", {
|
||||
Cola.AST_Conditional = Cola.DEFNODE("Conditional", "condition consequent alternative", {
|
||||
$documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`",
|
||||
$propdoc: {
|
||||
condition: "[AST_Node]",
|
||||
|
|
@ -716,13 +717,13 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
|||
}
|
||||
});
|
||||
|
||||
var AST_Assign = DEFNODE("Assign", null, {
|
||||
Cola.AST_Assign = Cola.DEFNODE("Assign", null, {
|
||||
$documentation: "An assignment expression — `a = b + 5`",
|
||||
}, AST_Binary);
|
||||
}, Cola.AST_Binary);
|
||||
|
||||
/* -----[ LITERALS ]----- */
|
||||
|
||||
var AST_Array = DEFNODE("Array", "elements", {
|
||||
Cola.AST_Array = Cola.DEFNODE("Array", "elements", {
|
||||
$documentation: "An array literal",
|
||||
$propdoc: {
|
||||
elements: "[AST_Node*] array of elements"
|
||||
|
|
@ -736,7 +737,7 @@ var AST_Array = DEFNODE("Array", "elements", {
|
|||
}
|
||||
});
|
||||
|
||||
var AST_Object = DEFNODE("Object", "properties", {
|
||||
Cola.AST_Object = Cola.DEFNODE("Object", "properties", {
|
||||
$documentation: "An object literal",
|
||||
$propdoc: {
|
||||
properties: "[AST_ObjectProperty*] array of properties"
|
||||
|
|
@ -750,7 +751,7 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||
}
|
||||
});
|
||||
|
||||
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||
Cola.AST_ObjectProperty = Cola.DEFNODE("ObjectProperty", "key value", {
|
||||
$documentation: "Base class for literal object properties",
|
||||
$propdoc: {
|
||||
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",
|
||||
|
|
@ -763,19 +764,19 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
|||
}
|
||||
});
|
||||
|
||||
var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", null, {
|
||||
Cola.AST_ObjectKeyVal = Cola.DEFNODE("ObjectKeyVal", null, {
|
||||
$documentation: "A key: value object property",
|
||||
}, AST_ObjectProperty);
|
||||
}, Cola.AST_ObjectProperty);
|
||||
|
||||
var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {
|
||||
Cola.AST_ObjectSetter = Cola.DEFNODE("ObjectSetter", null, {
|
||||
$documentation: "An object setter property",
|
||||
}, AST_ObjectProperty);
|
||||
}, Cola.AST_ObjectProperty);
|
||||
|
||||
var AST_ObjectGetter = DEFNODE("ObjectGetter", null, {
|
||||
Cola.AST_ObjectGetter = Cola.DEFNODE("ObjectGetter", null, {
|
||||
$documentation: "An object getter property",
|
||||
}, AST_ObjectProperty);
|
||||
}, Cola.AST_ObjectProperty);
|
||||
|
||||
var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
||||
Cola.AST_Symbol = Cola.DEFNODE("Symbol", "scope name thedef", {
|
||||
$propdoc: {
|
||||
name: "[string] name of this symbol",
|
||||
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||
|
|
@ -784,42 +785,42 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
|||
$documentation: "Base class for all symbols",
|
||||
});
|
||||
|
||||
var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
||||
Cola.AST_SymbolAccessor = Cola.DEFNODE("SymbolAccessor", null, {
|
||||
$documentation: "The name of a property accessor (setter/getter function)"
|
||||
}, AST_Symbol);
|
||||
}, Cola.AST_Symbol);
|
||||
|
||||
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
||||
Cola.AST_SymbolDeclaration = Cola.DEFNODE("SymbolDeclaration", "init", {
|
||||
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
||||
$propdoc: {
|
||||
init: "[AST_Node*/S] array of initializers for this declaration."
|
||||
}
|
||||
}, AST_Symbol);
|
||||
}, Cola.AST_Symbol);
|
||||
|
||||
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||
Cola.AST_SymbolVar = Cola.DEFNODE("SymbolVar", null, {
|
||||
$documentation: "Symbol defining a variable",
|
||||
}, AST_SymbolDeclaration);
|
||||
}, Cola.AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||
Cola.AST_SymbolConst = Cola.DEFNODE("SymbolConst", null, {
|
||||
$documentation: "A constant declaration"
|
||||
}, AST_SymbolDeclaration);
|
||||
}, Cola.AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
||||
Cola.AST_SymbolFunarg = Cola.DEFNODE("SymbolFunarg", null, {
|
||||
$documentation: "Symbol naming a function argument",
|
||||
}, AST_SymbolVar);
|
||||
}, Cola.AST_SymbolVar);
|
||||
|
||||
var AST_SymbolDefun = DEFNODE("SymbolDefun", null, {
|
||||
Cola.AST_SymbolDefun = Cola.DEFNODE("SymbolDefun", null, {
|
||||
$documentation: "Symbol defining a function",
|
||||
}, AST_SymbolDeclaration);
|
||||
}, Cola.AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {
|
||||
Cola.AST_SymbolLambda = Cola.DEFNODE("SymbolLambda", null, {
|
||||
$documentation: "Symbol naming a function expression",
|
||||
}, AST_SymbolDeclaration);
|
||||
}, Cola.AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
||||
Cola.AST_SymbolCatch = Cola.DEFNODE("SymbolCatch", null, {
|
||||
$documentation: "Symbol naming the exception in catch",
|
||||
}, AST_SymbolDeclaration);
|
||||
}, Cola.AST_SymbolDeclaration);
|
||||
|
||||
var AST_Label = DEFNODE("Label", "references", {
|
||||
Cola.AST_Label = Cola.DEFNODE("Label", "references", {
|
||||
$documentation: "Symbol naming a label (declaration)",
|
||||
$propdoc: {
|
||||
references: "[AST_LoopControl*] a list of nodes referring to this label"
|
||||
|
|
@ -828,110 +829,110 @@ var AST_Label = DEFNODE("Label", "references", {
|
|||
this.references = [];
|
||||
this.thedef = this;
|
||||
}
|
||||
}, AST_Symbol);
|
||||
}, Cola.AST_Symbol);
|
||||
|
||||
var AST_SymbolRef = DEFNODE("SymbolRef", null, {
|
||||
Cola.AST_SymbolRef = Cola.DEFNODE("SymbolRef", null, {
|
||||
$documentation: "Reference to some symbol (not definition/declaration)",
|
||||
}, AST_Symbol);
|
||||
}, Cola.AST_Symbol);
|
||||
|
||||
var AST_LabelRef = DEFNODE("LabelRef", null, {
|
||||
Cola.AST_LabelRef = Cola.DEFNODE("LabelRef", null, {
|
||||
$documentation: "Reference to a label symbol",
|
||||
}, AST_Symbol);
|
||||
}, Cola.AST_Symbol);
|
||||
|
||||
var AST_This = DEFNODE("This", null, {
|
||||
Cola.AST_This = Cola.DEFNODE("This", null, {
|
||||
$documentation: "The `this` symbol",
|
||||
}, AST_Symbol);
|
||||
}, Cola.AST_Symbol);
|
||||
|
||||
var AST_Constant = DEFNODE("Constant", null, {
|
||||
Cola.AST_Constant = Cola.DEFNODE("Constant", null, {
|
||||
$documentation: "Base class for all constants",
|
||||
getValue: function() {
|
||||
return this.value;
|
||||
}
|
||||
});
|
||||
|
||||
var AST_String = DEFNODE("String", "value", {
|
||||
Cola.AST_String = Cola.DEFNODE("String", "value", {
|
||||
$documentation: "A string literal",
|
||||
$propdoc: {
|
||||
value: "[string] the contents of this string"
|
||||
}
|
||||
}, AST_Constant);
|
||||
}, Cola.AST_Constant);
|
||||
|
||||
var AST_StringTemplate = DEFNODE("StringTemplate", null, {
|
||||
Cola.AST_StringTemplate = Cola.DEFNODE("StringTemplate", null, {
|
||||
$documentation: "A string template",
|
||||
$propdoc: {
|
||||
body: "[AST_Statement*] the contents of this string template"
|
||||
}
|
||||
}, AST_Block);
|
||||
}, Cola.AST_Block);
|
||||
|
||||
var AST_Number = DEFNODE("Number", "value", {
|
||||
Cola.AST_Number = Cola.DEFNODE("Number", "value", {
|
||||
$documentation: "A number literal",
|
||||
$propdoc: {
|
||||
value: "[number] the numeric value"
|
||||
}
|
||||
}, AST_Constant);
|
||||
}, Cola.AST_Constant);
|
||||
|
||||
var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||
Cola.AST_RegExp = Cola.DEFNODE("RegExp", "value", {
|
||||
$documentation: "A regexp literal",
|
||||
$propdoc: {
|
||||
value: "[RegExp] the actual regexp"
|
||||
}
|
||||
}, AST_Constant);
|
||||
}, Cola.AST_Constant);
|
||||
|
||||
var AST_Atom = DEFNODE("Atom", null, {
|
||||
Cola.AST_Atom = Cola.DEFNODE("Atom", null, {
|
||||
$documentation: "Base class for atoms",
|
||||
}, AST_Constant);
|
||||
}, Cola.AST_Constant);
|
||||
|
||||
var AST_Null = DEFNODE("Null", null, {
|
||||
Cola.AST_Null = Cola.DEFNODE("Null", null, {
|
||||
$documentation: "The `null` atom",
|
||||
value: null
|
||||
}, AST_Atom);
|
||||
}, Cola.AST_Atom);
|
||||
|
||||
var AST_NaN = DEFNODE("NaN", null, {
|
||||
Cola.AST_NaN = Cola.DEFNODE("NaN", null, {
|
||||
$documentation: "The impossible value",
|
||||
value: 0/0
|
||||
}, AST_Atom);
|
||||
}, Cola.AST_Atom);
|
||||
|
||||
var AST_Undefined = DEFNODE("Undefined", null, {
|
||||
Cola.AST_Undefined = Cola.DEFNODE("Undefined", null, {
|
||||
$documentation: "The `undefined` value",
|
||||
value: (function(){}())
|
||||
}, AST_Atom);
|
||||
}, Cola.AST_Atom);
|
||||
|
||||
var AST_Hole = DEFNODE("Hole", null, {
|
||||
Cola.AST_Hole = Cola.DEFNODE("Hole", null, {
|
||||
$documentation: "A hole in an array",
|
||||
value: (function(){}())
|
||||
}, AST_Atom);
|
||||
}, Cola.AST_Atom);
|
||||
|
||||
var AST_Infinity = DEFNODE("Infinity", null, {
|
||||
Cola.AST_Infinity = Cola.DEFNODE("Infinity", null, {
|
||||
$documentation: "The `Infinity` value",
|
||||
value: 1/0
|
||||
}, AST_Atom);
|
||||
}, Cola.AST_Atom);
|
||||
|
||||
var AST_Boolean = DEFNODE("Boolean", null, {
|
||||
Cola.AST_Boolean = Cola.DEFNODE("Boolean", null, {
|
||||
$documentation: "Base class for booleans",
|
||||
}, AST_Atom);
|
||||
}, Cola.AST_Atom);
|
||||
|
||||
var AST_False = DEFNODE("False", null, {
|
||||
Cola.AST_False = Cola.DEFNODE("False", null, {
|
||||
$documentation: "The `false` atom",
|
||||
value: false
|
||||
}, AST_Boolean);
|
||||
}, Cola.AST_Boolean);
|
||||
|
||||
var AST_True = DEFNODE("True", null, {
|
||||
Cola.AST_True = Cola.DEFNODE("True", null, {
|
||||
$documentation: "The `true` atom",
|
||||
value: true
|
||||
}, AST_Boolean);
|
||||
}, Cola.AST_Boolean);
|
||||
|
||||
/* -----[ TreeWalker ]----- */
|
||||
|
||||
function TreeWalker(callback) {
|
||||
Cola.TreeWalker = function (callback) {
|
||||
this.visit = callback;
|
||||
this.stack = [];
|
||||
};
|
||||
TreeWalker.prototype = {
|
||||
Cola.TreeWalker.prototype = {
|
||||
_visit: function(node, descend) {
|
||||
this.stack.push(node);
|
||||
var ret = this.visit(node, descend ? function(){
|
||||
descend.call(node);
|
||||
} : noop);
|
||||
} : Cola.noop);
|
||||
if (!ret && descend) {
|
||||
descend.call(node);
|
||||
}
|
||||
|
|
@ -958,22 +959,22 @@ TreeWalker.prototype = {
|
|||
}
|
||||
},
|
||||
has_directive: function(type) {
|
||||
return this.find_parent(AST_Scope).has_directive(type);
|
||||
return this.find_parent(Cola.AST_Scope).has_directive(type);
|
||||
},
|
||||
in_boolean_context: function() {
|
||||
var stack = this.stack;
|
||||
var i = stack.length, self = stack[--i];
|
||||
while (i > 0) {
|
||||
var p = stack[--i];
|
||||
if ((p instanceof AST_If && p.condition === self) ||
|
||||
(p instanceof AST_Conditional && p.condition === self) ||
|
||||
(p instanceof AST_DWLoop && p.condition === self) ||
|
||||
(p instanceof AST_For && p.condition === self) ||
|
||||
(p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self))
|
||||
if ((p instanceof Cola.AST_If && p.condition === self) ||
|
||||
(p instanceof Cola.AST_Conditional && p.condition === self) ||
|
||||
(p instanceof Cola.AST_DWLoop && p.condition === self) ||
|
||||
(p instanceof Cola.AST_For && p.condition === self) ||
|
||||
(p instanceof Cola.AST_UnaryPrefix && p.operator == "!" && p.expression === self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||")))
|
||||
if (!(p instanceof Cola.AST_Binary && (p.operator == "&&" || p.operator == "||")))
|
||||
return false;
|
||||
self = p;
|
||||
}
|
||||
|
|
@ -982,12 +983,12 @@ TreeWalker.prototype = {
|
|||
var stack = this.stack;
|
||||
if (label) for (var i = stack.length; --i >= 0;) {
|
||||
var x = stack[i];
|
||||
if (x instanceof AST_LabeledStatement && x.label.name == label.name) {
|
||||
if (x instanceof Cola.AST_LabeledStatement && x.label.name == label.name) {
|
||||
return x.body;
|
||||
}
|
||||
} else for (var i = stack.length; --i >= 0;) {
|
||||
var x = stack[i];
|
||||
if (x instanceof AST_Switch || x instanceof AST_IterationStatement)
|
||||
if (x instanceof Cola.AST_Switch || x instanceof Cola.AST_IterationStatement)
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
912
lib/compress.js
912
lib/compress.js
File diff suppressed because it is too large
Load Diff
|
|
@ -65,7 +65,7 @@
|
|||
|
||||
try {
|
||||
// 1. compile
|
||||
ast = parse(source);
|
||||
ast = Cola.parse(source);
|
||||
ast = translate(ast);
|
||||
ast.print(stream);
|
||||
translationArea.value = stream.toString();
|
||||
|
|
@ -85,6 +85,8 @@
|
|||
} catch(e){
|
||||
translationArea.value = '';
|
||||
resultArea.value = '';
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +96,7 @@
|
|||
|
||||
function Translate(){
|
||||
stream = OutputStream({ beautify : true });
|
||||
translate(parse(source)).print(stream);
|
||||
translate(Cola.parse(source)).print(stream);
|
||||
return stream.toString();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,16 +47,16 @@
|
|||
|
||||
var MOZ_TO_ME = {
|
||||
TryStatement : function(M) {
|
||||
return new AST_Try({
|
||||
return new Cola.AST_Try({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
body : from_moz(M.block).body,
|
||||
bcatch : from_moz(M.handlers[0]),
|
||||
bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
|
||||
bfinally : M.finalizer ? new Cola.AST_Finally(from_moz(M.finalizer)) : null
|
||||
});
|
||||
},
|
||||
CatchClause : function(M) {
|
||||
return new AST_Catch({
|
||||
return new Cola.AST_Catch({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
argname : from_moz(M.param),
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
});
|
||||
},
|
||||
ObjectExpression : function(M) {
|
||||
return new AST_Object({
|
||||
return new Cola.AST_Object({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
properties : M.properties.map(function(prop){
|
||||
|
|
@ -78,22 +78,22 @@
|
|||
};
|
||||
switch (prop.kind) {
|
||||
case "init":
|
||||
return new AST_ObjectKeyVal(args);
|
||||
return new Cola.AST_ObjectKeyVal(args);
|
||||
case "set":
|
||||
args.value.name = from_moz(key);
|
||||
return new AST_ObjectSetter(args);
|
||||
return new Cola.AST_ObjectSetter(args);
|
||||
case "get":
|
||||
args.value.name = from_moz(key);
|
||||
return new AST_ObjectGetter(args);
|
||||
return new Cola.AST_ObjectGetter(args);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
SequenceExpression : function(M) {
|
||||
return AST_Seq.from_array(M.expressions.map(from_moz));
|
||||
return Cola.AST_Seq.from_array(M.expressions.map(from_moz));
|
||||
},
|
||||
MemberExpression : function(M) {
|
||||
return new (M.computed ? AST_Sub : AST_Dot)({
|
||||
return new (M.computed ? Cola.AST_Sub : Cola.AST_Dot)({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
property : M.computed ? from_moz(M.property) : M.property.name,
|
||||
|
|
@ -101,7 +101,7 @@
|
|||
});
|
||||
},
|
||||
SwitchCase : function(M) {
|
||||
return new (M.test ? AST_Case : AST_Default)({
|
||||
return new (M.test ? Cola.AST_Case : Cola.AST_Default)({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
expression : from_moz(M.test),
|
||||
|
|
@ -113,33 +113,33 @@
|
|||
start : my_start_token(M),
|
||||
end : my_end_token(M)
|
||||
};
|
||||
if (val === null) return new AST_Null(args);
|
||||
if (val === null) return new Cola.AST_Null(args);
|
||||
switch (typeof val) {
|
||||
case "string":
|
||||
args.value = val;
|
||||
return new AST_String(args);
|
||||
return new Cola.AST_String(args);
|
||||
case "number":
|
||||
args.value = val;
|
||||
return new AST_Number(args);
|
||||
return new Cola.AST_Number(args);
|
||||
case "boolean":
|
||||
return new (val ? AST_True : AST_False)(args);
|
||||
return new (val ? Cola.AST_True : Cola.AST_False)(args);
|
||||
default:
|
||||
args.value = val;
|
||||
return new AST_RegExp(args);
|
||||
return new Cola.AST_RegExp(args);
|
||||
}
|
||||
},
|
||||
UnaryExpression: From_Moz_Unary,
|
||||
UpdateExpression: From_Moz_Unary,
|
||||
Identifier: function(M) {
|
||||
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
||||
return new (M.name == "this" ? AST_This
|
||||
: p.type == "LabeledStatement" ? AST_Label
|
||||
: 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
|
||||
: p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef
|
||||
: AST_SymbolRef)({
|
||||
return new (M.name == "this" ? Cola.AST_This
|
||||
: p.type == "LabeledStatement" ? Cola.AST_Label
|
||||
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? Cola.AST_SymbolConst : Cola.AST_SymbolVar)
|
||||
: p.type == "FunctionExpression" ? (p.id === M ? Cola.AST_SymbolLambda : Cola.AST_SymbolFunarg)
|
||||
: p.type == "FunctionDeclaration" ? (p.id === M ? Cola.AST_SymbolDefun : Cola.AST_SymbolFunarg)
|
||||
: p.type == "CatchClause" ? Cola.AST_SymbolCatch
|
||||
: p.type == "BreakStatement" || p.type == "ContinueStatement" ? Cola.AST_LabelRef
|
||||
: Cola.AST_SymbolRef)({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
name : M.name
|
||||
|
|
@ -150,7 +150,7 @@
|
|||
function From_Moz_Unary(M) {
|
||||
var prefix = "prefix" in M ? M.prefix
|
||||
: M.type == "UnaryExpression" ? true : false;
|
||||
return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
|
||||
return new (prefix ? Cola.AST_UnaryPrefix : Cola.AST_UnaryPostfix)({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
operator : M.operator,
|
||||
|
|
@ -160,43 +160,43 @@
|
|||
|
||||
var ME_TO_MOZ = {};
|
||||
|
||||
map("Node", AST_Node);
|
||||
map("Program", AST_Toplevel, "body@body");
|
||||
map("Function", AST_Function, "id>name, params@argnames, body%body");
|
||||
map("EmptyStatement", AST_EmptyStatement);
|
||||
map("BlockStatement", AST_BlockStatement, "body@body");
|
||||
map("ExpressionStatement", AST_SimpleStatement, "expression>body");
|
||||
map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
|
||||
map("LabeledStatement", AST_LabeledStatement, "label>label, body>body");
|
||||
map("BreakStatement", AST_Break, "label>label");
|
||||
map("ContinueStatement", AST_Continue, "label>label");
|
||||
map("WithStatement", AST_With, "object>expression, body>body");
|
||||
map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body");
|
||||
map("ReturnStatement", AST_Return, "argument>value");
|
||||
map("ThrowStatement", AST_Throw, "argument>value");
|
||||
map("WhileStatement", AST_While, "test>condition, body>body");
|
||||
map("DoWhileStatement", AST_Do, "test>condition, body>body");
|
||||
map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
|
||||
map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
|
||||
map("DebuggerStatement", AST_Debugger);
|
||||
map("FunctionDeclaration", AST_Defun, "id>name, params@argnames, body%body");
|
||||
map("VariableDeclaration", AST_Var, "declarations@definitions");
|
||||
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
|
||||
map("Node", Cola.AST_Node);
|
||||
map("Program", Cola.AST_Toplevel, "body@body");
|
||||
map("Function", Cola.AST_Function, "id>name, params@argnames, body%body");
|
||||
map("EmptyStatement", Cola.AST_EmptyStatement);
|
||||
map("BlockStatement", Cola.AST_BlockStatement, "body@body");
|
||||
map("ExpressionStatement", Cola.AST_SimpleStatement, "expression>body");
|
||||
map("IfStatement", Cola.AST_If, "test>condition, consequent>body, alternate>alternative");
|
||||
map("LabeledStatement", Cola.AST_LabeledStatement, "label>label, body>body");
|
||||
map("BreakStatement", Cola.AST_Break, "label>label");
|
||||
map("ContinueStatement", Cola.AST_Continue, "label>label");
|
||||
map("WithStatement", Cola.AST_With, "object>expression, body>body");
|
||||
map("SwitchStatement", Cola.AST_Switch, "discriminant>expression, cases@body");
|
||||
map("ReturnStatement", Cola.AST_Return, "argument>value");
|
||||
map("ThrowStatement", Cola.AST_Throw, "argument>value");
|
||||
map("WhileStatement", Cola.AST_While, "test>condition, body>body");
|
||||
map("DoWhileStatement", Cola.AST_Do, "test>condition, body>body");
|
||||
map("ForStatement", Cola.AST_For, "init>init, test>condition, update>step, body>body");
|
||||
map("ForInStatement", Cola.AST_ForIn, "left>init, right>object, body>body");
|
||||
map("DebuggerStatement", Cola.AST_Debugger);
|
||||
map("FunctionDeclaration", Cola.AST_Defun, "id>name, params@argnames, body%body");
|
||||
map("VariableDeclaration", Cola.AST_Var, "declarations@definitions");
|
||||
map("VariableDeclarator", Cola.AST_VarDef, "id>name, init>value");
|
||||
|
||||
map("ThisExpression", AST_This);
|
||||
map("ArrayExpression", AST_Array, "elements@elements");
|
||||
map("FunctionExpression", AST_Function, "id>name, params@argnames, body%body");
|
||||
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
|
||||
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
|
||||
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
|
||||
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
|
||||
map("NewExpression", AST_New, "callee>expression, arguments@args");
|
||||
map("CallExpression", AST_Call, "callee>expression, arguments@args");
|
||||
map("ThisExpression", Cola.AST_This);
|
||||
map("ArrayExpression", Cola.AST_Array, "elements@elements");
|
||||
map("FunctionExpression", Cola.AST_Function, "id>name, params@argnames, body%body");
|
||||
map("BinaryExpression", Cola.AST_Binary, "operator=operator, left>left, right>right");
|
||||
map("AssignmentExpression", Cola.AST_Assign, "operator=operator, left>left, right>right");
|
||||
map("LogicalExpression", Cola.AST_Binary, "operator=operator, left>left, right>right");
|
||||
map("ConditionalExpression", Cola.AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
|
||||
map("NewExpression", Cola.AST_New, "callee>expression, arguments@args");
|
||||
map("CallExpression", Cola.AST_Call, "callee>expression, arguments@args");
|
||||
|
||||
/* -----[ tools ]----- */
|
||||
|
||||
function my_start_token(moznode) {
|
||||
return new AST_Token({
|
||||
return new Cola.AST_Token({
|
||||
file : moznode.loc && moznode.loc.source,
|
||||
line : moznode.loc && moznode.loc.start.line,
|
||||
col : moznode.loc && moznode.loc.start.column,
|
||||
|
|
@ -206,7 +206,7 @@
|
|||
};
|
||||
|
||||
function my_end_token(moznode) {
|
||||
return new AST_Token({
|
||||
return new Cola.AST_Token({
|
||||
file : moznode.loc && moznode.loc.source,
|
||||
line : moznode.loc && moznode.loc.end.line,
|
||||
col : moznode.loc && moznode.loc.end.column,
|
||||
|
|
@ -256,7 +256,7 @@
|
|||
return ret;
|
||||
};
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node){
|
||||
Cola.AST_Node.from_mozilla_ast = function(node){
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
var ast = from_moz(node);
|
||||
|
|
|
|||
342
lib/output.js
342
lib/output.js
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
function OutputStream(options) {
|
||||
|
||||
options = defaults(options, {
|
||||
options = Cola.defaults(options, {
|
||||
indent_start : 0,
|
||||
indent_level : 4,
|
||||
quote_keys : false,
|
||||
|
|
@ -121,7 +121,7 @@ function OutputStream(options) {
|
|||
};
|
||||
|
||||
function make_indent(back) {
|
||||
return repeat_string(" ", options.indent_start + indentation - back * options.indent_level);
|
||||
return Cola.repeat_string(" ", options.indent_start + indentation - back * options.indent_level);
|
||||
};
|
||||
|
||||
/* -----[ beautification/minification ]----- */
|
||||
|
|
@ -139,7 +139,7 @@ function OutputStream(options) {
|
|||
print("\n");
|
||||
};
|
||||
|
||||
var requireSemicolonChars = makePredicate("( [ + * / - , .");
|
||||
var requireSemicolonChars = Cola.makePredicate("( [ + * / - , .");
|
||||
|
||||
function print(str) {
|
||||
str = String(str);
|
||||
|
|
@ -176,8 +176,8 @@ function OutputStream(options) {
|
|||
|
||||
if (might_need_space) {
|
||||
var prev = last_char();
|
||||
if ((is_identifier_char(prev)
|
||||
&& (is_identifier_char(ch) || ch == "\\"))
|
||||
if ((Cola.is_identifier_char(prev)
|
||||
&& (Cola.is_identifier_char(ch) || ch == "\\"))
|
||||
|| (/^[\+\-\/]$/.test(ch) && ch == prev))
|
||||
{
|
||||
OUTPUT += " ";
|
||||
|
|
@ -208,7 +208,7 @@ function OutputStream(options) {
|
|||
if (options.beautify) {
|
||||
print(make_indent(half ? 0.5 : 0));
|
||||
}
|
||||
} : noop;
|
||||
} : Cola.noop;
|
||||
|
||||
var with_indent = options.beautify ? function(col, cont) {
|
||||
if (col === true) col = next_indent();
|
||||
|
|
@ -221,7 +221,7 @@ function OutputStream(options) {
|
|||
|
||||
var newline = options.beautify ? function() {
|
||||
print("\n");
|
||||
} : noop;
|
||||
} : Cola.noop;
|
||||
|
||||
var semicolon = options.beautify ? function() {
|
||||
print(";");
|
||||
|
|
@ -286,7 +286,7 @@ function OutputStream(options) {
|
|||
(!name && token.type == "name") ? token.value : name
|
||||
);
|
||||
} catch(ex) {
|
||||
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
|
||||
Cola.AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
|
||||
file: token.file,
|
||||
line: token.line,
|
||||
col: token.col,
|
||||
|
|
@ -295,7 +295,7 @@ function OutputStream(options) {
|
|||
name: name || ""
|
||||
})
|
||||
}
|
||||
} : noop;
|
||||
} : Cola.noop;
|
||||
|
||||
function get() {
|
||||
return OUTPUT;
|
||||
|
|
@ -354,7 +354,7 @@ function OutputStream(options) {
|
|||
nodetype.DEFMETHOD("_codegen", generator);
|
||||
};
|
||||
|
||||
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||
Cola.AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||
var self = this, generator = self._codegen;
|
||||
function doit() {
|
||||
self.add_comments(stream);
|
||||
|
|
@ -370,7 +370,7 @@ function OutputStream(options) {
|
|||
stream.pop_node();
|
||||
});
|
||||
|
||||
AST_Node.DEFMETHOD("print_to_string", function(options){
|
||||
Cola.AST_Node.DEFMETHOD("print_to_string", function(options){
|
||||
var s = OutputStream(options);
|
||||
this.print(s);
|
||||
return s.get();
|
||||
|
|
@ -378,7 +378,7 @@ function OutputStream(options) {
|
|||
|
||||
/* -----[ comments ]----- */
|
||||
|
||||
AST_Node.DEFMETHOD("add_comments", function(output){
|
||||
Cola.AST_Node.DEFMETHOD("add_comments", function(output){
|
||||
var c = output.option("comments"), self = this;
|
||||
if (c) {
|
||||
var start = self.start;
|
||||
|
|
@ -388,15 +388,15 @@ function OutputStream(options) {
|
|||
|
||||
// XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112
|
||||
// and https://github.com/mishoo/UglifyJS2/issues/372
|
||||
if (self instanceof AST_Exit && self.value) {
|
||||
self.value.walk(new TreeWalker(function(node){
|
||||
if (self instanceof Cola.AST_Exit && self.value) {
|
||||
self.value.walk(new Cola.TreeWalker(function(node){
|
||||
if (node.start && node.start.comments_before) {
|
||||
comments = comments.concat(node.start.comments_before);
|
||||
node.start.comments_before = [];
|
||||
}
|
||||
if (node instanceof AST_Function ||
|
||||
node instanceof AST_Array ||
|
||||
node instanceof AST_Object)
|
||||
if (node instanceof Cola.AST_Function ||
|
||||
node instanceof Cola.AST_Array ||
|
||||
node instanceof Cola.AST_Object)
|
||||
{
|
||||
return true; // don't go inside.
|
||||
}
|
||||
|
|
@ -437,56 +437,56 @@ function OutputStream(options) {
|
|||
nodetype.DEFMETHOD("needs_parens", func);
|
||||
};
|
||||
|
||||
PARENS(AST_Node, function(){
|
||||
PARENS(Cola.AST_Node, function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
// a function expression needs parens around it when it's provably
|
||||
// the first token to appear in a statement.
|
||||
PARENS(AST_Function, function(output){
|
||||
PARENS(Cola.AST_Function, function(output){
|
||||
return first_in_statement(output);
|
||||
});
|
||||
|
||||
// same goes for an object literal, because otherwise it would be
|
||||
// interpreted as a block of code.
|
||||
PARENS(AST_Object, function(output){
|
||||
PARENS(Cola.AST_Object, function(output){
|
||||
return first_in_statement(output);
|
||||
});
|
||||
|
||||
PARENS(AST_Unary, function(output){
|
||||
PARENS(Cola.AST_Unary, function(output){
|
||||
var p = output.parent();
|
||||
return p instanceof AST_PropAccess && p.expression === this;
|
||||
return p instanceof Cola.AST_PropAccess && p.expression === this;
|
||||
});
|
||||
|
||||
PARENS(AST_Seq, function(output){
|
||||
PARENS(Cola.AST_Seq, function(output){
|
||||
var p = output.parent();
|
||||
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
||||
|| p instanceof AST_Unary // !(foo, bar, baz)
|
||||
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|
||||
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|
||||
|| p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|
||||
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
||||
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|
||||
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
|
||||
return p instanceof Cola.AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
||||
|| p instanceof Cola.AST_Unary // !(foo, bar, baz)
|
||||
|| p instanceof Cola.AST_Binary // 1 + (2, 3) + 4 ==> 8
|
||||
|| p instanceof Cola.AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|
||||
|| p instanceof Cola.AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|
||||
|| p instanceof Cola.AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
||||
|| p instanceof Cola.AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|
||||
|| p instanceof Cola.AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
|
||||
* ==> 20 (side effect, set a := 10 and b := 20) */
|
||||
;
|
||||
});
|
||||
|
||||
PARENS(AST_Binary, function(output){
|
||||
PARENS(Cola.AST_Binary, function(output){
|
||||
var p = output.parent();
|
||||
// (foo && bar)()
|
||||
if (p instanceof AST_Call && p.expression === this)
|
||||
if (p instanceof Cola.AST_Call && p.expression === this)
|
||||
return true;
|
||||
// typeof (foo && bar)
|
||||
if (p instanceof AST_Unary)
|
||||
if (p instanceof Cola.AST_Unary)
|
||||
return true;
|
||||
// (foo && bar)["prop"], (foo && bar).prop
|
||||
if (p instanceof AST_PropAccess && p.expression === this)
|
||||
if (p instanceof Cola.AST_PropAccess && p.expression === this)
|
||||
return true;
|
||||
// this deals with precedence: 3 * (2 + 1)
|
||||
if (p instanceof AST_Binary) {
|
||||
var po = p.operator, pp = PRECEDENCE[po];
|
||||
var so = this.operator, sp = PRECEDENCE[so];
|
||||
if (p instanceof Cola.AST_Binary) {
|
||||
var po = p.operator, pp = Cola.PRECEDENCE[po];
|
||||
var so = this.operator, sp = Cola.PRECEDENCE[so];
|
||||
if (pp > sp
|
||||
|| (pp == sp
|
||||
&& this === p.right)) {
|
||||
|
|
@ -495,9 +495,9 @@ function OutputStream(options) {
|
|||
}
|
||||
});
|
||||
|
||||
PARENS(AST_PropAccess, function(output){
|
||||
PARENS(Cola.AST_PropAccess, function(output){
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_New && p.expression === this) {
|
||||
if (p instanceof Cola.AST_New && p.expression === this) {
|
||||
// i.e. new (foo.bar().baz)
|
||||
//
|
||||
// if there's one call into this subtree, then we need
|
||||
|
|
@ -505,8 +505,8 @@ function OutputStream(options) {
|
|||
// interpreted as passing the arguments to the upper New
|
||||
// expression.
|
||||
try {
|
||||
this.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_Call) throw p;
|
||||
this.walk(new Cola.TreeWalker(function(node){
|
||||
if (node instanceof Cola.AST_Call) throw p;
|
||||
}));
|
||||
} catch(ex) {
|
||||
if (ex !== p) throw ex;
|
||||
|
|
@ -515,69 +515,69 @@ function OutputStream(options) {
|
|||
}
|
||||
});
|
||||
|
||||
PARENS(AST_Call, function(output){
|
||||
PARENS(Cola.AST_Call, function(output){
|
||||
var p = output.parent(), p1;
|
||||
if (p instanceof AST_New && p.expression === this)
|
||||
if (p instanceof Cola.AST_New && p.expression === this)
|
||||
return true;
|
||||
|
||||
// workaround for Safari bug.
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=123506
|
||||
return this.expression instanceof AST_Function
|
||||
&& p instanceof AST_PropAccess
|
||||
return this.expression instanceof Cola.AST_Function
|
||||
&& p instanceof Cola.AST_PropAccess
|
||||
&& p.expression === this
|
||||
&& (p1 = output.parent(1)) instanceof AST_Assign
|
||||
&& (p1 = output.parent(1)) instanceof Cola.AST_Assign
|
||||
&& p1.left === p;
|
||||
});
|
||||
|
||||
PARENS(AST_New, function(output){
|
||||
PARENS(Cola.AST_New, function(output){
|
||||
var p = output.parent();
|
||||
if (no_constructor_parens(this, output)
|
||||
&& (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
|
||||
|| p instanceof AST_Call && p.expression === this)) // (new foo)(bar)
|
||||
&& (p instanceof Cola.AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
|
||||
|| p instanceof Cola.AST_Call && p.expression === this)) // (new foo)(bar)
|
||||
return true;
|
||||
});
|
||||
|
||||
PARENS(AST_Number, function(output){
|
||||
PARENS(Cola.AST_Number, function(output){
|
||||
var p = output.parent();
|
||||
if (this.getValue() < 0 && p instanceof AST_PropAccess && p.expression === this)
|
||||
if (this.getValue() < 0 && p instanceof Cola.AST_PropAccess && p.expression === this)
|
||||
return true;
|
||||
});
|
||||
|
||||
PARENS(AST_NaN, function(output){
|
||||
PARENS(Cola.AST_NaN, function(output){
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_PropAccess && p.expression === this)
|
||||
if (p instanceof Cola.AST_PropAccess && p.expression === this)
|
||||
return true;
|
||||
});
|
||||
|
||||
function assign_and_conditional_paren_rules(output) {
|
||||
var p = output.parent();
|
||||
// !(a = false) → true
|
||||
if (p instanceof AST_Unary)
|
||||
if (p instanceof Cola.AST_Unary)
|
||||
return true;
|
||||
// 1 + (a = 2) + 3 → 6, side effect setting a = 2
|
||||
if (p instanceof AST_Binary && !(p instanceof AST_Assign))
|
||||
if (p instanceof Cola.AST_Binary && !(p instanceof Cola.AST_Assign))
|
||||
return true;
|
||||
// (a = func)() —or— new (a = Object)()
|
||||
if (p instanceof AST_Call && p.expression === this)
|
||||
if (p instanceof Cola.AST_Call && p.expression === this)
|
||||
return true;
|
||||
// (a = foo) ? bar : baz
|
||||
if (p instanceof AST_Conditional && p.condition === this)
|
||||
if (p instanceof Cola.AST_Conditional && p.condition === this)
|
||||
return true;
|
||||
// (a = foo)["prop"] —or— (a = foo).prop
|
||||
if (p instanceof AST_PropAccess && p.expression === this)
|
||||
if (p instanceof Cola.AST_PropAccess && p.expression === this)
|
||||
return true;
|
||||
};
|
||||
|
||||
PARENS(AST_Assign, assign_and_conditional_paren_rules);
|
||||
PARENS(AST_Conditional, assign_and_conditional_paren_rules);
|
||||
PARENS(Cola.AST_Assign, assign_and_conditional_paren_rules);
|
||||
PARENS(Cola.AST_Conditional, assign_and_conditional_paren_rules);
|
||||
|
||||
/* -----[ PRINTERS ]----- */
|
||||
|
||||
DEFPRINT(AST_Directive, function(self, output){
|
||||
DEFPRINT(Cola.AST_Directive, function(self, output){
|
||||
output.print_string(self.value);
|
||||
output.semicolon();
|
||||
});
|
||||
DEFPRINT(AST_Debugger, function(self, output){
|
||||
DEFPRINT(Cola.AST_Debugger, function(self, output){
|
||||
output.print("debugger");
|
||||
output.semicolon();
|
||||
});
|
||||
|
|
@ -587,7 +587,7 @@ function OutputStream(options) {
|
|||
function display_body(body, is_toplevel, output) {
|
||||
var last = body.length - 1;
|
||||
body.forEach(function(stmt, i){
|
||||
if (!(stmt instanceof AST_EmptyStatement)) {
|
||||
if (!(stmt instanceof Cola.AST_EmptyStatement)) {
|
||||
output.indent();
|
||||
stmt.print(output);
|
||||
if (!(i == last && is_toplevel)) {
|
||||
|
|
@ -598,24 +598,24 @@ function OutputStream(options) {
|
|||
});
|
||||
};
|
||||
|
||||
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){
|
||||
Cola.AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){
|
||||
force_statement(this.body, output);
|
||||
});
|
||||
|
||||
DEFPRINT(AST_Statement, function(self, output){
|
||||
DEFPRINT(Cola.AST_Statement, function(self, output){
|
||||
self.body.print(output);
|
||||
output.semicolon();
|
||||
});
|
||||
DEFPRINT(AST_Toplevel, function(self, output){
|
||||
DEFPRINT(Cola.AST_Toplevel, function(self, output){
|
||||
display_body(self.body, true, output);
|
||||
output.print("");
|
||||
});
|
||||
DEFPRINT(AST_LabeledStatement, function(self, output){
|
||||
DEFPRINT(Cola.AST_LabeledStatement, function(self, output){
|
||||
self.label.print(output);
|
||||
output.colon();
|
||||
self.body.print(output);
|
||||
});
|
||||
DEFPRINT(AST_SimpleStatement, function(self, output){
|
||||
DEFPRINT(Cola.AST_SimpleStatement, function(self, output){
|
||||
self.body.print(output);
|
||||
output.semicolon();
|
||||
});
|
||||
|
|
@ -625,13 +625,13 @@ function OutputStream(options) {
|
|||
});
|
||||
else output.print("{}");
|
||||
};
|
||||
DEFPRINT(AST_BlockStatement, function(self, output){
|
||||
DEFPRINT(Cola.AST_BlockStatement, function(self, output){
|
||||
print_bracketed(self.body, output);
|
||||
});
|
||||
DEFPRINT(AST_EmptyStatement, function(self, output){
|
||||
DEFPRINT(Cola.AST_EmptyStatement, function(self, output){
|
||||
output.semicolon();
|
||||
});
|
||||
DEFPRINT(AST_Do, function(self, output){
|
||||
DEFPRINT(Cola.AST_Do, function(self, output){
|
||||
output.print("do");
|
||||
output.space();
|
||||
self._do_print_body(output);
|
||||
|
|
@ -643,7 +643,7 @@ function OutputStream(options) {
|
|||
});
|
||||
output.semicolon();
|
||||
});
|
||||
DEFPRINT(AST_While, function(self, output){
|
||||
DEFPRINT(Cola.AST_While, function(self, output){
|
||||
output.print("while");
|
||||
output.space();
|
||||
output.with_parens(function(){
|
||||
|
|
@ -652,12 +652,12 @@ function OutputStream(options) {
|
|||
output.space();
|
||||
self._do_print_body(output);
|
||||
});
|
||||
DEFPRINT(AST_For, function(self, output){
|
||||
DEFPRINT(Cola.AST_For, function(self, output){
|
||||
output.print("for");
|
||||
output.space();
|
||||
output.with_parens(function(){
|
||||
if (self.init) {
|
||||
if (self.init instanceof AST_Definitions) {
|
||||
if (self.init instanceof Cola.AST_Definitions) {
|
||||
self.init.print(output);
|
||||
} else {
|
||||
parenthesize_for_noin(self.init, output, true);
|
||||
|
|
@ -681,7 +681,7 @@ function OutputStream(options) {
|
|||
output.space();
|
||||
self._do_print_body(output);
|
||||
});
|
||||
DEFPRINT(AST_ForIn, function(self, output){
|
||||
DEFPRINT(Cola.AST_ForIn, function(self, output){
|
||||
output.print("for");
|
||||
output.space();
|
||||
output.with_parens(function(){
|
||||
|
|
@ -694,7 +694,7 @@ function OutputStream(options) {
|
|||
output.space();
|
||||
self._do_print_body(output);
|
||||
});
|
||||
DEFPRINT(AST_With, function(self, output){
|
||||
DEFPRINT(Cola.AST_With, function(self, output){
|
||||
output.print("with");
|
||||
output.space();
|
||||
output.with_parens(function(){
|
||||
|
|
@ -705,7 +705,7 @@ function OutputStream(options) {
|
|||
});
|
||||
|
||||
/* -----[ functions ]----- */
|
||||
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){
|
||||
Cola.AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){
|
||||
var self = this;
|
||||
if (!nokeyword) {
|
||||
output.print("function");
|
||||
|
|
@ -723,12 +723,12 @@ function OutputStream(options) {
|
|||
output.space();
|
||||
print_bracketed(self.body, output);
|
||||
});
|
||||
DEFPRINT(AST_Lambda, function(self, output){
|
||||
DEFPRINT(Cola.AST_Lambda, function(self, output){
|
||||
self._do_print(output);
|
||||
});
|
||||
|
||||
/* -----[ exits ]----- */
|
||||
AST_Exit.DEFMETHOD("_do_print", function(output, kind){
|
||||
Cola.AST_Exit.DEFMETHOD("_do_print", function(output, kind){
|
||||
output.print(kind);
|
||||
if (this.value) {
|
||||
output.space();
|
||||
|
|
@ -736,15 +736,15 @@ function OutputStream(options) {
|
|||
}
|
||||
output.semicolon();
|
||||
});
|
||||
DEFPRINT(AST_Return, function(self, output){
|
||||
DEFPRINT(Cola.AST_Return, function(self, output){
|
||||
self._do_print(output, "return");
|
||||
});
|
||||
DEFPRINT(AST_Throw, function(self, output){
|
||||
DEFPRINT(Cola.AST_Throw, function(self, output){
|
||||
self._do_print(output, "throw");
|
||||
});
|
||||
|
||||
/* -----[ loop control ]----- */
|
||||
AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){
|
||||
Cola.AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){
|
||||
output.print(kind);
|
||||
if (this.label) {
|
||||
output.space();
|
||||
|
|
@ -752,10 +752,10 @@ function OutputStream(options) {
|
|||
}
|
||||
output.semicolon();
|
||||
});
|
||||
DEFPRINT(AST_Break, function(self, output){
|
||||
DEFPRINT(Cola.AST_Break, function(self, output){
|
||||
self._do_print(output, "break");
|
||||
});
|
||||
DEFPRINT(AST_Continue, function(self, output){
|
||||
DEFPRINT(Cola.AST_Continue, function(self, output){
|
||||
self._do_print(output, "continue");
|
||||
});
|
||||
|
||||
|
|
@ -774,7 +774,7 @@ function OutputStream(options) {
|
|||
// adds the block brackets if needed.
|
||||
if (!self.body)
|
||||
return output.force_semicolon();
|
||||
if (self.body instanceof AST_Do
|
||||
if (self.body instanceof Cola.AST_Do
|
||||
&& !output.option("screw_ie8")) {
|
||||
// https://github.com/mishoo/UglifyJS/issues/#issue/57 IE
|
||||
// croaks with "syntax error" on code like this: if (foo)
|
||||
|
|
@ -785,21 +785,21 @@ function OutputStream(options) {
|
|||
}
|
||||
var b = self.body;
|
||||
while (true) {
|
||||
if (b instanceof AST_If) {
|
||||
if (b instanceof Cola.AST_If) {
|
||||
if (!b.alternative) {
|
||||
make_block(self.body, output);
|
||||
return;
|
||||
}
|
||||
b = b.alternative;
|
||||
}
|
||||
else if (b instanceof AST_StatementWithBody) {
|
||||
else if (b instanceof Cola.AST_StatementWithBody) {
|
||||
b = b.body;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
force_statement(self.body, output);
|
||||
};
|
||||
DEFPRINT(AST_If, function(self, output){
|
||||
DEFPRINT(Cola.AST_If, function(self, output){
|
||||
output.print("if");
|
||||
output.space();
|
||||
output.with_parens(function(){
|
||||
|
|
@ -818,7 +818,7 @@ function OutputStream(options) {
|
|||
});
|
||||
|
||||
/* -----[ switch ]----- */
|
||||
DEFPRINT(AST_Switch, function(self, output){
|
||||
DEFPRINT(Cola.AST_Switch, function(self, output){
|
||||
output.print("switch");
|
||||
output.space();
|
||||
output.with_parens(function(){
|
||||
|
|
@ -834,7 +834,7 @@ function OutputStream(options) {
|
|||
});
|
||||
else output.print("{}");
|
||||
});
|
||||
AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){
|
||||
Cola.AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){
|
||||
if (this.body.length > 0) {
|
||||
output.newline();
|
||||
this.body.forEach(function(stmt){
|
||||
|
|
@ -844,11 +844,11 @@ function OutputStream(options) {
|
|||
});
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_Default, function(self, output){
|
||||
DEFPRINT(Cola.AST_Default, function(self, output){
|
||||
output.print("default:");
|
||||
self._do_print_body(output);
|
||||
});
|
||||
DEFPRINT(AST_Case, function(self, output){
|
||||
DEFPRINT(Cola.AST_Case, function(self, output){
|
||||
output.print("case");
|
||||
output.space();
|
||||
self.expression.print(output);
|
||||
|
|
@ -857,7 +857,7 @@ function OutputStream(options) {
|
|||
});
|
||||
|
||||
/* -----[ exceptions ]----- */
|
||||
DEFPRINT(AST_Try, function(self, output){
|
||||
DEFPRINT(Cola.AST_Try, function(self, output){
|
||||
output.print("try");
|
||||
output.space();
|
||||
print_bracketed(self.body, output);
|
||||
|
|
@ -870,7 +870,7 @@ function OutputStream(options) {
|
|||
self.bfinally.print(output);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_Catch, function(self, output){
|
||||
DEFPRINT(Cola.AST_Catch, function(self, output){
|
||||
output.print("catch");
|
||||
output.space();
|
||||
output.with_parens(function(){
|
||||
|
|
@ -879,14 +879,14 @@ function OutputStream(options) {
|
|||
output.space();
|
||||
print_bracketed(self.body, output);
|
||||
});
|
||||
DEFPRINT(AST_Finally, function(self, output){
|
||||
DEFPRINT(Cola.AST_Finally, function(self, output){
|
||||
output.print("finally");
|
||||
output.space();
|
||||
print_bracketed(self.body, output);
|
||||
});
|
||||
|
||||
/* -----[ var/const ]----- */
|
||||
AST_Definitions.DEFMETHOD("_do_print", function(output, kind){
|
||||
Cola.AST_Definitions.DEFMETHOD("_do_print", function(output, kind){
|
||||
output.print(kind);
|
||||
output.space();
|
||||
this.definitions.forEach(function(def, i){
|
||||
|
|
@ -894,15 +894,15 @@ function OutputStream(options) {
|
|||
def.print(output);
|
||||
});
|
||||
var p = output.parent();
|
||||
var in_for = p instanceof AST_For || p instanceof AST_ForIn;
|
||||
var in_for = p instanceof Cola.AST_For || p instanceof Cola.AST_ForIn;
|
||||
var avoid_semicolon = in_for && p.init === this;
|
||||
if (!avoid_semicolon)
|
||||
output.semicolon();
|
||||
});
|
||||
DEFPRINT(AST_Var, function(self, output){
|
||||
DEFPRINT(Cola.AST_Var, function(self, output){
|
||||
self._do_print(output, "var");
|
||||
});
|
||||
DEFPRINT(AST_Const, function(self, output){
|
||||
DEFPRINT(Cola.AST_Const, function(self, output){
|
||||
self._do_print(output, "const");
|
||||
});
|
||||
|
||||
|
|
@ -911,8 +911,8 @@ function OutputStream(options) {
|
|||
else try {
|
||||
// need to take some precautions here:
|
||||
// https://github.com/mishoo/UglifyJS2/issues/60
|
||||
node.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_Binary && node.operator == "in")
|
||||
node.walk(new Cola.TreeWalker(function(node){
|
||||
if (node instanceof Cola.AST_Binary && node.operator == "in")
|
||||
throw output;
|
||||
}));
|
||||
node.print(output);
|
||||
|
|
@ -922,22 +922,22 @@ function OutputStream(options) {
|
|||
}
|
||||
};
|
||||
|
||||
DEFPRINT(AST_VarDef, function(self, output){
|
||||
DEFPRINT(Cola.AST_VarDef, function(self, output){
|
||||
self.name.print(output);
|
||||
if (self.value) {
|
||||
output.space();
|
||||
output.print("=");
|
||||
output.space();
|
||||
var p = output.parent(1);
|
||||
var noin = p instanceof AST_For || p instanceof AST_ForIn;
|
||||
var noin = p instanceof Cola.AST_For || p instanceof Cola.AST_ForIn;
|
||||
parenthesize_for_noin(self.value, output, noin);
|
||||
}
|
||||
});
|
||||
|
||||
/* -----[ other expressions ]----- */
|
||||
DEFPRINT(AST_Call, function(self, output){
|
||||
DEFPRINT(Cola.AST_Call, function(self, output){
|
||||
self.expression.print(output);
|
||||
if (self instanceof AST_New && no_constructor_parens(self, output))
|
||||
if (self instanceof Cola.AST_New && no_constructor_parens(self, output))
|
||||
return;
|
||||
output.with_parens(function(){
|
||||
self.args.forEach(function(expr, i){
|
||||
|
|
@ -946,13 +946,13 @@ function OutputStream(options) {
|
|||
});
|
||||
});
|
||||
});
|
||||
DEFPRINT(AST_New, function(self, output){
|
||||
DEFPRINT(Cola.AST_New, function(self, output){
|
||||
output.print("new");
|
||||
output.space();
|
||||
AST_Call.prototype._codegen(self, output);
|
||||
Cola.AST_Call.prototype._codegen(self, output);
|
||||
});
|
||||
|
||||
AST_Seq.DEFMETHOD("_do_print", function(output){
|
||||
Cola.AST_Seq.DEFMETHOD("_do_print", function(output){
|
||||
this.car.print(output);
|
||||
if (this.cdr) {
|
||||
output.comma();
|
||||
|
|
@ -963,10 +963,10 @@ function OutputStream(options) {
|
|||
this.cdr.print(output);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_Seq, function(self, output){
|
||||
DEFPRINT(Cola.AST_Seq, function(self, output){
|
||||
self._do_print(output);
|
||||
// var p = output.parent();
|
||||
// if (p instanceof AST_Statement) {
|
||||
// if (p instanceof Cola.AST_Statement) {
|
||||
// output.with_indent(output.next_indent(), function(){
|
||||
// self._do_print(output);
|
||||
// });
|
||||
|
|
@ -974,10 +974,10 @@ function OutputStream(options) {
|
|||
// self._do_print(output);
|
||||
// }
|
||||
});
|
||||
DEFPRINT(AST_Dot, function(self, output){
|
||||
DEFPRINT(Cola.AST_Dot, function(self, output){
|
||||
var expr = self.expression;
|
||||
expr.print(output);
|
||||
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
||||
if (expr instanceof Cola.AST_Number && expr.getValue() >= 0) {
|
||||
if (!/[xa-f.]/i.test(output.last())) {
|
||||
output.print(".");
|
||||
}
|
||||
|
|
@ -987,31 +987,31 @@ function OutputStream(options) {
|
|||
output.add_mapping(self.end);
|
||||
output.print_name(self.property);
|
||||
});
|
||||
DEFPRINT(AST_Sub, function(self, output){
|
||||
DEFPRINT(Cola.AST_Sub, function(self, output){
|
||||
self.expression.print(output);
|
||||
output.print("[");
|
||||
self.property.print(output);
|
||||
output.print("]");
|
||||
});
|
||||
DEFPRINT(AST_UnaryPrefix, function(self, output){
|
||||
DEFPRINT(Cola.AST_UnaryPrefix, function(self, output){
|
||||
var op = self.operator;
|
||||
output.print(op);
|
||||
if (/^[a-z]/i.test(op))
|
||||
output.space();
|
||||
self.expression.print(output);
|
||||
});
|
||||
DEFPRINT(AST_UnaryPostfix, function(self, output){
|
||||
DEFPRINT(Cola.AST_UnaryPostfix, function(self, output){
|
||||
self.expression.print(output);
|
||||
output.print(self.operator);
|
||||
});
|
||||
DEFPRINT(AST_Binary, function(self, output){
|
||||
DEFPRINT(Cola.AST_Binary, function(self, output){
|
||||
self.left.print(output);
|
||||
output.space();
|
||||
output.print(self.operator);
|
||||
if (self.operator == "<"
|
||||
&& self.right instanceof AST_UnaryPrefix
|
||||
&& self.right instanceof Cola.AST_UnaryPrefix
|
||||
&& self.right.operator == "!"
|
||||
&& self.right.expression instanceof AST_UnaryPrefix
|
||||
&& self.right.expression instanceof Cola.AST_UnaryPrefix
|
||||
&& self.right.expression.operator == "--") {
|
||||
// space is mandatory to avoid outputting <!--
|
||||
// http://javascript.spec.whatwg.org/#comment-syntax
|
||||
|
|
@ -1022,7 +1022,7 @@ function OutputStream(options) {
|
|||
}
|
||||
self.right.print(output);
|
||||
});
|
||||
DEFPRINT(AST_Conditional, function(self, output){
|
||||
DEFPRINT(Cola.AST_Conditional, function(self, output){
|
||||
self.condition.print(output);
|
||||
output.space();
|
||||
output.print("?");
|
||||
|
|
@ -1034,7 +1034,7 @@ function OutputStream(options) {
|
|||
});
|
||||
|
||||
/* -----[ literals ]----- */
|
||||
DEFPRINT(AST_Array, function(self, output){
|
||||
DEFPRINT(Cola.AST_Array, function(self, output){
|
||||
output.with_square(function(){
|
||||
var a = self.elements, len = a.length;
|
||||
if (len > 0) output.space();
|
||||
|
|
@ -1044,13 +1044,13 @@ function OutputStream(options) {
|
|||
// If the final element is a hole, we need to make sure it
|
||||
// doesn't look like a trailing comma, by inserting an actual
|
||||
// trailing comma.
|
||||
if (i === len - 1 && exp instanceof AST_Hole)
|
||||
if (i === len - 1 && exp instanceof Cola.AST_Hole)
|
||||
output.comma();
|
||||
});
|
||||
if (len > 0) output.space();
|
||||
});
|
||||
});
|
||||
DEFPRINT(AST_Object, function(self, output){
|
||||
DEFPRINT(Cola.AST_Object, function(self, output){
|
||||
if (self.properties.length > 0) output.with_block(function(){
|
||||
self.properties.forEach(function(prop, i){
|
||||
if (i) {
|
||||
|
|
@ -1064,7 +1064,7 @@ function OutputStream(options) {
|
|||
});
|
||||
else output.print("{}");
|
||||
});
|
||||
DEFPRINT(AST_ObjectKeyVal, function(self, output){
|
||||
DEFPRINT(Cola.AST_ObjectKeyVal, function(self, output){
|
||||
var key = self.key;
|
||||
if (output.option("quote_keys")) {
|
||||
output.print_string(key + "");
|
||||
|
|
@ -1073,7 +1073,7 @@ function OutputStream(options) {
|
|||
&& +key + "" == key)
|
||||
&& parseFloat(key) >= 0) {
|
||||
output.print(make_num(key));
|
||||
} else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) {
|
||||
} else if (Cola.RESERVED_WORDS(key) ? output.option("screw_ie8") : Cola.is_identifier_string(key)) {
|
||||
output.print_name(key);
|
||||
} else {
|
||||
output.print_string(key);
|
||||
|
|
@ -1081,42 +1081,42 @@ function OutputStream(options) {
|
|||
output.colon();
|
||||
self.value.print(output);
|
||||
});
|
||||
DEFPRINT(AST_ObjectSetter, function(self, output){
|
||||
DEFPRINT(Cola.AST_ObjectSetter, function(self, output){
|
||||
output.print("set");
|
||||
output.space();
|
||||
self.key.print(output);
|
||||
self.value._do_print(output, true);
|
||||
});
|
||||
DEFPRINT(AST_ObjectGetter, function(self, output){
|
||||
DEFPRINT(Cola.AST_ObjectGetter, function(self, output){
|
||||
output.print("get");
|
||||
output.space();
|
||||
self.key.print(output);
|
||||
self.value._do_print(output, true);
|
||||
});
|
||||
DEFPRINT(AST_Symbol, function(self, output){
|
||||
DEFPRINT(Cola.AST_Symbol, function(self, output){
|
||||
var def = self.definition();
|
||||
output.print_name(def ? def.mangled_name || def.name : self.name);
|
||||
});
|
||||
DEFPRINT(AST_Undefined, function(self, output){
|
||||
DEFPRINT(Cola.AST_Undefined, function(self, output){
|
||||
output.print("void 0");
|
||||
});
|
||||
DEFPRINT(AST_Hole, noop);
|
||||
DEFPRINT(AST_Infinity, function(self, output){
|
||||
DEFPRINT(Cola.AST_Hole, Cola.noop);
|
||||
DEFPRINT(Cola.AST_Infinity, function(self, output){
|
||||
output.print("1/0");
|
||||
});
|
||||
DEFPRINT(AST_NaN, function(self, output){
|
||||
DEFPRINT(Cola.AST_NaN, function(self, output){
|
||||
output.print("0/0");
|
||||
});
|
||||
DEFPRINT(AST_This, function(self, output){
|
||||
DEFPRINT(Cola.AST_This, function(self, output){
|
||||
output.print("this");
|
||||
});
|
||||
DEFPRINT(AST_Constant, function(self, output){
|
||||
DEFPRINT(Cola.AST_Constant, function(self, output){
|
||||
output.print(self.getValue());
|
||||
});
|
||||
DEFPRINT(AST_String, function(self, output){
|
||||
DEFPRINT(Cola.AST_String, function(self, output){
|
||||
output.print_string(self.getValue());
|
||||
});
|
||||
DEFPRINT(AST_Number, function(self, output){
|
||||
DEFPRINT(Cola.AST_Number, function(self, output){
|
||||
output.print(make_num(self.getValue()));
|
||||
});
|
||||
|
||||
|
|
@ -1148,7 +1148,7 @@ function OutputStream(options) {
|
|||
].indexOf(code) < 0;
|
||||
};
|
||||
|
||||
DEFPRINT(AST_RegExp, function(self, output){
|
||||
DEFPRINT(Cola.AST_RegExp, function(self, output){
|
||||
var str = self.getValue().toString();
|
||||
if (output.option("ascii_only")) {
|
||||
str = output.to_ascii(str);
|
||||
|
|
@ -1162,15 +1162,15 @@ function OutputStream(options) {
|
|||
}
|
||||
output.print(str);
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
||||
if (p instanceof Cola.AST_Binary && /^in/.test(p.operator) && p.left === self)
|
||||
output.print(" ");
|
||||
});
|
||||
|
||||
function force_statement(stat, output) {
|
||||
if (output.option("bracketize")) {
|
||||
if (!stat || stat instanceof AST_EmptyStatement)
|
||||
if (!stat || stat instanceof Cola.AST_EmptyStatement)
|
||||
output.print("{}");
|
||||
else if (stat instanceof AST_BlockStatement)
|
||||
else if (stat instanceof Cola.AST_BlockStatement)
|
||||
stat.print(output);
|
||||
else output.with_block(function(){
|
||||
output.indent();
|
||||
|
|
@ -1178,7 +1178,7 @@ function OutputStream(options) {
|
|||
output.newline();
|
||||
});
|
||||
} else {
|
||||
if (!stat || stat instanceof AST_EmptyStatement)
|
||||
if (!stat || stat instanceof Cola.AST_EmptyStatement)
|
||||
output.force_semicolon();
|
||||
else
|
||||
stat.print(output);
|
||||
|
|
@ -1191,15 +1191,15 @@ function OutputStream(options) {
|
|||
function first_in_statement(output) {
|
||||
var a = output.stack(), i = a.length, node = a[--i], p = a[--i];
|
||||
while (i > 0) {
|
||||
if (p instanceof AST_Statement && p.body === node)
|
||||
if (p instanceof Cola.AST_Statement && p.body === node)
|
||||
return true;
|
||||
if ((p instanceof AST_Seq && p.car === node ) ||
|
||||
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
|
||||
(p instanceof AST_Dot && p.expression === node ) ||
|
||||
(p instanceof AST_Sub && p.expression === node ) ||
|
||||
(p instanceof AST_Conditional && p.condition === node ) ||
|
||||
(p instanceof AST_Binary && p.left === node ) ||
|
||||
(p instanceof AST_UnaryPostfix && p.expression === node ))
|
||||
if ((p instanceof Cola.AST_Seq && p.car === node ) ||
|
||||
(p instanceof Cola.AST_Call && p.expression === node && !(p instanceof Cola.AST_New) ) ||
|
||||
(p instanceof Cola.AST_Dot && p.expression === node ) ||
|
||||
(p instanceof Cola.AST_Sub && p.expression === node ) ||
|
||||
(p instanceof Cola.AST_Conditional && p.condition === node ) ||
|
||||
(p instanceof Cola.AST_Binary && p.left === node ) ||
|
||||
(p instanceof Cola.AST_UnaryPostfix && p.expression === node ))
|
||||
{
|
||||
node = p;
|
||||
p = a[--i];
|
||||
|
|
@ -1209,7 +1209,7 @@ function OutputStream(options) {
|
|||
}
|
||||
};
|
||||
|
||||
// self should be AST_New. decide if we want to show parens or not.
|
||||
// self should be Cola.AST_New. decide if we want to show parens or not.
|
||||
function no_constructor_parens(self, output) {
|
||||
return self.args.length == 0 && !output.option("beautify");
|
||||
};
|
||||
|
|
@ -1246,7 +1246,7 @@ function OutputStream(options) {
|
|||
};
|
||||
|
||||
function make_block(stmt, output) {
|
||||
if (stmt instanceof AST_BlockStatement) {
|
||||
if (stmt instanceof Cola.AST_BlockStatement) {
|
||||
stmt.print(output);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1266,8 +1266,8 @@ function OutputStream(options) {
|
|||
};
|
||||
|
||||
// We could easily add info for ALL nodes, but it seems to me that
|
||||
// would be quite wasteful, hence this noop in the base class.
|
||||
DEFMAP(AST_Node, noop);
|
||||
// would be quite wasteful, hence this Cola.noop in the base class.
|
||||
DEFMAP(Cola.AST_Node, Cola.noop);
|
||||
|
||||
function basic_sourcemap_gen(self, output) {
|
||||
output.add_mapping(self.start);
|
||||
|
|
@ -1276,24 +1276,24 @@ function OutputStream(options) {
|
|||
// XXX: I'm not exactly sure if we need it for all of these nodes,
|
||||
// or if we should add even more.
|
||||
|
||||
DEFMAP(AST_Directive, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Debugger, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Symbol, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Jump, basic_sourcemap_gen);
|
||||
DEFMAP(AST_StatementWithBody, basic_sourcemap_gen);
|
||||
DEFMAP(AST_LabeledStatement, noop); // since the label symbol will mark it
|
||||
DEFMAP(AST_Lambda, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Switch, basic_sourcemap_gen);
|
||||
DEFMAP(AST_SwitchBranch, basic_sourcemap_gen);
|
||||
DEFMAP(AST_BlockStatement, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Toplevel, noop);
|
||||
DEFMAP(AST_New, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Try, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Catch, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Finally, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Definitions, basic_sourcemap_gen);
|
||||
DEFMAP(AST_Constant, basic_sourcemap_gen);
|
||||
DEFMAP(AST_ObjectProperty, function(self, output){
|
||||
DEFMAP(Cola.AST_Directive, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Debugger, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Symbol, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Jump, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_StatementWithBody, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_LabeledStatement, Cola.noop); // since the label symbol will mark it
|
||||
DEFMAP(Cola.AST_Lambda, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Switch, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_SwitchBranch, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_BlockStatement, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Toplevel, Cola.noop);
|
||||
DEFMAP(Cola.AST_New, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Try, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Catch, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Finally, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Definitions, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_Constant, basic_sourcemap_gen);
|
||||
DEFMAP(Cola.AST_ObjectProperty, function(self, output){
|
||||
output.add_mapping(self.start, self.key);
|
||||
});
|
||||
|
||||
|
|
|
|||
1164
lib/parse.js
1164
lib/parse.js
File diff suppressed because it is too large
Load Diff
240
lib/scope.js
240
lib/scope.js
|
|
@ -64,15 +64,15 @@ SymbolDef.prototype = {
|
|||
mangle: function(options) {
|
||||
if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var s = this.scope;
|
||||
if (!options.screw_ie8 && this.orig[0] instanceof AST_SymbolLambda)
|
||||
if (!options.screw_ie8 && this.orig[0] instanceof Cola.AST_SymbolLambda)
|
||||
s = s.parent_scope;
|
||||
this.mangled_name = s.next_mangled(options, this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
options = defaults(options, {
|
||||
Cola.AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
options = Cola.defaults(options, {
|
||||
screw_ie8: false
|
||||
});
|
||||
|
||||
|
|
@ -81,17 +81,17 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||
var scope = self.parent_scope = null;
|
||||
var defun = null;
|
||||
var nesting = 0;
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (options.screw_ie8 && node instanceof AST_Catch) {
|
||||
var tw = new Cola.TreeWalker(function(node, descend){
|
||||
if (options.screw_ie8 && node instanceof Cola.AST_Catch) {
|
||||
var save_scope = scope;
|
||||
scope = new AST_Scope(node);
|
||||
scope = new Cola.AST_Scope(node);
|
||||
scope.init_scope_vars(nesting);
|
||||
scope.parent_scope = save_scope;
|
||||
descend();
|
||||
scope = save_scope;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
if (node instanceof Cola.AST_Scope) {
|
||||
node.init_scope_vars(nesting);
|
||||
var save_scope = node.parent_scope = scope;
|
||||
var save_defun = defun;
|
||||
|
|
@ -99,39 +99,39 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||
++nesting; descend(); --nesting;
|
||||
scope = save_scope;
|
||||
defun = save_defun;
|
||||
return true; // don't descend again in TreeWalker
|
||||
return true; // don't descend again in Cola.TreeWalker
|
||||
}
|
||||
if (node instanceof AST_Directive) {
|
||||
if (node instanceof Cola.AST_Directive) {
|
||||
node.scope = scope;
|
||||
push_uniq(scope.directives, node.value);
|
||||
Cola.push_uniq(scope.directives, node.value);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_With) {
|
||||
if (node instanceof Cola.AST_With) {
|
||||
for (var s = scope; s; s = s.parent_scope)
|
||||
s.uses_with = true;
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Symbol) {
|
||||
if (node instanceof Cola.AST_Symbol) {
|
||||
node.scope = scope;
|
||||
}
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
if (node instanceof Cola.AST_SymbolLambda) {
|
||||
defun.def_function(node);
|
||||
}
|
||||
else if (node instanceof AST_SymbolDefun) {
|
||||
else if (node instanceof Cola.AST_SymbolDefun) {
|
||||
// Careful here, the scope where this should be defined is
|
||||
// the parent scope. The reason is that we enter a new
|
||||
// scope when we encounter the AST_Defun node (which is
|
||||
// instanceof AST_Scope) but we get to the symbol a bit
|
||||
// scope when we encounter the Cola.AST_Defun node (which is
|
||||
// instanceof Cola.AST_Scope) but we get to the symbol a bit
|
||||
// later.
|
||||
(node.scope = defun.parent_scope).def_function(node);
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar
|
||||
|| node instanceof AST_SymbolConst) {
|
||||
else if (node instanceof Cola.AST_SymbolVar
|
||||
|| node instanceof Cola.AST_SymbolConst) {
|
||||
var def = defun.def_variable(node);
|
||||
def.constant = node instanceof AST_SymbolConst;
|
||||
def.constant = node instanceof Cola.AST_SymbolConst;
|
||||
def.init = tw.parent().value;
|
||||
}
|
||||
else if (node instanceof AST_SymbolCatch) {
|
||||
else if (node instanceof Cola.AST_SymbolCatch) {
|
||||
(options.screw_ie8 ? scope : defun)
|
||||
.def_variable(node);
|
||||
}
|
||||
|
|
@ -140,16 +140,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||
|
||||
// pass 2: find back references and eval
|
||||
var func = null;
|
||||
var globals = self.globals = new Dictionary();
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node instanceof AST_Lambda) {
|
||||
var globals = self.globals = new Cola.Dictionary();
|
||||
var tw = new Cola.TreeWalker(function(node, descend){
|
||||
if (node instanceof Cola.AST_Lambda) {
|
||||
var prev_func = func;
|
||||
func = node;
|
||||
descend();
|
||||
func = prev_func;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
if (node instanceof Cola.AST_SymbolRef) {
|
||||
var name = node.name;
|
||||
var sym = node.scope.find_variable(name);
|
||||
if (!sym) {
|
||||
|
|
@ -163,7 +163,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||
globals.set(name, g);
|
||||
}
|
||||
node.thedef = g;
|
||||
if (name == "eval" && tw.parent() instanceof AST_Call) {
|
||||
if (name == "eval" && tw.parent() instanceof Cola.AST_Call) {
|
||||
for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope)
|
||||
s.uses_eval = true;
|
||||
}
|
||||
|
|
@ -180,10 +180,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||
self.walk(tw);
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
||||
Cola.AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
||||
this.directives = []; // contains the directives defined in this scope, i.e. "use strict"
|
||||
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||
this.variables = new Cola.Dictionary(); // map name to Cola.AST_SymbolVar (variables defined in this scope; includes functions)
|
||||
this.functions = new Cola.Dictionary(); // map name to Cola.AST_SymbolDefun (functions defined in this scope)
|
||||
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
||||
this.parent_scope = null; // the parent scope
|
||||
|
|
@ -192,43 +192,43 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
|||
this.nesting = nesting; // the nesting level of this scope (0 means toplevel)
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("strict", function(){
|
||||
Cola.AST_Scope.DEFMETHOD("strict", function(){
|
||||
return this.has_directive("use strict");
|
||||
});
|
||||
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||
Cola.AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
Cola.AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||
this.uses_arguments = false;
|
||||
});
|
||||
|
||||
AST_SymbolRef.DEFMETHOD("reference", function() {
|
||||
Cola.AST_SymbolRef.DEFMETHOD("reference", function() {
|
||||
var def = this.definition();
|
||||
def.references.push(this);
|
||||
var s = this.scope;
|
||||
while (s) {
|
||||
push_uniq(s.enclosed, def);
|
||||
Cola.push_uniq(s.enclosed, def);
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
this.frame = this.scope.nesting - def.scope.nesting;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
if (name instanceof AST_Symbol) name = name.name;
|
||||
Cola.AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
if (name instanceof Cola.AST_Symbol) name = name.name;
|
||||
return this.variables.get(name)
|
||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("has_directive", function(value){
|
||||
Cola.AST_Scope.DEFMETHOD("has_directive", function(value){
|
||||
return this.parent_scope && this.parent_scope.has_directive(value)
|
||||
|| (this.directives.indexOf(value) >= 0 ? this : null);
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||
Cola.AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
Cola.AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
var def;
|
||||
if (!this.variables.has(symbol.name)) {
|
||||
def = new SymbolDef(this, this.variables.size(), symbol);
|
||||
|
|
@ -241,11 +241,11 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
|||
return symbol.thedef = def;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
Cola.AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
var ext = this.enclosed;
|
||||
out: while (true) {
|
||||
var m = base54(++this.cname);
|
||||
if (!is_identifier(m)) continue; // skip over "do"
|
||||
if (!Cola.is_identifier(m)) continue; // skip over "do"
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||
// shadow a name excepted from mangling.
|
||||
|
|
@ -263,65 +263,65 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
|||
}
|
||||
});
|
||||
|
||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
Cola.AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
// #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
|
||||
|
||||
var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
|
||||
var tricky_def = def.orig[0] instanceof Cola.AST_SymbolFunarg && this.name && this.name.definition();
|
||||
while (true) {
|
||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
||||
var name = Cola.AST_Lambda.prototype.next_mangled.call(this, options, def);
|
||||
if (!(tricky_def && tricky_def.mangled_name == name))
|
||||
return name;
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("references", function(sym){
|
||||
if (sym instanceof AST_Symbol) sym = sym.definition();
|
||||
Cola.AST_Scope.DEFMETHOD("references", function(sym){
|
||||
if (sym instanceof Cola.AST_Symbol) sym = sym.definition();
|
||||
return this.enclosed.indexOf(sym) < 0 ? null : sym;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
Cola.AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
return this.definition().unmangleable(options);
|
||||
});
|
||||
|
||||
// property accessors are not mangleable
|
||||
AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
|
||||
Cola.AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
|
||||
return true;
|
||||
});
|
||||
|
||||
// labels are always mangleable
|
||||
AST_Label.DEFMETHOD("unmangleable", function(){
|
||||
Cola.AST_Label.DEFMETHOD("unmangleable", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
||||
Cola.AST_Symbol.DEFMETHOD("unreferenced", function(){
|
||||
return this.definition().references.length == 0
|
||||
&& !(this.scope.uses_eval || this.scope.uses_with);
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("undeclared", function(){
|
||||
Cola.AST_Symbol.DEFMETHOD("undeclared", function(){
|
||||
return this.definition().undeclared;
|
||||
});
|
||||
|
||||
AST_LabelRef.DEFMETHOD("undeclared", function(){
|
||||
Cola.AST_LabelRef.DEFMETHOD("undeclared", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Label.DEFMETHOD("undeclared", function(){
|
||||
Cola.AST_Label.DEFMETHOD("undeclared", function(){
|
||||
return false;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("definition", function(){
|
||||
Cola.AST_Symbol.DEFMETHOD("definition", function(){
|
||||
return this.thedef;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("global", function(){
|
||||
Cola.AST_Symbol.DEFMETHOD("global", function(){
|
||||
return this.definition().global;
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||
return defaults(options, {
|
||||
Cola.AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||
return Cola.defaults(options, {
|
||||
except : [],
|
||||
eval : false,
|
||||
sort : false,
|
||||
|
|
@ -330,23 +330,23 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
|||
});
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
Cola.AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
// We only need to mangle declaration nodes. Special logic wired
|
||||
// into the code generator will display the mangled name if it's
|
||||
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
||||
// the AST_SymbolDeclaration that it points to).
|
||||
// present (and for Cola.AST_SymbolRef-s it'll use the mangled name of
|
||||
// the Cola.AST_SymbolDeclaration that it points to).
|
||||
var lname = -1;
|
||||
var to_mangle = [];
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
// lname is incremented when we get to the AST_Label
|
||||
var tw = new Cola.TreeWalker(function(node, descend){
|
||||
if (node instanceof Cola.AST_LabeledStatement) {
|
||||
// lname is incremented when we get to the Cola.AST_Label
|
||||
var save_nesting = lname;
|
||||
descend();
|
||||
lname = save_nesting;
|
||||
return true; // don't descend again in TreeWalker
|
||||
return true; // don't descend again in Cola.TreeWalker
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
if (node instanceof Cola.AST_Scope) {
|
||||
var p = tw.parent(), a = [];
|
||||
node.variables.each(function(symbol){
|
||||
if (options.except.indexOf(symbol.name) < 0) {
|
||||
|
|
@ -359,13 +359,13 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||
to_mangle.push.apply(to_mangle, a);
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
if (node instanceof Cola.AST_Label) {
|
||||
var name;
|
||||
do name = base54(++lname); while (!is_identifier(name));
|
||||
do name = base54(++lname); while (!Cola.is_identifier(name));
|
||||
node.mangled_name = name;
|
||||
return true;
|
||||
}
|
||||
if (options.screw_ie8 && node instanceof AST_SymbolCatch) {
|
||||
if (options.screw_ie8 && node instanceof Cola.AST_SymbolCatch) {
|
||||
to_mangle.push(node.definition());
|
||||
return;
|
||||
}
|
||||
|
|
@ -374,70 +374,70 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||
Cola.AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
var tw = new TreeWalker(function(node){
|
||||
if (node instanceof AST_Constant)
|
||||
var tw = new Cola.TreeWalker(function(node){
|
||||
if (node instanceof Cola.AST_Constant)
|
||||
base54.consider(node.print_to_string());
|
||||
else if (node instanceof AST_Return)
|
||||
else if (node instanceof Cola.AST_Return)
|
||||
base54.consider("return");
|
||||
else if (node instanceof AST_Throw)
|
||||
else if (node instanceof Cola.AST_Throw)
|
||||
base54.consider("throw");
|
||||
else if (node instanceof AST_Continue)
|
||||
else if (node instanceof Cola.AST_Continue)
|
||||
base54.consider("continue");
|
||||
else if (node instanceof AST_Break)
|
||||
else if (node instanceof Cola.AST_Break)
|
||||
base54.consider("break");
|
||||
else if (node instanceof AST_Debugger)
|
||||
else if (node instanceof Cola.AST_Debugger)
|
||||
base54.consider("debugger");
|
||||
else if (node instanceof AST_Directive)
|
||||
else if (node instanceof Cola.AST_Directive)
|
||||
base54.consider(node.value);
|
||||
else if (node instanceof AST_While)
|
||||
else if (node instanceof Cola.AST_While)
|
||||
base54.consider("while");
|
||||
else if (node instanceof AST_Do)
|
||||
else if (node instanceof Cola.AST_Do)
|
||||
base54.consider("do while");
|
||||
else if (node instanceof AST_If) {
|
||||
else if (node instanceof Cola.AST_If) {
|
||||
base54.consider("if");
|
||||
if (node.alternative) base54.consider("else");
|
||||
}
|
||||
else if (node instanceof AST_Var)
|
||||
else if (node instanceof Cola.AST_Var)
|
||||
base54.consider("var");
|
||||
else if (node instanceof AST_Const)
|
||||
else if (node instanceof Cola.AST_Const)
|
||||
base54.consider("const");
|
||||
else if (node instanceof AST_Lambda)
|
||||
else if (node instanceof Cola.AST_Lambda)
|
||||
base54.consider("function");
|
||||
else if (node instanceof AST_For)
|
||||
else if (node instanceof Cola.AST_For)
|
||||
base54.consider("for");
|
||||
else if (node instanceof AST_ForIn)
|
||||
else if (node instanceof Cola.AST_ForIn)
|
||||
base54.consider("for in");
|
||||
else if (node instanceof AST_Switch)
|
||||
else if (node instanceof Cola.AST_Switch)
|
||||
base54.consider("switch");
|
||||
else if (node instanceof AST_Case)
|
||||
else if (node instanceof Cola.AST_Case)
|
||||
base54.consider("case");
|
||||
else if (node instanceof AST_Default)
|
||||
else if (node instanceof Cola.AST_Default)
|
||||
base54.consider("default");
|
||||
else if (node instanceof AST_With)
|
||||
else if (node instanceof Cola.AST_With)
|
||||
base54.consider("with");
|
||||
else if (node instanceof AST_ObjectSetter)
|
||||
else if (node instanceof Cola.AST_ObjectSetter)
|
||||
base54.consider("set" + node.key);
|
||||
else if (node instanceof AST_ObjectGetter)
|
||||
else if (node instanceof Cola.AST_ObjectGetter)
|
||||
base54.consider("get" + node.key);
|
||||
else if (node instanceof AST_ObjectKeyVal)
|
||||
else if (node instanceof Cola.AST_ObjectKeyVal)
|
||||
base54.consider(node.key);
|
||||
else if (node instanceof AST_New)
|
||||
else if (node instanceof Cola.AST_New)
|
||||
base54.consider("new");
|
||||
else if (node instanceof AST_This)
|
||||
else if (node instanceof Cola.AST_This)
|
||||
base54.consider("this");
|
||||
else if (node instanceof AST_Try)
|
||||
else if (node instanceof Cola.AST_Try)
|
||||
base54.consider("try");
|
||||
else if (node instanceof AST_Catch)
|
||||
else if (node instanceof Cola.AST_Catch)
|
||||
base54.consider("catch");
|
||||
else if (node instanceof AST_Finally)
|
||||
else if (node instanceof Cola.AST_Finally)
|
||||
base54.consider("finally");
|
||||
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
||||
else if (node instanceof Cola.AST_Symbol && node.unmangleable(options))
|
||||
base54.consider(node.name);
|
||||
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
||||
else if (node instanceof Cola.AST_Unary || node instanceof Cola.AST_Binary)
|
||||
base54.consider(node.operator);
|
||||
else if (node instanceof AST_Dot)
|
||||
else if (node instanceof Cola.AST_Dot)
|
||||
base54.consider(node.property);
|
||||
});
|
||||
this.walk(tw);
|
||||
|
|
@ -459,9 +459,9 @@ var base54 = (function() {
|
|||
}
|
||||
};
|
||||
base54.sort = function() {
|
||||
chars = mergeSort(chars, function(a, b){
|
||||
if (is_digit(a) && !is_digit(b)) return 1;
|
||||
if (is_digit(b) && !is_digit(a)) return -1;
|
||||
chars = Cola.mergeSort(chars, function(a, b){
|
||||
if (Cola.is_digit(a) && !Cola.is_digit(b)) return 1;
|
||||
if (Cola.is_digit(b) && !Cola.is_digit(a)) return -1;
|
||||
return frequency[b] - frequency[a];
|
||||
});
|
||||
};
|
||||
|
|
@ -481,8 +481,8 @@ var base54 = (function() {
|
|||
return base54;
|
||||
})();
|
||||
|
||||
AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
||||
options = defaults(options, {
|
||||
Cola.AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
||||
options = Cola.defaults(options, {
|
||||
undeclared : false, // this makes a lot of noise
|
||||
unreferenced : true,
|
||||
assign_to_global : true,
|
||||
|
|
@ -490,15 +490,15 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
|||
nested_defuns : true,
|
||||
eval : true
|
||||
});
|
||||
var tw = new TreeWalker(function(node){
|
||||
var tw = new Cola.TreeWalker(function(node){
|
||||
if (options.undeclared
|
||||
&& node instanceof AST_SymbolRef
|
||||
&& node instanceof Cola.AST_SymbolRef
|
||||
&& node.undeclared())
|
||||
{
|
||||
// XXX: this also warns about JS standard names,
|
||||
// i.e. Object, Array, parseInt etc. Should add a list of
|
||||
// exceptions.
|
||||
AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", {
|
||||
Cola.AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", {
|
||||
name: node.name,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
|
|
@ -508,14 +508,14 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
|||
if (options.assign_to_global)
|
||||
{
|
||||
var sym = null;
|
||||
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef)
|
||||
if (node instanceof Cola.AST_Assign && node.left instanceof Cola.AST_SymbolRef)
|
||||
sym = node.left;
|
||||
else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef)
|
||||
else if (node instanceof Cola.AST_ForIn && node.init instanceof Cola.AST_SymbolRef)
|
||||
sym = node.init;
|
||||
if (sym
|
||||
&& (sym.undeclared()
|
||||
|| (sym.global() && sym.scope !== sym.definition().scope))) {
|
||||
AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", {
|
||||
Cola.AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", {
|
||||
msg: sym.undeclared() ? "Accidental global?" : "Assignment to global",
|
||||
name: sym.name,
|
||||
file: sym.start.file,
|
||||
|
|
@ -525,16 +525,16 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
|||
}
|
||||
}
|
||||
if (options.eval
|
||||
&& node instanceof AST_SymbolRef
|
||||
&& node instanceof Cola.AST_SymbolRef
|
||||
&& node.undeclared()
|
||||
&& node.name == "eval") {
|
||||
AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start);
|
||||
Cola.AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start);
|
||||
}
|
||||
if (options.unreferenced
|
||||
&& (node instanceof AST_SymbolDeclaration || node instanceof AST_Label)
|
||||
&& (node instanceof Cola.AST_SymbolDeclaration || node instanceof Cola.AST_Label)
|
||||
&& node.unreferenced()) {
|
||||
AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", {
|
||||
type: node instanceof AST_Label ? "Label" : "Symbol",
|
||||
Cola.AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", {
|
||||
type: node instanceof Cola.AST_Label ? "Label" : "Symbol",
|
||||
name: node.name,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
|
|
@ -542,9 +542,9 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
|||
});
|
||||
}
|
||||
if (options.func_arguments
|
||||
&& node instanceof AST_Lambda
|
||||
&& node instanceof Cola.AST_Lambda
|
||||
&& node.uses_arguments) {
|
||||
AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", {
|
||||
Cola.AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", {
|
||||
name: node.name ? node.name.name : "anonymous",
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
|
|
@ -552,9 +552,9 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
|||
});
|
||||
}
|
||||
if (options.nested_defuns
|
||||
&& node instanceof AST_Defun
|
||||
&& !(tw.parent() instanceof AST_Scope)) {
|
||||
AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", {
|
||||
&& node instanceof Cola.AST_Defun
|
||||
&& !(tw.parent() instanceof Cola.AST_Scope)) {
|
||||
Cola.AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", {
|
||||
name: node.name.name,
|
||||
type: tw.parent().TYPE,
|
||||
file: node.start.file,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
// a small wrapper around fitzgen's source-map library
|
||||
function SourceMap(options) {
|
||||
options = defaults(options, {
|
||||
options = Cola.defaults(options, {
|
||||
file : null,
|
||||
root : null,
|
||||
orig : null,
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@
|
|||
// Tree transformer helpers.
|
||||
|
||||
function TreeTransformer(before, after) {
|
||||
TreeWalker.call(this);
|
||||
Cola.TreeWalker.call(this);
|
||||
this.before = before;
|
||||
this.after = after;
|
||||
}
|
||||
TreeTransformer.prototype = new TreeWalker;
|
||||
TreeTransformer.prototype = new Cola.TreeWalker;
|
||||
|
||||
(function(undefined){
|
||||
|
||||
|
|
@ -76,142 +76,142 @@ TreeTransformer.prototype = new TreeWalker;
|
|||
};
|
||||
|
||||
function do_list(list, tw) {
|
||||
return MAP(list, function(node){
|
||||
return Cola.MAP(list, function(node){
|
||||
return node.transform(tw, true);
|
||||
});
|
||||
};
|
||||
|
||||
_(AST_Node, noop);
|
||||
_(Cola.AST_Node, Cola.noop);
|
||||
|
||||
_(AST_LabeledStatement, function(self, tw){
|
||||
_(Cola.AST_LabeledStatement, function(self, tw){
|
||||
self.label = self.label.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_SimpleStatement, function(self, tw){
|
||||
_(Cola.AST_SimpleStatement, function(self, tw){
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Block, function(self, tw){
|
||||
_(Cola.AST_Block, function(self, tw){
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_DWLoop, function(self, tw){
|
||||
_(Cola.AST_DWLoop, function(self, tw){
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_For, function(self, tw){
|
||||
_(Cola.AST_For, function(self, tw){
|
||||
if (self.init) self.init = self.init.transform(tw);
|
||||
if (self.condition) self.condition = self.condition.transform(tw);
|
||||
if (self.step) self.step = self.step.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_ForIn, function(self, tw){
|
||||
_(Cola.AST_ForIn, function(self, tw){
|
||||
self.init = self.init.transform(tw);
|
||||
self.object = self.object.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_With, function(self, tw){
|
||||
_(Cola.AST_With, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Exit, function(self, tw){
|
||||
_(Cola.AST_Exit, function(self, tw){
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_LoopControl, function(self, tw){
|
||||
_(Cola.AST_LoopControl, function(self, tw){
|
||||
if (self.label) self.label = self.label.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_If, function(self, tw){
|
||||
_(Cola.AST_If, function(self, tw){
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Switch, function(self, tw){
|
||||
_(Cola.AST_Switch, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Case, function(self, tw){
|
||||
_(Cola.AST_Case, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Try, function(self, tw){
|
||||
_(Cola.AST_Try, function(self, tw){
|
||||
self.body = do_list(self.body, tw);
|
||||
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
||||
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Catch, function(self, tw){
|
||||
_(Cola.AST_Catch, function(self, tw){
|
||||
self.argname = self.argname.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Definitions, function(self, tw){
|
||||
_(Cola.AST_Definitions, function(self, tw){
|
||||
self.definitions = do_list(self.definitions, tw);
|
||||
});
|
||||
|
||||
_(AST_VarDef, function(self, tw){
|
||||
_(Cola.AST_VarDef, function(self, tw){
|
||||
self.name = self.name.transform(tw);
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Lambda, function(self, tw){
|
||||
_(Cola.AST_Lambda, function(self, tw){
|
||||
if (self.name) self.name = self.name.transform(tw);
|
||||
self.argnames = do_list(self.argnames, tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Call, function(self, tw){
|
||||
_(Cola.AST_Call, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.args = do_list(self.args, tw);
|
||||
});
|
||||
|
||||
_(AST_Seq, function(self, tw){
|
||||
_(Cola.AST_Seq, function(self, tw){
|
||||
self.car = self.car.transform(tw);
|
||||
self.cdr = self.cdr.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Dot, function(self, tw){
|
||||
_(Cola.AST_Dot, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Sub, function(self, tw){
|
||||
_(Cola.AST_Sub, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.property = self.property.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Unary, function(self, tw){
|
||||
_(Cola.AST_Unary, function(self, tw){
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Binary, function(self, tw){
|
||||
_(Cola.AST_Binary, function(self, tw){
|
||||
self.left = self.left.transform(tw);
|
||||
self.right = self.right.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Conditional, function(self, tw){
|
||||
_(Cola.AST_Conditional, function(self, tw){
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.consequent = self.consequent.transform(tw);
|
||||
self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Array, function(self, tw){
|
||||
_(Cola.AST_Array, function(self, tw){
|
||||
self.elements = do_list(self.elements, tw);
|
||||
});
|
||||
|
||||
_(AST_Object, function(self, tw){
|
||||
_(Cola.AST_Object, function(self, tw){
|
||||
self.properties = do_list(self.properties, tw);
|
||||
});
|
||||
|
||||
_(AST_ObjectProperty, function(self, tw){
|
||||
_(Cola.AST_ObjectProperty, function(self, tw){
|
||||
self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -41,114 +41,114 @@ function translate(tree){
|
|||
var tt = new TreeTransformer(null, function(node){
|
||||
var newNode, props;
|
||||
|
||||
if(node instanceof AST_Binary && node.operator == '**'){
|
||||
if(node instanceof Cola.AST_Binary && node.operator == '**'){
|
||||
props = {
|
||||
args : [node.left, node.right],
|
||||
start : new AST_Token({ nlb : false, type : 'name', value : 'Math' }),
|
||||
end : new AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
start : new Cola.AST_Token({ nlb : false, type : 'name', value : 'Math' }),
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
};
|
||||
props.expression = new AST_Dot({
|
||||
props.expression = new Cola.AST_Dot({
|
||||
property : 'pow',
|
||||
start : props.start,
|
||||
end : new AST_Token({ nlb : false, type : 'name', value : 'pow' }),
|
||||
expression : new AST_SymbolRef({ name : 'Math', start : props.start, end : props.start })
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'name', value : 'pow' }),
|
||||
expression : new Cola.AST_SymbolRef({ name : 'Math', start : props.start, end : props.start })
|
||||
});
|
||||
|
||||
node = new AST_Call(props);
|
||||
node = new Cola.AST_Call(props);
|
||||
} else
|
||||
|
||||
if(node instanceof AST_Binary && node.operator == '%%'){
|
||||
if(node instanceof Cola.AST_Binary && node.operator == '%%'){
|
||||
props = {
|
||||
args : [node.left, node.right],
|
||||
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_modulo' }),
|
||||
end : new AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_modulo' }),
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
};
|
||||
props.expression = new AST_SymbolRef({
|
||||
props.expression = new Cola.AST_SymbolRef({
|
||||
name : '$_cola_modulo',
|
||||
start : props.start,
|
||||
end : props.start
|
||||
});
|
||||
|
||||
node = new AST_Call(props);
|
||||
node = new Cola.AST_Call(props);
|
||||
} else
|
||||
|
||||
if(node instanceof AST_SimpleStatement && node.body instanceof AST_Assign && node.body.operator == '?='){
|
||||
if(node instanceof Cola.AST_SimpleStatement && node.body instanceof Cola.AST_Assign && node.body.operator == '?='){
|
||||
node.body.operator = '=';
|
||||
|
||||
props = {
|
||||
args : [node.body.left],
|
||||
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_isntset' }),
|
||||
end : new AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_isntset' }),
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
};
|
||||
props.expression = new AST_SymbolRef({
|
||||
props.expression = new Cola.AST_SymbolRef({
|
||||
name : '$_cola_isntset',
|
||||
start : props.start,
|
||||
end : props.start
|
||||
});
|
||||
|
||||
node = new AST_If({
|
||||
node = new Cola.AST_If({
|
||||
body : node.clone(),
|
||||
start : new AST_Token({ nlb : false, type : 'keyword', value : 'if' }),
|
||||
end : new AST_Token({ nlb : false, type : 'punc', value : ';' }),
|
||||
condition : new AST_Call(props)
|
||||
start : new Cola.AST_Token({ nlb : false, type : 'keyword', value : 'if' }),
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ';' }),
|
||||
condition : new Cola.AST_Call(props)
|
||||
});
|
||||
} else
|
||||
|
||||
if(node instanceof AST_Assign && node.operator == '?='){
|
||||
if(node instanceof Cola.AST_Assign && node.operator == '?='){
|
||||
node.operator = '=';
|
||||
|
||||
props = {
|
||||
args : [node.left],
|
||||
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_isntset' }),
|
||||
end : new AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_isntset' }),
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
};
|
||||
props.expression = new AST_SymbolRef({
|
||||
props.expression = new Cola.AST_SymbolRef({
|
||||
name : '$_cola_isntset',
|
||||
start : props.start,
|
||||
end : props.start
|
||||
});
|
||||
|
||||
node = new AST_Conditional({
|
||||
start : new AST_Token({ nlb : false, type : 'punc', value : '(' }),
|
||||
end : new AST_Token({ nlb : false, type : 'punc', value : ')' }),
|
||||
condition : new AST_Call(props),
|
||||
node = new Cola.AST_Conditional({
|
||||
start : new Cola.AST_Token({ nlb : false, type : 'punc', value : '(' }),
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' }),
|
||||
condition : new Cola.AST_Call(props),
|
||||
consequent : node.clone(),
|
||||
alternative : node.left
|
||||
});
|
||||
} else
|
||||
|
||||
if(node instanceof AST_Binary && node.operator == 'is'){
|
||||
if(node instanceof Cola.AST_Binary && node.operator == 'is'){
|
||||
props = {
|
||||
args : [node.left, node.right],
|
||||
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_is' }),
|
||||
end : new AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_is' }),
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
};
|
||||
props.expression = new AST_SymbolRef({
|
||||
props.expression = new Cola.AST_SymbolRef({
|
||||
name : '$_cola_is',
|
||||
start : props.start,
|
||||
end : props.start
|
||||
});
|
||||
|
||||
node = new AST_Call(props);
|
||||
node = new Cola.AST_Call(props);
|
||||
} else
|
||||
|
||||
if(node instanceof AST_Binary && node.operator == 'isnt'){
|
||||
if(node instanceof Cola.AST_Binary && node.operator == 'isnt'){
|
||||
props = {
|
||||
args : [node.left, node.right],
|
||||
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_isnt' }),
|
||||
end : new AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_isnt' }),
|
||||
end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
|
||||
};
|
||||
props.expression = new AST_SymbolRef({
|
||||
props.expression = new Cola.AST_SymbolRef({
|
||||
name : '$_cola_isnt',
|
||||
start : props.start,
|
||||
end : props.start
|
||||
});
|
||||
|
||||
node = new AST_Call(props);
|
||||
node = new Cola.AST_Call(props);
|
||||
} else
|
||||
|
||||
if(node instanceof AST_StringTemplate){
|
||||
newNode = new AST_Binary({
|
||||
if(node instanceof Cola.AST_StringTemplate){
|
||||
newNode = new Cola.AST_Binary({
|
||||
operator : '+',
|
||||
left : node.body[0],
|
||||
right : node.body[1],
|
||||
|
|
@ -156,7 +156,7 @@ function translate(tree){
|
|||
end : node.body[1].end
|
||||
});
|
||||
for(var i = 2; i < node.body.length; i++)
|
||||
newNode = new AST_Binary({
|
||||
newNode = new Cola.AST_Binary({
|
||||
operator : '+',
|
||||
left : newNode,
|
||||
right : node.body[i],
|
||||
|
|
@ -167,7 +167,7 @@ function translate(tree){
|
|||
node = newNode;
|
||||
} else
|
||||
|
||||
if(node instanceof AST_RegExp && (node.value.indexOf('\n') != -1 || /\/[\w]*x[\w]*$/.test(node.value))){
|
||||
if(node instanceof Cola.AST_RegExp && (node.value.indexOf('\n') != -1 || /\/[\w]*x[\w]*$/.test(node.value))){
|
||||
node.value = node.value.replace(/[\r\n\s]/g,'').replace(/(\/[\w]*)x([\w]*$)/, '$1$2');
|
||||
}
|
||||
|
||||
|
|
|
|||
55
lib/utils.js
55
lib/utils.js
|
|
@ -42,79 +42,80 @@
|
|||
***********************************************************************/
|
||||
|
||||
"use strict";
|
||||
!window.Cola && (window.Cola = {});
|
||||
|
||||
function array_to_hash(a) {
|
||||
Cola.array_to_hash = function (a) {
|
||||
var ret = Object.create(null);
|
||||
for (var i = 0; i < a.length; ++i)
|
||||
ret[a[i]] = true;
|
||||
return ret;
|
||||
};
|
||||
|
||||
function slice(a, start) {
|
||||
Cola.slice = function (a, start) {
|
||||
return Array.prototype.slice.call(a, start || 0);
|
||||
};
|
||||
|
||||
function characters(str) {
|
||||
Cola.characters = function (str) {
|
||||
return str.split("");
|
||||
};
|
||||
|
||||
function member(name, array) {
|
||||
Cola.member = function (name, array) {
|
||||
for (var i = array.length; --i >= 0;)
|
||||
if (array[i] == name)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
function find_if(func, array) {
|
||||
Cola.find_if = function (func, array) {
|
||||
for (var i = 0, n = array.length; i < n; ++i) {
|
||||
if (func(array[i]))
|
||||
return array[i];
|
||||
}
|
||||
};
|
||||
|
||||
function repeat_string(str, i) {
|
||||
Cola.repeat_string = function (str, i) {
|
||||
if (i <= 0) return "";
|
||||
if (i == 1) return str;
|
||||
var d = repeat_string(str, i >> 1);
|
||||
var d = Cola.repeat_string(str, i >> 1);
|
||||
d += d;
|
||||
if (i & 1) d += str;
|
||||
return d;
|
||||
};
|
||||
|
||||
function DefaultsError(msg, defs) {
|
||||
Cola.DefaultsError = function (msg, defs) {
|
||||
Error.call(this, msg);
|
||||
this.msg = msg;
|
||||
this.defs = defs;
|
||||
};
|
||||
DefaultsError.prototype = Object.create(Error.prototype);
|
||||
DefaultsError.prototype.constructor = DefaultsError;
|
||||
Cola.DefaultsError.prototype = Object.create(Error.prototype);
|
||||
Cola.DefaultsError.prototype.constructor = Cola.DefaultsError;
|
||||
|
||||
DefaultsError.croak = function(msg, defs) {
|
||||
throw new DefaultsError(msg, defs);
|
||||
Cola.DefaultsError.croak = function(msg, defs) {
|
||||
throw new Cola.DefaultsError(msg, defs);
|
||||
};
|
||||
|
||||
function defaults(args, defs, croak) {
|
||||
Cola.defaults = function (args, defs, croak) {
|
||||
if (args === true)
|
||||
args = {};
|
||||
var ret = args || {};
|
||||
if (croak) for (var i in ret) if (ret.hasOwnProperty(i) && !defs.hasOwnProperty(i))
|
||||
DefaultsError.croak("`" + i + "` is not a supported option", defs);
|
||||
Cola.DefaultsError.croak("`" + i + "` is not a supported option", defs);
|
||||
for (var i in defs) if (defs.hasOwnProperty(i)) {
|
||||
ret[i] = (args && args.hasOwnProperty(i)) ? args[i] : defs[i];
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
function merge(obj, ext) {
|
||||
Cola.merge = function (obj, ext) {
|
||||
for (var i in ext) if (ext.hasOwnProperty(i)) {
|
||||
obj[i] = ext[i];
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
function noop() {};
|
||||
Cola.noop = function () {};
|
||||
|
||||
var MAP = (function(){
|
||||
Cola.MAP = (function(){
|
||||
function MAP(a, f, backwards) {
|
||||
var ret = [], top = [], i;
|
||||
function doit() {
|
||||
|
|
@ -162,24 +163,24 @@ var MAP = (function(){
|
|||
return MAP;
|
||||
})();
|
||||
|
||||
function push_uniq(array, el) {
|
||||
Cola.push_uniq = function (array, el) {
|
||||
if (array.indexOf(el) < 0)
|
||||
array.push(el);
|
||||
};
|
||||
|
||||
function string_template(text, props) {
|
||||
Cola.string_template = function (text, props) {
|
||||
return text.replace(/\{(.+?)\}/g, function(str, p){
|
||||
return props[p];
|
||||
});
|
||||
};
|
||||
|
||||
function remove(array, el) {
|
||||
Cola.remove = function (array, el) {
|
||||
for (var i = array.length; --i >= 0;) {
|
||||
if (array[i] === el) array.splice(i, 1);
|
||||
}
|
||||
};
|
||||
|
||||
function mergeSort(array, cmp) {
|
||||
Cola.mergeSort = function (array, cmp) {
|
||||
if (array.length < 2) return array.slice();
|
||||
function merge(a, b) {
|
||||
var r = [], ai = 0, bi = 0, i = 0;
|
||||
|
|
@ -203,13 +204,13 @@ function mergeSort(array, cmp) {
|
|||
return _ms(array);
|
||||
};
|
||||
|
||||
function set_difference(a, b) {
|
||||
Cola.set_difference = function (a, b) {
|
||||
return a.filter(function(el){
|
||||
return b.indexOf(el) < 0;
|
||||
});
|
||||
};
|
||||
|
||||
function set_intersection(a, b) {
|
||||
Cola.set_intersection = function (a, b) {
|
||||
return a.filter(function(el){
|
||||
return b.indexOf(el) >= 0;
|
||||
});
|
||||
|
|
@ -217,7 +218,7 @@ function set_intersection(a, b) {
|
|||
|
||||
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
||||
// [1] https://github.com/marijnh/acorn
|
||||
function makePredicate(words) {
|
||||
Cola.makePredicate = function (words) {
|
||||
if (!(words instanceof Array)) words = words.split(" ");
|
||||
var f = "", cats = [];
|
||||
out: for (var i = 0; i < words.length; ++i) {
|
||||
|
|
@ -252,18 +253,18 @@ function makePredicate(words) {
|
|||
return new Function("str", f);
|
||||
};
|
||||
|
||||
function all(array, predicate) {
|
||||
Cola.all = function (array, predicate) {
|
||||
for (var i = array.length; --i >= 0;)
|
||||
if (!predicate(array[i]))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
function Dictionary() {
|
||||
Cola.Dictionary = function () {
|
||||
this._values = Object.create(null);
|
||||
this._size = 0;
|
||||
};
|
||||
Dictionary.prototype = {
|
||||
Cola.Dictionary.prototype = {
|
||||
set: function(key, val) {
|
||||
if (!this.has(key)) ++this._size;
|
||||
this._values["$" + key] = val;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user