Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
J
jquery
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
夏彬
jquery
Commits
f4b5d3fc
Commit
f4b5d3fc
authored
May 02, 2011
by
John Resig
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update the UglifyJS code.
parent
c0d99390
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
222 additions
and
90 deletions
+222
-90
parse-js.js
build/lib/parse-js.js
+18
-22
process.js
build/lib/process.js
+73
-23
uglify.js
build/uglify.js
+131
-45
No files found.
build/lib/parse-js.js
View file @
f4b5d3fc
...
...
@@ -751,14 +751,17 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
};
var statement = embed_tokens ? function() {
var start = S.token;
var ast = $statement.apply(this, arguments);
ast[0] = add_tokens(ast[0], start, prev());
return ast;
} : $statement;
function $statement() {
function maybe_embed_tokens(parser) {
if (embed_tokens) return function() {
var start = S.token;
var ast = parser.apply(this, arguments);
ast[0] = add_tokens(ast[0], start, prev());
return ast;
};
else return parser;
};
var statement = maybe_embed_tokens(function() {
if (is("
operator
", "
/
")) {
S.peeked = null;
S.token = S.input(true); // force regexp
...
...
@@ -852,7 +855,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
unexpected();
}
}
};
}
)
;
function labeled_statement(label) {
S.labels.push(label);
...
...
@@ -910,14 +913,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return as("
for
-
in
", init, lhs, obj, in_loop(statement));
};
var function_ = embed_tokens ? function() {
var start = prev();
var ast = $function_.apply(this, arguments);
ast[0] = add_tokens(ast[0], start, prev());
return ast;
} : $function_;
function $function_(in_statement) {
var function_ = maybe_embed_tokens(function(in_statement) {
var name = is("
name
") ? prog1(S.token.value, next) : null;
if (in_statement && !name)
unexpected();
...
...
@@ -945,7 +941,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
S.in_loop = loop;
return a;
})());
};
}
)
;
function if_() {
var cond = parenthesised(), body = statement(), belse;
...
...
@@ -1053,7 +1049,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return
subscripts
(
as
(
"new"
,
newexp
,
args
),
true
);
};
function
expr_atom
(
allow_calls
)
{
var
expr_atom
=
maybe_embed_tokens
(
function
(
allow_calls
)
{
if
(
is
(
"operator"
,
"new"
))
{
next
();
return
new_
();
...
...
@@ -1088,7 +1084,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return
subscripts
(
prog1
(
atom
,
next
),
allow_calls
);
}
unexpected
();
};
}
)
;
function
expr_list
(
closing
,
allow_trailing_comma
,
allow_empty
)
{
var
first
=
true
,
a
=
[];
...
...
@@ -1228,7 +1224,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return
left
;
};
function
express
ion
(
commas
,
no_in
)
{
var
expression
=
maybe_embed_tokens
(
funct
ion
(
commas
,
no_in
)
{
if
(
arguments
.
length
==
0
)
commas
=
true
;
var
expr
=
maybe_assign
(
no_in
);
...
...
@@ -1237,7 +1233,7 @@ function parse($TEXT, exigent_mode, embed_tokens) {
return
as
(
"seq"
,
expr
,
expression
(
true
,
no_in
));
}
return
expr
;
};
}
)
;
function
in_loop
(
cont
)
{
try
{
...
...
build/lib/process.js
View file @
f4b5d3fc
...
...
@@ -75,6 +75,12 @@ function ast_walker(ast) {
return
a
;
})
];
};
function
_block
(
statements
)
{
var
out
=
[
this
[
0
]
];
if
(
statements
!=
null
)
out
.
push
(
MAP
(
statements
,
walk
));
return
out
;
};
var
walkers
=
{
"string"
:
function
(
str
)
{
return
[
this
[
0
],
str
];
...
...
@@ -88,12 +94,8 @@ function ast_walker(ast) {
"toplevel"
:
function
(
statements
)
{
return
[
this
[
0
],
MAP
(
statements
,
walk
)
];
},
"block"
:
function
(
statements
)
{
var
out
=
[
this
[
0
]
];
if
(
statements
!=
null
)
out
.
push
(
MAP
(
statements
,
walk
));
return
out
;
},
"block"
:
_block
,
"splice"
:
_block
,
"var"
:
_vardefs
,
"const"
:
_vardefs
,
"try"
:
function
(
t
,
c
,
f
)
{
...
...
@@ -377,7 +379,9 @@ function ast_add_scope(ast) {
};
function
_lambda
(
name
,
args
,
body
)
{
return
[
this
[
0
],
this
[
0
]
==
"defun"
?
define
(
name
)
:
name
,
args
,
with_new_scope
(
function
(){
var
is_defun
=
this
[
0
]
==
"defun"
;
return
[
this
[
0
],
is_defun
?
define
(
name
)
:
name
,
args
,
with_new_scope
(
function
(){
if
(
!
is_defun
)
define
(
name
);
MAP
(
args
,
define
);
return
MAP
(
body
,
walk
);
})];
...
...
@@ -463,9 +467,22 @@ function ast_mangle(ast, options) {
return
scope
.
get_mangled
(
name
,
newMangle
);
};
function
get_define
(
name
)
{
// we always lookup a defined symbol for the current scope FIRST, so declared
// vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value
if
(
!
scope
.
has
(
name
))
{
if
(
HOP
(
options
.
defines
,
name
))
{
return
options
.
defines
[
name
];
}
}
return
null
;
};
function
_lambda
(
name
,
args
,
body
)
{
if
(
name
)
name
=
get_mangled
(
name
);
var
is_defun
=
this
[
0
]
==
"defun"
;
if
(
is_defun
&&
name
)
name
=
get_mangled
(
name
);
body
=
with_scope
(
body
.
scope
,
function
(){
if
(
!
is_defun
&&
name
)
name
=
get_mangled
(
name
);
args
=
MAP
(
args
,
function
(
name
){
return
get_mangled
(
name
)
});
return
MAP
(
body
,
walk
);
});
...
...
@@ -507,7 +524,7 @@ function ast_mangle(ast, options) {
"var"
:
_vardefs
,
"const"
:
_vardefs
,
"name"
:
function
(
name
)
{
return
[
this
[
0
],
get_mangled
(
name
)
];
return
get_define
(
name
)
||
[
this
[
0
],
get_mangled
(
name
)
];
},
"try"
:
function
(
t
,
c
,
f
)
{
return
[
this
[
0
],
...
...
@@ -583,11 +600,18 @@ function boolean_expr(expr) {
};
function
make_conditional
(
c
,
t
,
e
)
{
var
make_real_conditional
=
function
()
{
if
(
c
[
0
]
==
"unary-prefix"
&&
c
[
1
]
==
"!"
)
{
return
e
?
[
"conditional"
,
c
[
2
],
e
,
t
]
:
[
"binary"
,
"||"
,
c
[
2
],
t
];
return
e
?
[
"conditional"
,
c
[
2
],
e
,
t
]
:
[
"binary"
,
"||"
,
c
[
2
],
t
];
}
else
{
return
e
?
[
"conditional"
,
c
,
t
,
e
]
:
[
"binary"
,
"&&"
,
c
,
t
];
return
e
?
[
"conditional"
,
c
,
t
,
e
]
:
[
"binary"
,
"&&"
,
c
,
t
];
}
};
// shortcut the conditional if the expression has a constant value
return
when_constant
(
c
,
function
(
ast
,
val
){
warn_unreachable
(
val
?
e
:
t
);
return
(
val
?
t
:
e
);
},
make_real_conditional
);
};
function
empty
(
b
)
{
...
...
@@ -676,6 +700,18 @@ var when_constant = (function(){
||
(
boolean_expr
(
expr
[
2
])
&&
boolean_expr
(
expr
[
3
]))))
{
expr
[
1
]
=
expr
[
1
].
substr
(
0
,
2
);
}
else
if
(
no
&&
expr
[
0
]
==
"binary"
&&
(
expr
[
1
]
==
"||"
||
expr
[
1
]
==
"&&"
))
{
// the whole expression is not constant but the lval may be...
try
{
var
lval
=
evaluate
(
expr
[
2
]);
expr
=
((
expr
[
1
]
==
"&&"
&&
(
lval
?
expr
[
3
]
:
lval
))
||
(
expr
[
1
]
==
"||"
&&
(
lval
?
lval
:
expr
[
3
]))
||
expr
);
}
catch
(
ex2
)
{
// IGNORE... lval is not constant
}
}
return
no
?
no
.
call
(
expr
,
expr
)
:
null
;
}
else
throw
ex
;
...
...
@@ -751,9 +787,14 @@ function ast_squeeze(ast, options) {
};
function
_lambda
(
name
,
args
,
body
)
{
return
[
this
[
0
],
name
,
args
,
with_scope
(
body
.
scope
,
function
(){
return
tighten
(
MAP
(
body
,
walk
),
"lambda"
);
})
];
var
is_defun
=
this
[
0
]
==
"defun"
;
body
=
with_scope
(
body
.
scope
,
function
(){
var
ret
=
tighten
(
MAP
(
body
,
walk
),
"lambda"
);
if
(
!
is_defun
&&
name
&&
!
HOP
(
scope
.
refs
,
name
))
name
=
null
;
return
ret
;
});
return
[
this
[
0
],
name
,
args
,
body
];
};
// we get here for blocks that have been already transformed.
...
...
@@ -959,13 +1000,7 @@ function ast_squeeze(ast, options) {
return
[
branch
[
0
]
?
walk
(
branch
[
0
])
:
null
,
block
];
})
];
},
"function"
:
function
()
{
var
ret
=
_lambda
.
apply
(
this
,
arguments
);
if
(
ret
[
1
]
&&
!
HOP
(
scope
.
refs
,
ret
[
1
]))
{
ret
[
1
]
=
null
;
}
return
ret
;
},
"function"
:
_lambda
,
"defun"
:
_lambda
,
"block"
:
function
(
body
)
{
if
(
body
)
return
rmblock
([
"block"
,
tighten
(
MAP
(
body
,
walk
))
]);
...
...
@@ -1067,6 +1102,8 @@ function to_ascii(str) {
});
};
var SPLICE_NEEDS_BRACKETS = jsp.array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]);
function gen_code(ast, options) {
options = defaults(options, {
indent_start : 0,
...
...
@@ -1197,6 +1234,19 @@ function gen_code(ast, options) {
return
make_block_statements
(
statements
)
.
join
(
newline
+
newline
);
},
"splice"
:
function
(
statements
)
{
var
parent
=
$stack
[
$stack
.
length
-
2
][
0
];
if
(
HOP
(
SPLICE_NEEDS_BRACKETS
,
parent
))
{
// we need block brackets in this case
return
make_block
.
apply
(
this
,
arguments
);
}
else
{
return
MAP
(
make_block_statements
(
statements
,
true
),
function
(
line
,
i
)
{
// the first line is already indented
return
i
>
0
?
indent
(
line
)
:
line
;
}).
join
(
newline
);
}
},
"block"
:
make_block
,
"var"
:
function
(
defs
)
{
return
"var "
+
add_commas
(
MAP
(
defs
,
make_1vardef
))
+
";"
;
...
...
@@ -1437,7 +1487,7 @@ function gen_code(ast, options) {
return
add_spaces
([
out
,
make_block
(
body
)
]);
};
function
make_block_statements
(
statements
)
{
function
make_block_statements
(
statements
,
noindent
)
{
for
(
var
a
=
[],
last
=
statements
.
length
-
1
,
i
=
0
;
i
<=
last
;
++
i
)
{
var
stat
=
statements
[
i
];
var
code
=
make
(
stat
);
...
...
@@ -1455,7 +1505,7 @@ function gen_code(ast, options) {
a
.
push
(
code
);
}
}
return
MAP
(
a
,
indent
);
return
noindent
?
a
:
MAP
(
a
,
indent
);
};
function
make_switch_block
(
body
)
{
...
...
build/uglify.js
View file @
f4b5d3fc
#! /usr/bin/env node
// -*- js
2
-*-
// -*- js -*-
global
.
sys
=
require
(
/^v0
\.[
012
]
/
.
test
(
process
.
version
)
?
"sys"
:
"util"
);
var
fs
=
require
(
"fs"
),
jsp
=
require
(
"./lib/parse-js"
),
pro
=
require
(
"./lib/process"
);
pro
.
set_logger
(
function
(
msg
){
sys
.
debug
(
msg
);
});
var
fs
=
require
(
"fs"
);
var
jsp
=
require
(
"./lib/parse-js"
),
pro
=
require
(
"./lib/process"
);
var
options
=
{
ast
:
false
,
...
...
@@ -17,13 +13,16 @@ var options = {
squeeze
:
true
,
make_seqs
:
true
,
dead_code
:
true
,
beautify
:
false
,
verbose
:
false
,
show_copyright
:
true
,
out_same_file
:
false
,
extra
:
false
,
unsafe
:
false
,
// XXX: extra & unsafe? but maybe we don't want both, so....
beautify_options
:
{
max_line_length
:
32
*
1024
,
unsafe
:
false
,
reserved_names
:
null
,
defines
:
{
},
codegen_options
:
{
ascii_only
:
false
,
beautify
:
false
,
indent_level
:
4
,
indent_start
:
0
,
quote_keys
:
false
,
...
...
@@ -40,15 +39,15 @@ out: while (args.length > 0) {
switch
(
v
)
{
case
"-b"
:
case
"--beautify"
:
options
.
beautify
=
true
;
options
.
codegen_options
.
beautify
=
true
;
break
;
case
"-i"
:
case
"--indent"
:
options
.
beautify
_options
.
indent_level
=
args
.
shift
();
options
.
codegen
_options
.
indent_level
=
args
.
shift
();
break
;
case
"-q"
:
case
"--quote-keys"
:
options
.
beautify
_options
.
quote_keys
=
true
;
options
.
codegen
_options
.
quote_keys
=
true
;
break
;
case
"-mt"
:
case
"--mangle-toplevel"
:
...
...
@@ -86,23 +85,109 @@ out: while (args.length > 0) {
case
"--ast"
:
options
.
ast
=
true
;
break
;
case
"--extra"
:
options
.
extra
=
true
;
break
;
case
"--unsafe"
:
options
.
unsafe
=
true
;
break
;
case
"--max-line-len"
:
options
.
max_line_length
=
parseInt
(
args
.
shift
(),
10
);
break
;
case
"--reserved-names"
:
options
.
reserved_names
=
args
.
shift
().
split
(
","
);
break
;
case
"-d"
:
case
"--define"
:
var
defarg
=
args
.
shift
();
try
{
var
defsym
=
function
(
sym
)
{
// KEYWORDS_ATOM doesn't include NaN or Infinity - should we check
// for them too ?? We don't check reserved words and the like as the
// define values are only substituted AFTER parsing
if
(
jsp
.
KEYWORDS_ATOM
.
hasOwnProperty
(
sym
))
{
throw
"Don't define values for inbuilt constant '"
+
sym
+
"'"
;
}
return
sym
;
},
defval
=
function
(
v
)
{
if
(
v
.
match
(
/^"
(
.*
)
"$/
)
||
v
.
match
(
/^'
(
.*
)
'$/
))
{
return
[
"string"
,
RegExp
.
$1
];
}
else
if
(
!
isNaN
(
parseFloat
(
v
)))
{
return
[
"num"
,
parseFloat
(
v
)
];
}
else
if
(
v
.
match
(
/^
[
a-z
\$
_
][
a-z
\$
_0-9
]
*$/i
))
{
return
[
"name"
,
v
];
}
else
if
(
!
v
.
match
(
/"/
))
{
return
[
"string"
,
v
];
}
else
if
(
!
v
.
match
(
/'/
))
{
return
[
"string"
,
v
];
}
throw
"Can't understand the specified value: "
+
v
;
};
if
(
defarg
.
match
(
/^
([
a-z_
\$][
a-z_
\$
0-9
]
*
)(
=
(
.*
))?
$/i
))
{
var
sym
=
defsym
(
RegExp
.
$1
),
val
=
RegExp
.
$2
?
defval
(
RegExp
.
$2
.
substr
(
1
))
:
[
'name'
,
'true'
];
options
.
defines
[
sym
]
=
val
;
}
else
{
throw
"The --define option expects SYMBOL[=value]"
;
}
}
catch
(
ex
)
{
sys
.
print
(
"ERROR: In option --define "
+
defarg
+
"
\n
"
+
ex
+
"
\n
"
);
process
.
exit
(
1
);
}
break
;
case
"--define-from-module"
:
var
defmodarg
=
args
.
shift
(),
defmodule
=
require
(
defmodarg
),
sym
,
val
;
for
(
sym
in
defmodule
)
{
if
(
defmodule
.
hasOwnProperty
(
sym
))
{
options
.
defines
[
sym
]
=
function
(
val
)
{
if
(
typeof
val
==
"string"
)
return
[
"string"
,
val
];
if
(
typeof
val
==
"number"
)
return
[
"num"
,
val
];
if
(
val
===
true
)
return
[
'name'
,
'true'
];
if
(
val
===
false
)
return
[
'name'
,
'false'
];
if
(
val
===
null
)
return
[
'name'
,
'null'
];
if
(
val
===
undefined
)
return
[
'name'
,
'undefined'
];
sys
.
print
(
"ERROR: In option --define-from-module "
+
defmodarg
+
"
\n
"
);
sys
.
print
(
"ERROR: Unknown object type for: "
+
sym
+
"="
+
val
+
"
\n
"
);
process
.
exit
(
1
);
return
null
;
}(
defmodule
[
sym
]);
}
}
break
;
case
"--ascii"
:
options
.
codegen_options
.
ascii_only
=
true
;
break
;
default
:
filename
=
v
;
break
out
;
}
}
if
(
options
.
verbose
)
{
pro
.
set_logger
(
function
(
msg
){
sys
.
debug
(
msg
);
});
}
jsp
.
set_logger
(
function
(
msg
){
sys
.
debug
(
msg
);
});
if
(
filename
)
{
fs
.
readFile
(
filename
,
"utf8"
,
function
(
err
,
text
){
if
(
err
)
{
throw
err
;
}
if
(
err
)
throw
err
;
output
(
squeeze_it
(
text
));
});
}
else
{
...
...
@@ -131,7 +216,9 @@ function output(text) {
});
}
out
.
write
(
text
);
out
.
end
();
if
(
options
.
output
!==
true
)
{
out
.
end
();
}
};
// --------- main ends here.
...
...
@@ -152,36 +239,35 @@ function show_copyright(comments) {
function
squeeze_it
(
code
)
{
var
result
=
""
;
if
(
options
.
show_copyright
)
{
var
initial_comments
=
[];
// keep first comment
var
tok
=
jsp
.
tokenizer
(
code
,
false
),
c
;
var
tok
=
jsp
.
tokenizer
(
code
),
c
;
c
=
tok
();
var
prev
=
null
;
while
(
/^comment/
.
test
(
c
.
type
)
&&
(
!
prev
||
prev
==
c
.
type
))
{
initial_comments
.
push
(
c
);
prev
=
c
.
type
;
c
=
tok
();
}
result
+=
show_copyright
(
initial_comments
);
result
+=
show_copyright
(
c
.
comments_before
);
}
try
{
var
ast
=
time_it
(
"parse"
,
function
(){
return
jsp
.
parse
(
code
);
});
if
(
options
.
mangle
)
ast
=
time_it
(
"mangle"
,
function
(){
return
pro
.
ast_mangle
(
ast
,
options
.
mangle_toplevel
);
});
if
(
options
.
squeeze
)
ast
=
time_it
(
"squeeze"
,
function
(){
ast
=
pro
.
ast_squeeze
(
ast
,
{
make_seqs
:
options
.
make_seqs
,
dead_code
:
options
.
dead_code
,
extra
:
options
.
extra
});
if
(
options
.
unsafe
)
ast
=
pro
.
ast_squeeze_more
(
ast
);
return
ast
;
if
(
options
.
mangle
)
ast
=
time_it
(
"mangle"
,
function
(){
return
pro
.
ast_mangle
(
ast
,
{
toplevel
:
options
.
mangle_toplevel
,
defines
:
options
.
defines
,
except
:
options
.
reserved_names
});
});
if
(
options
.
squeeze
)
ast
=
time_it
(
"squeeze"
,
function
(){
ast
=
pro
.
ast_squeeze
(
ast
,
{
make_seqs
:
options
.
make_seqs
,
dead_code
:
options
.
dead_code
,
keep_comps
:
!
options
.
unsafe
});
if
(
options
.
unsafe
)
ast
=
pro
.
ast_squeeze_more
(
ast
);
return
ast
;
});
if
(
options
.
ast
)
return
sys
.
inspect
(
ast
,
null
,
null
);
result
+=
time_it
(
"generate"
,
function
(){
return
pro
.
gen_code
(
ast
,
options
.
beautify
&&
options
.
beautify_options
)
});
result
+=
time_it
(
"generate"
,
function
(){
return
pro
.
gen_code
(
ast
,
options
.
codegen_options
)
});
if
(
!
options
.
codegen_options
.
beautify
&&
options
.
max_line_length
)
{
result
=
time_it
(
"split"
,
function
(){
return
pro
.
split_lines
(
result
,
options
.
max_line_length
)
});
}
return
result
;
}
catch
(
ex
)
{
sys
.
debug
(
ex
.
stack
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment