uglifier 0.1.1 → 0.2.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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
data/lib/uglifier.rb CHANGED
@@ -11,6 +11,7 @@ class Uglifier
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
13
  :extra => false, # Additional and potentially unsafe optimizations
14
+ :unsafe => false, # Optimizations known to be unsafe in some situations
14
15
  :beautify => false, # Ouput indented code
15
16
  :beautify_options => {
16
17
  :indent_level => 4,
@@ -21,12 +22,20 @@ class Uglifier
21
22
  }
22
23
 
23
24
  def initialize(options = {})
24
- @options = DEFAULTS.merge options
25
+ @options = DEFAULTS.merge(options)
26
+ @exports = {
27
+ "sys" => {
28
+ :debug => lambda {|m| puts m }
29
+ }
30
+ }
25
31
  end
26
32
 
27
33
  def compile(source)
28
34
  V8::Context.new do |cxt|
29
- initialize_v8(cxt)
35
+ cxt["process"] = { :version => "v0.2.0" }
36
+
37
+ load_file(cxt, "parse-js")
38
+ load_file(cxt, "process")
30
39
  begin
31
40
  return generate_code(cxt, ast(cxt, source))
32
41
  rescue Exception => e
@@ -35,6 +44,10 @@ class Uglifier
35
44
  end
36
45
  end
37
46
 
47
+ def self.compile(source, options = {})
48
+ self.new(options).compile(source)
49
+ end
50
+
38
51
  private
39
52
 
40
53
  def generate_code(cxt, ast)
@@ -42,14 +55,17 @@ class Uglifier
42
55
  end
43
56
 
44
57
  def ast(cxt, source)
45
- squeeze(cxt, mangle(cxt, cxt["parse"].call(source)))
58
+ squeeze_unsafe(cxt, squeeze(cxt, mangle(cxt, cxt["parse"].call(source))))
46
59
  end
47
60
 
48
61
  def mangle(cxt, ast)
62
+ return ast unless @options[:mangle]
49
63
  cxt["ast_mangle"].call(ast, @options[:toplevel])
50
64
  end
51
65
 
52
66
  def squeeze(cxt, ast)
67
+ return ast unless @options[:squeeze]
68
+
53
69
  cxt["ast_squeeze"].call(ast, {
54
70
  "make_seqs" => @options[:seqs],
55
71
  "dead_code" => @options[:dead_code],
@@ -57,25 +73,23 @@ class Uglifier
57
73
  })
58
74
  end
59
75
 
60
- def initialize_v8(cxt)
61
- cxt["process"] = { :version => "v0.2.0" }
62
- exports = {
63
- "sys" => {
64
- :debug => lambda { |m| puts m }
65
- },
66
- "./parse-js" => load_file(cxt, "vendor/uglifyjs/lib/parse-js.js")
67
- }
68
-
69
- cxt["require"] = lambda do |file|
70
- exports[file]
71
- end
72
-
73
- load_file(cxt, "vendor/uglifyjs/lib/process.js")
76
+ def squeeze_unsafe(cxt, ast)
77
+ return ast unless @options[:unsafe]
78
+ cxt["ast_squeeze_more"].call(ast)
74
79
  end
75
80
 
76
81
  def load_file(cxt, file)
82
+ old = cxt["exports"]
77
83
  cxt["exports"] = {}
78
- cxt.load(File.join(File.dirname(__FILE__), "..", file))
79
- cxt["exports"]
84
+ cxt["require"] = lambda {|r|
85
+ @exports[File.basename(r, ".js")] || begin
86
+ @exports[file] = cxt["exports"] # Prevent circular dependencies
87
+ load_file(cxt, File.basename(r, ".js"))
88
+ end
89
+ }
90
+ cxt.load(File.join(File.dirname(__FILE__), "..", "vendor", "uglifyjs", "lib", File.basename(file, ".js") + ".js"))
91
+ @exports[file] = cxt["exports"]
92
+ cxt["exports"] = old
93
+ @exports[file]
80
94
  end
81
95
  end
@@ -25,4 +25,19 @@ describe "Uglifier" do
25
25
  }")
26
26
  }.should_not raise_error(Uglifier::Error)
27
27
  end
28
+
29
+ it "does additional squeezing when unsafe options is true" do
30
+ unsafe_input = "function a(b){b.toString();}"
31
+ Uglifier.new(:unsafe => true).compile(unsafe_input).length.should < Uglifier.new(:unsafe => false).compile(unsafe_input).length
32
+ end
33
+
34
+ it "mangles variables only if mangle is set to true" do
35
+ code = "function longFunctionName(){}"
36
+ Uglifier.new(:mangle => false).compile(code).length.should == code.length
37
+ end
38
+
39
+ it "squeezes code only if squeeze is set to true" do
40
+ code = "function a(a){if(a) { return 0; } else { return 1; }}"
41
+ Uglifier.compile(code, :squeeze => false).length.should > Uglifier.compile(code, :squeeze => true).length
42
+ end
28
43
  end
data/uglifier.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{uglifier}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.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{2010-11-18}
12
+ s.date = %q{2010-11-24}
13
13
  s.email = %q{lautis@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE.txt",
@@ -29,7 +29,8 @@ Gem::Specification.new do |s|
29
29
  "spec/uglifier_spec.rb",
30
30
  "uglifier.gemspec",
31
31
  "vendor/uglifyjs/lib/parse-js.js",
32
- "vendor/uglifyjs/lib/process.js"
32
+ "vendor/uglifyjs/lib/process.js",
33
+ "vendor/uglifyjs/lib/squeeze-more.js"
33
34
  ]
34
35
  s.homepage = %q{http://github.com/lautis/uglifier}
35
36
  s.require_paths = ["lib"]
@@ -361,14 +361,10 @@ function ast_add_scope(ast) {
361
361
 
362
362
  function with_new_scope(cont) {
363
363
  current_scope = new Scope(current_scope);
364
- try {
365
- var ret = current_scope.body = cont();
366
- ret.scope = current_scope;
367
- return ret;
368
- }
369
- finally {
370
- current_scope = current_scope.parent;
371
- }
364
+ var ret = current_scope.body = cont();
365
+ ret.scope = current_scope;
366
+ current_scope = current_scope.parent;
367
+ return ret;
372
368
  };
373
369
 
374
370
  function define(name) {
@@ -987,17 +983,10 @@ function ast_squeeze(ast, options) {
987
983
  "unary-prefix": function(op, cond) {
988
984
  if (op == "!")
989
985
  return best_of(this, negate(cond));
990
- },
991
- "call": function(expr, args) {
992
- if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
993
- // foo.toString() ==> foo+""
994
- return [ "binary", "+", expr[1], [ "string", "" ]];
995
- }
996
986
  }
997
987
  }, function() {
998
988
  return walk(ast);
999
989
  });
1000
-
1001
990
  };
1002
991
 
1003
992
  /* -----[ re-generate code from the AST ]----- */
@@ -1091,7 +1080,7 @@ function gen_code(ast, beautify) {
1091
1080
  // parent is "stat", and so on. Messy stuff,
1092
1081
  // but it worths the trouble.
1093
1082
  var a = slice($stack), self = a.pop(), p = a.pop();
1094
- while (true) {
1083
+ while (p) {
1095
1084
  if (p[0] == "stat") return true;
1096
1085
  if ((p[0] == "seq" && p[1] === self) ||
1097
1086
  (p[0] == "call" && p[1] === self) ||
@@ -1115,7 +1104,7 @@ function gen_code(ast, beautify) {
1115
1104
  a.push(m[1] + "e" + m[2].length);
1116
1105
  }
1117
1106
  } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
1118
- a.push(m[2] + "e-" + (m[1].length + 1),
1107
+ a.push(m[2] + "e-" + (m[1].length + m[2].length),
1119
1108
  str.substr(str.indexOf(".")));
1120
1109
  }
1121
1110
  return best_of(a);
@@ -1329,6 +1318,13 @@ function gen_code(ast, beautify) {
1329
1318
  // to the inner IF). This function checks for this case and
1330
1319
  // adds the block brackets if needed.
1331
1320
  function make_then(th) {
1321
+ if (th[0] == "do") {
1322
+ // https://github.com/mishoo/UglifyJS/issues/#issue/57
1323
+ // IE croaks with "syntax error" on code like this:
1324
+ // if (foo) do ... while(cond); else ...
1325
+ // we need block brackets around do/while
1326
+ return make([ "block", [ th ]]);
1327
+ }
1332
1328
  var b = th;
1333
1329
  while (true) {
1334
1330
  var type = b[0];
@@ -1482,3 +1478,4 @@ exports.ast_mangle = ast_mangle;
1482
1478
  exports.ast_squeeze = ast_squeeze;
1483
1479
  exports.gen_code = gen_code;
1484
1480
  exports.ast_add_scope = ast_add_scope;
1481
+ exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
@@ -0,0 +1,22 @@
1
+ var jsp = require("./parse-js"),
2
+ pro = require("./process"),
3
+ slice = jsp.slice,
4
+ member = jsp.member,
5
+ PRECEDENCE = jsp.PRECEDENCE,
6
+ OPERATORS = jsp.OPERATORS;
7
+
8
+ function ast_squeeze_more(ast) {
9
+ var w = pro.ast_walker(), walk = w.walk;
10
+ return w.with_walkers({
11
+ "call": function(expr, args) {
12
+ if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
13
+ // foo.toString() ==> foo+""
14
+ return [ "binary", "+", expr[1], [ "string", "" ]];
15
+ }
16
+ }
17
+ }, function() {
18
+ return walk(ast);
19
+ });
20
+ };
21
+
22
+ exports.ast_squeeze_more = ast_squeeze_more;
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uglifier
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ville Lautanala
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-18 00:00:00 +02:00
18
+ date: 2010-11-24 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -200,6 +200,7 @@ files:
200
200
  - uglifier.gemspec
201
201
  - vendor/uglifyjs/lib/parse-js.js
202
202
  - vendor/uglifyjs/lib/process.js
203
+ - vendor/uglifyjs/lib/squeeze-more.js
203
204
  has_rdoc: true
204
205
  homepage: http://github.com/lautis/uglifier
205
206
  licenses: []