Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80713 views
1
/***********************************************************************
2
3
A JavaScript tokenizer / parser / beautifier / compressor.
4
https://github.com/mishoo/UglifyJS2
5
6
-------------------------------- (C) ---------------------------------
7
8
Author: Mihai Bazon
9
<[email protected]>
10
http://mihai.bazon.net/blog
11
12
Distributed under the BSD license:
13
14
Copyright 2012 (c) Mihai Bazon <[email protected]>
15
16
Redistribution and use in source and binary forms, with or without
17
modification, are permitted provided that the following conditions
18
are met:
19
20
* Redistributions of source code must retain the above
21
copyright notice, this list of conditions and the following
22
disclaimer.
23
24
* Redistributions in binary form must reproduce the above
25
copyright notice, this list of conditions and the following
26
disclaimer in the documentation and/or other materials
27
provided with the distribution.
28
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
30
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
33
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
34
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
39
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40
SUCH DAMAGE.
41
42
***********************************************************************/
43
44
"use strict";
45
46
(function(){
47
48
var MOZ_TO_ME = {
49
TryStatement : function(M) {
50
return new AST_Try({
51
start : my_start_token(M),
52
end : my_end_token(M),
53
body : from_moz(M.block).body,
54
bcatch : from_moz(M.handlers[0]),
55
bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
56
});
57
},
58
CatchClause : function(M) {
59
return new AST_Catch({
60
start : my_start_token(M),
61
end : my_end_token(M),
62
argname : from_moz(M.param),
63
body : from_moz(M.body).body
64
});
65
},
66
ObjectExpression : function(M) {
67
return new AST_Object({
68
start : my_start_token(M),
69
end : my_end_token(M),
70
properties : M.properties.map(function(prop){
71
var key = prop.key;
72
var name = key.type == "Identifier" ? key.name : key.value;
73
var args = {
74
start : my_start_token(key),
75
end : my_end_token(prop.value),
76
key : name,
77
value : from_moz(prop.value)
78
};
79
switch (prop.kind) {
80
case "init":
81
return new AST_ObjectKeyVal(args);
82
case "set":
83
args.value.name = from_moz(key);
84
return new AST_ObjectSetter(args);
85
case "get":
86
args.value.name = from_moz(key);
87
return new AST_ObjectGetter(args);
88
}
89
})
90
});
91
},
92
SequenceExpression : function(M) {
93
return AST_Seq.from_array(M.expressions.map(from_moz));
94
},
95
MemberExpression : function(M) {
96
return new (M.computed ? AST_Sub : AST_Dot)({
97
start : my_start_token(M),
98
end : my_end_token(M),
99
property : M.computed ? from_moz(M.property) : M.property.name,
100
expression : from_moz(M.object)
101
});
102
},
103
SwitchCase : function(M) {
104
return new (M.test ? AST_Case : AST_Default)({
105
start : my_start_token(M),
106
end : my_end_token(M),
107
expression : from_moz(M.test),
108
body : M.consequent.map(from_moz)
109
});
110
},
111
Literal : function(M) {
112
var val = M.value, args = {
113
start : my_start_token(M),
114
end : my_end_token(M)
115
};
116
if (val === null) return new AST_Null(args);
117
switch (typeof val) {
118
case "string":
119
args.value = val;
120
return new AST_String(args);
121
case "number":
122
args.value = val;
123
return new AST_Number(args);
124
case "boolean":
125
return new (val ? AST_True : AST_False)(args);
126
default:
127
args.value = val;
128
return new AST_RegExp(args);
129
}
130
},
131
UnaryExpression: From_Moz_Unary,
132
UpdateExpression: From_Moz_Unary,
133
Identifier: function(M) {
134
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
135
return new (M.name == "this" ? AST_This
136
: p.type == "LabeledStatement" ? AST_Label
137
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar)
138
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
139
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
140
: p.type == "CatchClause" ? AST_SymbolCatch
141
: p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef
142
: AST_SymbolRef)({
143
start : my_start_token(M),
144
end : my_end_token(M),
145
name : M.name
146
});
147
}
148
};
149
150
function From_Moz_Unary(M) {
151
var prefix = "prefix" in M ? M.prefix
152
: M.type == "UnaryExpression" ? true : false;
153
return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
154
start : my_start_token(M),
155
end : my_end_token(M),
156
operator : M.operator,
157
expression : from_moz(M.argument)
158
});
159
};
160
161
var ME_TO_MOZ = {};
162
163
map("Node", AST_Node);
164
map("Program", AST_Toplevel, "body@body");
165
map("Function", AST_Function, "id>name, params@argnames, body%body");
166
map("EmptyStatement", AST_EmptyStatement);
167
map("BlockStatement", AST_BlockStatement, "body@body");
168
map("ExpressionStatement", AST_SimpleStatement, "expression>body");
169
map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
170
map("LabeledStatement", AST_LabeledStatement, "label>label, body>body");
171
map("BreakStatement", AST_Break, "label>label");
172
map("ContinueStatement", AST_Continue, "label>label");
173
map("WithStatement", AST_With, "object>expression, body>body");
174
map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body");
175
map("ReturnStatement", AST_Return, "argument>value");
176
map("ThrowStatement", AST_Throw, "argument>value");
177
map("WhileStatement", AST_While, "test>condition, body>body");
178
map("DoWhileStatement", AST_Do, "test>condition, body>body");
179
map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
180
map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
181
map("DebuggerStatement", AST_Debugger);
182
map("FunctionDeclaration", AST_Defun, "id>name, params@argnames, body%body");
183
map("VariableDeclaration", AST_Var, "declarations@definitions");
184
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
185
186
map("ThisExpression", AST_This);
187
map("ArrayExpression", AST_Array, "elements@elements");
188
map("FunctionExpression", AST_Function, "id>name, params@argnames, body%body");
189
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
190
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
191
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
192
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
193
map("NewExpression", AST_New, "callee>expression, arguments@args");
194
map("CallExpression", AST_Call, "callee>expression, arguments@args");
195
196
/* -----[ tools ]----- */
197
198
function my_start_token(moznode) {
199
return new AST_Token({
200
file : moznode.loc && moznode.loc.source,
201
line : moznode.loc && moznode.loc.start.line,
202
col : moznode.loc && moznode.loc.start.column,
203
pos : moznode.start,
204
endpos : moznode.start
205
});
206
};
207
208
function my_end_token(moznode) {
209
return new AST_Token({
210
file : moznode.loc && moznode.loc.source,
211
line : moznode.loc && moznode.loc.end.line,
212
col : moznode.loc && moznode.loc.end.column,
213
pos : moznode.end,
214
endpos : moznode.end
215
});
216
};
217
218
function map(moztype, mytype, propmap) {
219
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
220
moz_to_me += "return new mytype({\n" +
221
"start: my_start_token(M),\n" +
222
"end: my_end_token(M)";
223
224
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){
225
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
226
if (!m) throw new Error("Can't understand property map: " + prop);
227
var moz = "M." + m[1], how = m[2], my = m[3];
228
moz_to_me += ",\n" + my + ": ";
229
if (how == "@") {
230
moz_to_me += moz + ".map(from_moz)";
231
} else if (how == ">") {
232
moz_to_me += "from_moz(" + moz + ")";
233
} else if (how == "=") {
234
moz_to_me += moz;
235
} else if (how == "%") {
236
moz_to_me += "from_moz(" + moz + ").body";
237
} else throw new Error("Can't understand operator in propmap: " + prop);
238
});
239
moz_to_me += "\n})}";
240
241
// moz_to_me = parse(moz_to_me).print_to_string({ beautify: true });
242
// console.log(moz_to_me);
243
244
moz_to_me = new Function("mytype", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
245
mytype, my_start_token, my_end_token, from_moz
246
);
247
return MOZ_TO_ME[moztype] = moz_to_me;
248
};
249
250
var FROM_MOZ_STACK = null;
251
252
function from_moz(node) {
253
FROM_MOZ_STACK.push(node);
254
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
255
FROM_MOZ_STACK.pop();
256
return ret;
257
};
258
259
AST_Node.from_mozilla_ast = function(node){
260
var save_stack = FROM_MOZ_STACK;
261
FROM_MOZ_STACK = [];
262
var ast = from_moz(node);
263
FROM_MOZ_STACK = save_stack;
264
return ast;
265
};
266
267
})();
268
269