Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80743 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 find_builtins() {
47
var a = [];
48
[ Object, Array, Function, Number,
49
String, Boolean, Error, Math,
50
Date, RegExp
51
].forEach(function(ctor){
52
Object.getOwnPropertyNames(ctor).map(add);
53
if (ctor.prototype) {
54
Object.getOwnPropertyNames(ctor.prototype).map(add);
55
}
56
});
57
function add(name) {
58
push_uniq(a, name);
59
}
60
return a;
61
}
62
63
function mangle_properties(ast, options) {
64
options = defaults(options, {
65
reserved : null,
66
cache : null,
67
only_cache : false
68
});
69
70
var reserved = options.reserved;
71
if (reserved == null)
72
reserved = find_builtins();
73
74
var cache = options.cache;
75
if (cache == null) {
76
cache = {
77
cname: -1,
78
props: new Dictionary()
79
};
80
}
81
82
var names_to_mangle = [];
83
84
// step 1: find candidates to mangle
85
ast.walk(new TreeWalker(function(node){
86
if (node instanceof AST_ObjectKeyVal) {
87
add(node.key);
88
}
89
else if (node instanceof AST_ObjectProperty) {
90
// setter or getter, since KeyVal is handled above
91
add(node.key.name);
92
}
93
else if (node instanceof AST_Dot) {
94
if (this.parent() instanceof AST_Assign) {
95
add(node.property);
96
}
97
}
98
else if (node instanceof AST_Sub) {
99
if (this.parent() instanceof AST_Assign) {
100
addStrings(node.property);
101
}
102
}
103
}));
104
105
// step 2: transform the tree, renaming properties
106
return ast.transform(new TreeTransformer(function(node){
107
if (node instanceof AST_ObjectKeyVal) {
108
if (should_mangle(node.key)) {
109
node.key = mangle(node.key);
110
}
111
}
112
else if (node instanceof AST_ObjectProperty) {
113
// setter or getter
114
if (should_mangle(node.key.name)) {
115
node.key.name = mangle(node.key.name);
116
}
117
}
118
else if (node instanceof AST_Dot) {
119
if (should_mangle(node.property)) {
120
node.property = mangle(node.property);
121
}
122
}
123
else if (node instanceof AST_Sub) {
124
node.property = mangleStrings(node.property);
125
}
126
// else if (node instanceof AST_String) {
127
// if (should_mangle(node.value)) {
128
// AST_Node.warn(
129
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
130
// file : node.start.file,
131
// line : node.start.line,
132
// col : node.start.col,
133
// prop : node.value
134
// }
135
// );
136
// }
137
// }
138
}));
139
140
// only function declarations after this line
141
142
function can_mangle(name) {
143
if (reserved.indexOf(name) >= 0) return false;
144
if (options.only_cache) {
145
return cache.props.has(name);
146
}
147
if (/^[0-9.]+$/.test(name)) return false;
148
return true;
149
}
150
151
function should_mangle(name) {
152
if (reserved.indexOf(name) >= 0) return false;
153
return cache.props.has(name)
154
|| names_to_mangle.indexOf(name) >= 0;
155
}
156
157
function add(name) {
158
if (can_mangle(name))
159
push_uniq(names_to_mangle, name);
160
}
161
162
function mangle(name) {
163
var mangled = cache.props.get(name);
164
if (!mangled) {
165
do {
166
mangled = base54(++cache.cname);
167
} while (!can_mangle(mangled));
168
cache.props.set(name, mangled);
169
}
170
return mangled;
171
}
172
173
function addStrings(node) {
174
var out = {};
175
try {
176
(function walk(node){
177
node.walk(new TreeWalker(function(node){
178
if (node instanceof AST_Seq) {
179
walk(node.cdr);
180
return true;
181
}
182
if (node instanceof AST_String) {
183
add(node.value);
184
return true;
185
}
186
if (node instanceof AST_Conditional) {
187
walk(node.consequent);
188
walk(node.alternative);
189
return true;
190
}
191
throw out;
192
}));
193
})(node);
194
} catch(ex) {
195
if (ex !== out) throw ex;
196
}
197
}
198
199
function mangleStrings(node) {
200
return node.transform(new TreeTransformer(function(node){
201
if (node instanceof AST_Seq) {
202
node.cdr = mangleStrings(node.cdr);
203
}
204
else if (node instanceof AST_String) {
205
if (should_mangle(node.value)) {
206
node.value = mangle(node.value);
207
}
208
}
209
else if (node instanceof AST_Conditional) {
210
node.consequent = mangleStrings(node.consequent);
211
node.alternative = mangleStrings(node.alternative);
212
}
213
return node;
214
}));
215
}
216
217
}
218
219