uglifier 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of uglifier might be problematic. Click here for more details.
- data/Gemfile +2 -2
- data/Rakefile +3 -9
- data/VERSION +1 -1
- data/lib/uglifier.rb +5 -14
- data/lib/uglifier/cli.rb +0 -4
- data/spec/uglifier_spec.rb +4 -4
- data/uglifier.gemspec +10 -26
- data/vendor/uglifyjs/lib/parse-js.js +185 -99
- data/vendor/uglifyjs/lib/process.js +335 -301
- metadata +20 -99
data/Gemfile
CHANGED
@@ -3,12 +3,12 @@ source "http://rubygems.org"
|
|
3
3
|
# Example:
|
4
4
|
# gem "activesupport", ">= 2.3.5"
|
5
5
|
|
6
|
-
gem "therubyracer", "
|
6
|
+
gem "therubyracer", "~> 0.8.0"
|
7
7
|
|
8
8
|
# Add dependencies to develop your gem here.
|
9
9
|
# Include everything needed to run rake, tests, features, etc.
|
10
10
|
group :development do
|
11
|
-
gem "rspec", "~> 2.
|
11
|
+
gem "rspec", "~> 2.5.0"
|
12
12
|
gem "bundler", "~> 1.0.0"
|
13
13
|
gem "jeweler", "~> 1.5.0"
|
14
14
|
gem "rcov", ">= 0"
|
data/Rakefile
CHANGED
@@ -17,15 +17,9 @@ Jeweler::Tasks.new do |gem|
|
|
17
17
|
gem.email = "lautis@gmail.com"
|
18
18
|
gem.homepage = "http://github.com/lautis/uglifier"
|
19
19
|
gem.authors = ["Ville Lautanala"]
|
20
|
-
|
21
|
-
#
|
22
|
-
|
23
|
-
# spec.add_development_dependency 'rspec', '> 1.2.3'
|
24
|
-
gem.add_development_dependency "therubyracer", ">=0.7.5"
|
25
|
-
gem.add_development_dependency "rspec", "~> 2.0.0"
|
26
|
-
gem.add_development_dependency "bundler", "~> 1.0.0"
|
27
|
-
gem.add_development_dependency "jeweler", "~> 1.5.0.pre5"
|
28
|
-
gem.add_development_dependency "rcov", ">= 0"
|
20
|
+
|
21
|
+
# Dependencies defined in Gemfile
|
22
|
+
|
29
23
|
gem.files.include 'vendor/uglifyjs/lib/*'
|
30
24
|
end
|
31
25
|
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/lib/uglifier.rb
CHANGED
@@ -10,7 +10,6 @@ class Uglifier
|
|
10
10
|
:squeeze => true, # Squeeze code resulting in smaller, but less-readable code
|
11
11
|
:seqs => true, # Reduce consecutive statements in blocks into single statement
|
12
12
|
:dead_code => true, # Remove dead code (e.g. after return)
|
13
|
-
:extra => false, # Additional and potentially unsafe optimizations
|
14
13
|
:unsafe => false, # Optimizations known to be unsafe in some situations
|
15
14
|
:copyright => true, # Show copyright message
|
16
15
|
:beautify => false, # Ouput indented code
|
@@ -59,22 +58,14 @@ class Uglifier
|
|
59
58
|
end
|
60
59
|
|
61
60
|
def copyright(source)
|
62
|
-
comments = []
|
63
|
-
|
64
61
|
tokens = @tokenizer.call(source, false)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
while (comment["type"].match(/^comment/) && (!prev || prev == comment["type"]))
|
69
|
-
comments << if comment["type"] == "comment1"
|
70
|
-
"//#{comment["value"]}\n"
|
62
|
+
tokens.call.comments_before.inject("") do |copyright, comment|
|
63
|
+
copyright + if comment["type"] == "comment1"
|
64
|
+
"//" + comment["value"] + "\n"
|
71
65
|
else
|
72
|
-
"
|
66
|
+
"/*" + comment["value"] + "*/\n"
|
73
67
|
end
|
74
|
-
prev = comment["type"]
|
75
|
-
comment = tokens.call
|
76
68
|
end
|
77
|
-
comments.join
|
78
69
|
end
|
79
70
|
|
80
71
|
def generate_code(ast)
|
@@ -96,7 +87,7 @@ class Uglifier
|
|
96
87
|
@node["ast_squeeze"].call(ast, {
|
97
88
|
"make_seqs" => @options[:seqs],
|
98
89
|
"dead_code" => @options[:dead_code],
|
99
|
-
"
|
90
|
+
"keep_comps" => !@options[:unsafe]
|
100
91
|
})
|
101
92
|
end
|
102
93
|
|
data/lib/uglifier/cli.rb
CHANGED
@@ -27,10 +27,6 @@ class Uglifier
|
|
27
27
|
options[:dead_code] = d
|
28
28
|
end
|
29
29
|
|
30
|
-
opts.on("-x", "--extra-optimizations", "Additional and potentially unsafe optimizations") do |x|
|
31
|
-
options[:extra] = x
|
32
|
-
end
|
33
|
-
|
34
30
|
opts.on("-u", "--unsafe-optimizations", "Optimizations known to be unsafe in some situations") do |d|
|
35
31
|
options[:unsafe] = d
|
36
32
|
end
|
data/spec/uglifier_spec.rb
CHANGED
@@ -31,7 +31,7 @@ describe "Uglifier" do
|
|
31
31
|
@source = <<-EOS
|
32
32
|
/* Copyright Notice */
|
33
33
|
/* (c) 2011 */
|
34
|
-
//
|
34
|
+
// INCLUDED
|
35
35
|
function identity(p) { return p; }
|
36
36
|
EOS
|
37
37
|
@minified = Uglifier.compile(@source, :copyright => true)
|
@@ -45,12 +45,12 @@ describe "Uglifier" do
|
|
45
45
|
@minified.should match /\(c\) 2011/
|
46
46
|
end
|
47
47
|
|
48
|
-
it "
|
49
|
-
@minified.
|
48
|
+
it "does include different comment types" do
|
49
|
+
@minified.should match /INCLUDED/
|
50
50
|
end
|
51
51
|
|
52
52
|
it "puts comments on own lines" do
|
53
|
-
@minified.split("\n").should have(
|
53
|
+
@minified.split("\n").should have(4).items
|
54
54
|
end
|
55
55
|
|
56
56
|
it "omits copyright notification if copyright parameter is set to false" do
|
data/uglifier.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{uglifier}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ville Lautanala"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-02-26}
|
13
13
|
s.default_executable = %q{uglify}
|
14
14
|
s.email = %q{lautis@gmail.com}
|
15
15
|
s.executables = ["uglify"]
|
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
|
|
39
39
|
]
|
40
40
|
s.homepage = %q{http://github.com/lautis/uglifier}
|
41
41
|
s.require_paths = ["lib"]
|
42
|
-
s.rubygems_version = %q{1.
|
42
|
+
s.rubygems_version = %q{1.5.0}
|
43
43
|
s.summary = %q{Ruby wrapper for UglifyJS JavaScript compressor}
|
44
44
|
s.test_files = [
|
45
45
|
"spec/spec_helper.rb",
|
@@ -47,43 +47,27 @@ Gem::Specification.new do |s|
|
|
47
47
|
]
|
48
48
|
|
49
49
|
if s.respond_to? :specification_version then
|
50
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
51
50
|
s.specification_version = 3
|
52
51
|
|
53
52
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
54
|
-
s.add_runtime_dependency(%q<therubyracer>, ["
|
55
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.
|
53
|
+
s.add_runtime_dependency(%q<therubyracer>, ["~> 0.8.0"])
|
54
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.5.0"])
|
56
55
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
56
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.0"])
|
58
57
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
59
|
-
s.add_development_dependency(%q<therubyracer>, [">= 0.7.5"])
|
60
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.0.0"])
|
61
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
62
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.5.0.pre5"])
|
63
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
64
58
|
else
|
65
|
-
s.add_dependency(%q<therubyracer>, ["
|
66
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
59
|
+
s.add_dependency(%q<therubyracer>, ["~> 0.8.0"])
|
60
|
+
s.add_dependency(%q<rspec>, ["~> 2.5.0"])
|
67
61
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
68
62
|
s.add_dependency(%q<jeweler>, ["~> 1.5.0"])
|
69
63
|
s.add_dependency(%q<rcov>, [">= 0"])
|
70
|
-
s.add_dependency(%q<therubyracer>, [">= 0.7.5"])
|
71
|
-
s.add_dependency(%q<rspec>, ["~> 2.0.0"])
|
72
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
73
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.0.pre5"])
|
74
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
75
64
|
end
|
76
65
|
else
|
77
|
-
s.add_dependency(%q<therubyracer>, ["
|
78
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
66
|
+
s.add_dependency(%q<therubyracer>, ["~> 0.8.0"])
|
67
|
+
s.add_dependency(%q<rspec>, ["~> 2.5.0"])
|
79
68
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
80
69
|
s.add_dependency(%q<jeweler>, ["~> 1.5.0"])
|
81
70
|
s.add_dependency(%q<rcov>, [">= 0"])
|
82
|
-
s.add_dependency(%q<therubyracer>, [">= 0.7.5"])
|
83
|
-
s.add_dependency(%q<rspec>, ["~> 2.0.0"])
|
84
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
85
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.0.pre5"])
|
86
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
87
71
|
end
|
88
72
|
end
|
89
73
|
|
@@ -182,7 +182,6 @@ var OPERATORS = array_to_hash([
|
|
182
182
|
">>=",
|
183
183
|
"<<=",
|
184
184
|
">>>=",
|
185
|
-
"~=",
|
186
185
|
"%=",
|
187
186
|
"|=",
|
188
187
|
"^=",
|
@@ -191,7 +190,7 @@ var OPERATORS = array_to_hash([
|
|
191
190
|
"||"
|
192
191
|
]);
|
193
192
|
|
194
|
-
var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t"));
|
193
|
+
var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t\u200b"));
|
195
194
|
|
196
195
|
var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
|
197
196
|
|
@@ -201,20 +200,47 @@ var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
|
|
201
200
|
|
202
201
|
/* -----[ Tokenizer ]----- */
|
203
202
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
203
|
+
// regexps adapted from http://xregexp.com/plugins/#unicode
|
204
|
+
var UNICODE = {
|
205
|
+
letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),
|
206
|
+
non_spacing_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"),
|
207
|
+
space_combining_mark: new RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"),
|
208
|
+
connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]")
|
209
209
|
};
|
210
210
|
|
211
|
-
function
|
212
|
-
return
|
211
|
+
function is_letter(ch) {
|
212
|
+
return UNICODE.letter.test(ch);
|
213
213
|
};
|
214
214
|
|
215
215
|
function is_digit(ch) {
|
216
216
|
ch = ch.charCodeAt(0);
|
217
|
-
return ch >= 48 && ch <= 57;
|
217
|
+
return ch >= 48 && ch <= 57; //XXX: find out if "UnicodeDigit" means something else than 0..9
|
218
|
+
};
|
219
|
+
|
220
|
+
function is_alphanumeric_char(ch) {
|
221
|
+
return is_digit(ch) || is_letter(ch);
|
222
|
+
};
|
223
|
+
|
224
|
+
function is_unicode_combining_mark(ch) {
|
225
|
+
return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
|
226
|
+
};
|
227
|
+
|
228
|
+
function is_unicode_connector_punctuation(ch) {
|
229
|
+
return UNICODE.connector_punctuation.test(ch);
|
230
|
+
};
|
231
|
+
|
232
|
+
function is_identifier_start(ch) {
|
233
|
+
return ch == "$" || ch == "_" || is_letter(ch);
|
234
|
+
};
|
235
|
+
|
236
|
+
function is_identifier_char(ch) {
|
237
|
+
return is_identifier_start(ch)
|
238
|
+
|| is_unicode_combining_mark(ch)
|
239
|
+
|| is_digit(ch)
|
240
|
+
|| is_unicode_connector_punctuation(ch)
|
241
|
+
|| ch == "\u200c" // zero-width non-joiner <ZWNJ>
|
242
|
+
|| ch == "\u200d" // zero-width joiner <ZWJ> (in my ECMA-262 PDF, this is also 200c)
|
243
|
+
;
|
218
244
|
};
|
219
245
|
|
220
246
|
function parse_js_number(num) {
|
@@ -253,18 +279,19 @@ function is_token(token, type, val) {
|
|
253
279
|
|
254
280
|
var EX_EOF = {};
|
255
281
|
|
256
|
-
function tokenizer($TEXT
|
282
|
+
function tokenizer($TEXT) {
|
257
283
|
|
258
284
|
var S = {
|
259
|
-
text
|
260
|
-
pos
|
261
|
-
tokpos
|
262
|
-
line
|
263
|
-
tokline
|
264
|
-
col
|
265
|
-
tokcol
|
266
|
-
newline_before
|
267
|
-
regex_allowed
|
285
|
+
text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
|
286
|
+
pos : 0,
|
287
|
+
tokpos : 0,
|
288
|
+
line : 0,
|
289
|
+
tokline : 0,
|
290
|
+
col : 0,
|
291
|
+
tokcol : 0,
|
292
|
+
newline_before : false,
|
293
|
+
regex_allowed : false,
|
294
|
+
comments_before : []
|
268
295
|
};
|
269
296
|
|
270
297
|
function peek() { return S.text.charAt(S.pos); };
|
@@ -299,7 +326,7 @@ function tokenizer($TEXT, skip_comments) {
|
|
299
326
|
S.tokpos = S.pos;
|
300
327
|
};
|
301
328
|
|
302
|
-
function token(type, value) {
|
329
|
+
function token(type, value, is_comment) {
|
303
330
|
S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
|
304
331
|
(type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
|
305
332
|
(type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
|
@@ -311,6 +338,10 @@ function tokenizer($TEXT, skip_comments) {
|
|
311
338
|
pos : S.tokpos,
|
312
339
|
nlb : S.newline_before
|
313
340
|
};
|
341
|
+
if (!is_comment) {
|
342
|
+
ret.comments_before = S.comments_before;
|
343
|
+
S.comments_before = [];
|
344
|
+
}
|
314
345
|
S.newline_before = false;
|
315
346
|
return ret;
|
316
347
|
};
|
@@ -334,7 +365,7 @@ function tokenizer($TEXT, skip_comments) {
|
|
334
365
|
};
|
335
366
|
|
336
367
|
function read_num(prefix) {
|
337
|
-
var has_e = false, after_e = false, has_x = false;
|
368
|
+
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
|
338
369
|
var num = read_while(function(ch, i){
|
339
370
|
if (ch == "x" || ch == "X") {
|
340
371
|
if (has_x) return false;
|
@@ -350,7 +381,12 @@ function tokenizer($TEXT, skip_comments) {
|
|
350
381
|
}
|
351
382
|
if (ch == "+") return after_e;
|
352
383
|
after_e = false;
|
353
|
-
|
384
|
+
if (ch == ".") {
|
385
|
+
if (!has_dot)
|
386
|
+
return has_dot = true;
|
387
|
+
return false;
|
388
|
+
}
|
389
|
+
return is_alphanumeric_char(ch);
|
354
390
|
});
|
355
391
|
if (prefix)
|
356
392
|
num = prefix + num;
|
@@ -412,7 +448,7 @@ function tokenizer($TEXT, skip_comments) {
|
|
412
448
|
ret = S.text.substring(S.pos, i);
|
413
449
|
S.pos = i;
|
414
450
|
}
|
415
|
-
return token("comment1", ret);
|
451
|
+
return token("comment1", ret, true);
|
416
452
|
};
|
417
453
|
|
418
454
|
function read_multiline_comment() {
|
@@ -420,14 +456,41 @@ function tokenizer($TEXT, skip_comments) {
|
|
420
456
|
return with_eof_error("Unterminated multiline comment", function(){
|
421
457
|
var i = find("*/", true),
|
422
458
|
text = S.text.substring(S.pos, i),
|
423
|
-
tok = token("comment2", text);
|
459
|
+
tok = token("comment2", text, true);
|
424
460
|
S.pos = i + 2;
|
425
461
|
S.line += text.split("\n").length - 1;
|
426
462
|
S.newline_before = text.indexOf("\n") >= 0;
|
463
|
+
|
464
|
+
// https://github.com/mishoo/UglifyJS/issues/#issue/100
|
465
|
+
if (/^@cc_on/i.test(text)) {
|
466
|
+
warn("WARNING: at line " + S.line);
|
467
|
+
warn("*** Found \"conditional comment\": " + text);
|
468
|
+
warn("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer.");
|
469
|
+
}
|
470
|
+
|
427
471
|
return tok;
|
428
472
|
});
|
429
473
|
};
|
430
474
|
|
475
|
+
function read_name() {
|
476
|
+
var backslash = false, name = "", ch;
|
477
|
+
while ((ch = peek()) != null) {
|
478
|
+
if (!backslash) {
|
479
|
+
if (ch == "\\") backslash = true, next();
|
480
|
+
else if (is_identifier_char(ch)) name += next();
|
481
|
+
else break;
|
482
|
+
}
|
483
|
+
else {
|
484
|
+
if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX");
|
485
|
+
ch = read_escaped_char();
|
486
|
+
if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
|
487
|
+
name += ch;
|
488
|
+
backslash = false;
|
489
|
+
}
|
490
|
+
}
|
491
|
+
return name;
|
492
|
+
};
|
493
|
+
|
431
494
|
function read_regexp() {
|
432
495
|
return with_eof_error("Unterminated regular expression", function(){
|
433
496
|
var prev_backslash = false, regexp = "", ch, in_class = false;
|
@@ -447,15 +510,14 @@ function tokenizer($TEXT, skip_comments) {
|
|
447
510
|
} else {
|
448
511
|
regexp += ch;
|
449
512
|
}
|
450
|
-
var mods =
|
451
|
-
return HOP(REGEXP_MODIFIERS, ch);
|
452
|
-
});
|
513
|
+
var mods = read_name();
|
453
514
|
return token("regexp", [ regexp, mods ]);
|
454
515
|
});
|
455
516
|
};
|
456
517
|
|
457
518
|
function read_operator(prefix) {
|
458
519
|
function grow(op) {
|
520
|
+
if (!peek()) return op;
|
459
521
|
var bigger = op + peek();
|
460
522
|
if (HOP(OPERATORS, bigger)) {
|
461
523
|
next();
|
@@ -467,19 +529,18 @@ function tokenizer($TEXT, skip_comments) {
|
|
467
529
|
return token("operator", grow(prefix || next()));
|
468
530
|
};
|
469
531
|
|
470
|
-
|
532
|
+
function handle_slash() {
|
471
533
|
next();
|
472
534
|
var regex_allowed = S.regex_allowed;
|
473
535
|
switch (peek()) {
|
474
|
-
case "/":
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
case "*": return read_multiline_comment();
|
536
|
+
case "/":
|
537
|
+
S.comments_before.push(read_line_comment());
|
538
|
+
S.regex_allowed = regex_allowed;
|
539
|
+
return next_token();
|
540
|
+
case "*":
|
541
|
+
S.comments_before.push(read_multiline_comment());
|
542
|
+
S.regex_allowed = regex_allowed;
|
543
|
+
return next_token();
|
483
544
|
}
|
484
545
|
return S.regex_allowed ? read_regexp() : read_operator("/");
|
485
546
|
};
|
@@ -492,7 +553,7 @@ function tokenizer($TEXT, skip_comments) {
|
|
492
553
|
};
|
493
554
|
|
494
555
|
function read_word() {
|
495
|
-
var word =
|
556
|
+
var word = read_name();
|
496
557
|
return !HOP(KEYWORDS, word)
|
497
558
|
? token("name", word)
|
498
559
|
: HOP(OPERATORS, word)
|
@@ -524,7 +585,7 @@ function tokenizer($TEXT, skip_comments) {
|
|
524
585
|
if (ch == ".") return handle_dot();
|
525
586
|
if (ch == "/") return handle_slash();
|
526
587
|
if (HOP(OPERATOR_CHARS, ch)) return read_operator();
|
527
|
-
if (
|
588
|
+
if (ch == "\\" || is_identifier_start(ch)) return read_word();
|
528
589
|
parse_error("Unexpected character '" + ch + "'");
|
529
590
|
};
|
530
591
|
|
@@ -560,7 +621,7 @@ var ASSIGNMENT = (function(a, ret, i){
|
|
560
621
|
}
|
561
622
|
return ret;
|
562
623
|
})(
|
563
|
-
["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "
|
624
|
+
["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="],
|
564
625
|
{ "=": true },
|
565
626
|
0
|
566
627
|
);
|
@@ -603,16 +664,16 @@ function NodeWithToken(str, start, end) {
|
|
603
664
|
|
604
665
|
NodeWithToken.prototype.toString = function() { return this.name; };
|
605
666
|
|
606
|
-
function parse($TEXT,
|
667
|
+
function parse($TEXT, exigent_mode, embed_tokens) {
|
607
668
|
|
608
669
|
var S = {
|
609
|
-
input: tokenizer($TEXT, true),
|
610
|
-
token: null,
|
611
|
-
prev: null,
|
612
|
-
peeked: null,
|
613
|
-
in_function: 0,
|
614
|
-
in_loop: 0,
|
615
|
-
labels: []
|
670
|
+
input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT,
|
671
|
+
token : null,
|
672
|
+
prev : null,
|
673
|
+
peeked : null,
|
674
|
+
in_function : 0,
|
675
|
+
in_loop : 0,
|
676
|
+
labels : []
|
616
677
|
};
|
617
678
|
|
618
679
|
S.token = next();
|
@@ -666,7 +727,7 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
666
727
|
function expect(punc) { return expect_token("punc", punc); };
|
667
728
|
|
668
729
|
function can_insert_semicolon() {
|
669
|
-
return !
|
730
|
+
return !exigent_mode && (
|
670
731
|
S.token.nlb || is("eof") || is("punc", "}")
|
671
732
|
);
|
672
733
|
};
|
@@ -688,14 +749,14 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
688
749
|
};
|
689
750
|
|
690
751
|
function add_tokens(str, start, end) {
|
691
|
-
return new NodeWithToken(str, start, end);
|
752
|
+
return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
|
692
753
|
};
|
693
754
|
|
694
755
|
var statement = embed_tokens ? function() {
|
695
756
|
var start = S.token;
|
696
|
-
var
|
697
|
-
|
698
|
-
return
|
757
|
+
var ast = $statement.apply(this, arguments);
|
758
|
+
ast[0] = add_tokens(ast[0], start, prev());
|
759
|
+
return ast;
|
699
760
|
} : $statement;
|
700
761
|
|
701
762
|
function $statement() {
|
@@ -797,7 +858,7 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
797
858
|
function labeled_statement(label) {
|
798
859
|
S.labels.push(label);
|
799
860
|
var start = S.token, stat = statement();
|
800
|
-
if (
|
861
|
+
if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
|
801
862
|
unexpected(start);
|
802
863
|
S.labels.pop();
|
803
864
|
return as("label", label, stat);
|
@@ -822,29 +883,42 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
822
883
|
|
823
884
|
function for_() {
|
824
885
|
expect("(");
|
825
|
-
var
|
826
|
-
if (
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
var obj = expression();
|
833
|
-
expect(")");
|
834
|
-
return as("for-in", has_var, name, obj, in_loop(statement));
|
835
|
-
} else {
|
836
|
-
// classic for
|
837
|
-
var init = is("punc", ";") ? null : has_var ? var_() : expression();
|
838
|
-
expect(";");
|
839
|
-
var test = is("punc", ";") ? null : expression();
|
840
|
-
expect(";");
|
841
|
-
var step = is("punc", ")") ? null : expression();
|
842
|
-
expect(")");
|
843
|
-
return as("for", init, test, step, in_loop(statement));
|
886
|
+
var init = null;
|
887
|
+
if (!is("punc", ";")) {
|
888
|
+
init = is("keyword", "var")
|
889
|
+
? (next(), var_(true))
|
890
|
+
: expression(true, true);
|
891
|
+
if (is("operator", "in"))
|
892
|
+
return for_in(init);
|
844
893
|
}
|
894
|
+
return regular_for(init);
|
845
895
|
};
|
846
896
|
|
847
|
-
function
|
897
|
+
function regular_for(init) {
|
898
|
+
expect(";");
|
899
|
+
var test = is("punc", ";") ? null : expression();
|
900
|
+
expect(";");
|
901
|
+
var step = is("punc", ")") ? null : expression();
|
902
|
+
expect(")");
|
903
|
+
return as("for", init, test, step, in_loop(statement));
|
904
|
+
};
|
905
|
+
|
906
|
+
function for_in(init) {
|
907
|
+
var lhs = init[0] == "var" ? as("name", init[1][0]) : init;
|
908
|
+
next();
|
909
|
+
var obj = expression();
|
910
|
+
expect(")");
|
911
|
+
return as("for-in", init, lhs, obj, in_loop(statement));
|
912
|
+
};
|
913
|
+
|
914
|
+
var function_ = embed_tokens ? function() {
|
915
|
+
var start = prev();
|
916
|
+
var ast = $function_.apply(this, arguments);
|
917
|
+
ast[0] = add_tokens(ast[0], start, prev());
|
918
|
+
return ast;
|
919
|
+
} : $function_;
|
920
|
+
|
921
|
+
function $function_(in_statement) {
|
848
922
|
var name = is("name") ? prog1(S.token.value, next) : null;
|
849
923
|
if (in_statement && !name)
|
850
924
|
unexpected();
|
@@ -941,7 +1015,7 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
941
1015
|
return as("try", body, bcatch, bfinally);
|
942
1016
|
};
|
943
1017
|
|
944
|
-
function vardefs() {
|
1018
|
+
function vardefs(no_in) {
|
945
1019
|
var a = [];
|
946
1020
|
for (;;) {
|
947
1021
|
if (!is("name"))
|
@@ -950,7 +1024,7 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
950
1024
|
next();
|
951
1025
|
if (is("operator", "=")) {
|
952
1026
|
next();
|
953
|
-
a.push([ name, expression(false) ]);
|
1027
|
+
a.push([ name, expression(false, no_in) ]);
|
954
1028
|
} else {
|
955
1029
|
a.push([ name ]);
|
956
1030
|
}
|
@@ -961,8 +1035,8 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
961
1035
|
return a;
|
962
1036
|
};
|
963
1037
|
|
964
|
-
function var_() {
|
965
|
-
return as("var", vardefs());
|
1038
|
+
function var_(no_in) {
|
1039
|
+
return as("var", vardefs(no_in));
|
966
1040
|
};
|
967
1041
|
|
968
1042
|
function const_() {
|
@@ -1017,27 +1091,30 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
1017
1091
|
unexpected();
|
1018
1092
|
};
|
1019
1093
|
|
1020
|
-
function expr_list(closing, allow_trailing_comma) {
|
1094
|
+
function expr_list(closing, allow_trailing_comma, allow_empty) {
|
1021
1095
|
var first = true, a = [];
|
1022
1096
|
while (!is("punc", closing)) {
|
1023
1097
|
if (first) first = false; else expect(",");
|
1024
|
-
if (allow_trailing_comma && is("punc", closing))
|
1025
|
-
|
1026
|
-
|
1098
|
+
if (allow_trailing_comma && is("punc", closing)) break;
|
1099
|
+
if (is("punc", ",") && allow_empty) {
|
1100
|
+
a.push([ "atom", "undefined" ]);
|
1101
|
+
} else {
|
1102
|
+
a.push(expression(false));
|
1103
|
+
}
|
1027
1104
|
}
|
1028
1105
|
next();
|
1029
1106
|
return a;
|
1030
1107
|
};
|
1031
1108
|
|
1032
1109
|
function array_() {
|
1033
|
-
return as("array", expr_list("]", !
|
1110
|
+
return as("array", expr_list("]", !exigent_mode, true));
|
1034
1111
|
};
|
1035
1112
|
|
1036
1113
|
function object_() {
|
1037
1114
|
var first = true, a = [];
|
1038
1115
|
while (!is("punc", "}")) {
|
1039
1116
|
if (first) first = false; else expect(",");
|
1040
|
-
if (!
|
1117
|
+
if (!exigent_mode && is("punc", "}"))
|
1041
1118
|
// allow trailing comma
|
1042
1119
|
break;
|
1043
1120
|
var type = S.token.type;
|
@@ -1100,61 +1177,65 @@ function parse($TEXT, strict_mode, embed_tokens) {
|
|
1100
1177
|
return as(tag, op, expr);
|
1101
1178
|
};
|
1102
1179
|
|
1103
|
-
function expr_op(left, min_prec) {
|
1180
|
+
function expr_op(left, min_prec, no_in) {
|
1104
1181
|
var op = is("operator") ? S.token.value : null;
|
1182
|
+
if (op && op == "in" && no_in) op = null;
|
1105
1183
|
var prec = op != null ? PRECEDENCE[op] : null;
|
1106
1184
|
if (prec != null && prec > min_prec) {
|
1107
1185
|
next();
|
1108
|
-
var right = expr_op(expr_atom(true), prec);
|
1109
|
-
return expr_op(as("binary", op, left, right), min_prec);
|
1186
|
+
var right = expr_op(expr_atom(true), prec, no_in);
|
1187
|
+
return expr_op(as("binary", op, left, right), min_prec, no_in);
|
1110
1188
|
}
|
1111
1189
|
return left;
|
1112
1190
|
};
|
1113
1191
|
|
1114
|
-
function expr_ops() {
|
1115
|
-
return expr_op(expr_atom(true), 0);
|
1192
|
+
function expr_ops(no_in) {
|
1193
|
+
return expr_op(expr_atom(true), 0, no_in);
|
1116
1194
|
};
|
1117
1195
|
|
1118
|
-
function maybe_conditional() {
|
1119
|
-
var expr = expr_ops();
|
1196
|
+
function maybe_conditional(no_in) {
|
1197
|
+
var expr = expr_ops(no_in);
|
1120
1198
|
if (is("operator", "?")) {
|
1121
1199
|
next();
|
1122
1200
|
var yes = expression(false);
|
1123
1201
|
expect(":");
|
1124
|
-
return as("conditional", expr, yes, expression(false));
|
1202
|
+
return as("conditional", expr, yes, expression(false, no_in));
|
1125
1203
|
}
|
1126
1204
|
return expr;
|
1127
1205
|
};
|
1128
1206
|
|
1129
1207
|
function is_assignable(expr) {
|
1208
|
+
if (!exigent_mode) return true;
|
1130
1209
|
switch (expr[0]) {
|
1131
1210
|
case "dot":
|
1132
1211
|
case "sub":
|
1212
|
+
case "new":
|
1213
|
+
case "call":
|
1133
1214
|
return true;
|
1134
1215
|
case "name":
|
1135
1216
|
return expr[1] != "this";
|
1136
1217
|
}
|
1137
1218
|
};
|
1138
1219
|
|
1139
|
-
function maybe_assign() {
|
1140
|
-
var left = maybe_conditional(), val = S.token.value;
|
1220
|
+
function maybe_assign(no_in) {
|
1221
|
+
var left = maybe_conditional(no_in), val = S.token.value;
|
1141
1222
|
if (is("operator") && HOP(ASSIGNMENT, val)) {
|
1142
1223
|
if (is_assignable(left)) {
|
1143
1224
|
next();
|
1144
|
-
return as("assign", ASSIGNMENT[val], left, maybe_assign());
|
1225
|
+
return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in));
|
1145
1226
|
}
|
1146
1227
|
croak("Invalid assignment");
|
1147
1228
|
}
|
1148
1229
|
return left;
|
1149
1230
|
};
|
1150
1231
|
|
1151
|
-
function expression(commas) {
|
1232
|
+
function expression(commas, no_in) {
|
1152
1233
|
if (arguments.length == 0)
|
1153
1234
|
commas = true;
|
1154
|
-
var expr = maybe_assign();
|
1235
|
+
var expr = maybe_assign(no_in);
|
1155
1236
|
if (commas && is("punc", ",")) {
|
1156
1237
|
next();
|
1157
|
-
return as("seq", expr, expression());
|
1238
|
+
return as("seq", expr, expression(true, no_in));
|
1158
1239
|
}
|
1159
1240
|
return expr;
|
1160
1241
|
};
|
@@ -1217,6 +1298,8 @@ function HOP(obj, prop) {
|
|
1217
1298
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
1218
1299
|
};
|
1219
1300
|
|
1301
|
+
var warn = function() {};
|
1302
|
+
|
1220
1303
|
/* -----[ Exports ]----- */
|
1221
1304
|
|
1222
1305
|
exports.tokenizer = tokenizer;
|
@@ -1232,3 +1315,6 @@ exports.KEYWORDS = KEYWORDS;
|
|
1232
1315
|
exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN;
|
1233
1316
|
exports.OPERATORS = OPERATORS;
|
1234
1317
|
exports.is_alphanumeric_char = is_alphanumeric_char;
|
1318
|
+
exports.set_logger = function(logger) {
|
1319
|
+
warn = logger;
|
1320
|
+
};
|