Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80760 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
return new (M.prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
152
start : my_start_token(M),
153
end : my_end_token(M),
154
operator : M.operator,
155
expression : from_moz(M.argument)
156
})
157
};
158
159
var ME_TO_MOZ = {};
160
161
map("Node", AST_Node);
162
map("Program", AST_Toplevel, "body@body");
163
map("Function", AST_Function, "id>name, params@argnames, body%body");
164
map("EmptyStatement", AST_EmptyStatement);
165
map("BlockStatement", AST_BlockStatement, "body@body");
166
map("ExpressionStatement", AST_SimpleStatement, "expression>body");
167
map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
168
map("LabeledStatement", AST_LabeledStatement, "label>label, body>body");
169
map("BreakStatement", AST_Break, "label>label");
170
map("ContinueStatement", AST_Continue, "label>label");
171
map("WithStatement", AST_With, "object>expression, body>body");
172
map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body");
173
map("ReturnStatement", AST_Return, "argument>value");
174
map("ThrowStatement", AST_Throw, "argument>value");
175
map("WhileStatement", AST_While, "test>condition, body>body");
176
map("DoWhileStatement", AST_Do, "test>condition, body>body");
177
map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
178
map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
179
map("DebuggerStatement", AST_Debugger);
180
map("FunctionDeclaration", AST_Defun, "id>name, params@argnames, body%body");
181
map("VariableDeclaration", AST_Var, "declarations@definitions");
182
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
183
184
map("ThisExpression", AST_This);
185
map("ArrayExpression", AST_Array, "elements@elements");
186
map("FunctionExpression", AST_Function, "id>name, params@argnames, body%body");
187
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
188
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
189
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
190
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
191
map("NewExpression", AST_New, "callee>expression, arguments@args");
192
map("CallExpression", AST_Call, "callee>expression, arguments@args");
193
194
/* -----[ tools ]----- */
195
196
function my_start_token(moznode) {
197
return new AST_Token({
198
file : moznode.loc && moznode.loc.source,
199
line : moznode.loc && moznode.loc.start.line,
200
col : moznode.loc && moznode.loc.start.column,
201
pos : moznode.start,
202
endpos : moznode.start
203
});
204
};
205
206
function my_end_token(moznode) {
207
return new AST_Token({
208
file : moznode.loc && moznode.loc.source,
209
line : moznode.loc && moznode.loc.end.line,
210
col : moznode.loc && moznode.loc.end.column,
211
pos : moznode.end,
212
endpos : moznode.end
213
});
214
};
215
216
function map(moztype, mytype, propmap) {
217
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
218
moz_to_me += "return new mytype({\n" +
219
"start: my_start_token(M),\n" +
220
"end: my_end_token(M)";
221
222
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){
223
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
224
if (!m) throw new Error("Can't understand property map: " + prop);
225
var moz = "M." + m[1], how = m[2], my = m[3];
226
moz_to_me += ",\n" + my + ": ";
227
if (how == "@") {
228
moz_to_me += moz + ".map(from_moz)";
229
} else if (how == ">") {
230
moz_to_me += "from_moz(" + moz + ")";
231
} else if (how == "=") {
232
moz_to_me += moz;
233
} else if (how == "%") {
234
moz_to_me += "from_moz(" + moz + ").body";
235
} else throw new Error("Can't understand operator in propmap: " + prop);
236
});
237
moz_to_me += "\n})}";
238
239
// moz_to_me = parse(moz_to_me).print_to_string({ beautify: true });
240
// console.log(moz_to_me);
241
242
moz_to_me = new Function("mytype", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
243
mytype, my_start_token, my_end_token, from_moz
244
);
245
return MOZ_TO_ME[moztype] = moz_to_me;
246
};
247
248
var FROM_MOZ_STACK = null;
249
250
function from_moz(node) {
251
FROM_MOZ_STACK.push(node);
252
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
253
FROM_MOZ_STACK.pop();
254
return ret;
255
};
256
257
AST_Node.from_mozilla_ast = function(node){
258
var save_stack = FROM_MOZ_STACK;
259
FROM_MOZ_STACK = [];
260
var ast = from_moz(node);
261
FROM_MOZ_STACK = save_stack;
262
return ast;
263
};
264
265
})();
266
267