minjs 0.1.7 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/minjs/compressor.rb +371 -226
- data/lib/minjs/ecma262/base.rb +61 -15
- data/lib/minjs/ecma262/exp.rb +202 -75
- data/lib/minjs/ecma262/lit.rb +81 -5
- data/lib/minjs/ecma262/punc.rb +4 -0
- data/lib/minjs/ecma262/st.rb +254 -149
- data/lib/minjs/version.rb +1 -1
- metadata +2 -2
data/lib/minjs/compressor.rb
CHANGED
@@ -36,7 +36,17 @@ module Minjs
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def to_js(options = {})
|
39
|
-
|
39
|
+
remove_empty_statement
|
40
|
+
@prog.to_js(options).sub(/;;\Z/, ";")
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_empty_statement(node = @prog)
|
44
|
+
node.traverse(nil) {|st, parent|
|
45
|
+
if st.kind_of? ECMA262::StatementList
|
46
|
+
st.remove_empty_statement
|
47
|
+
end
|
48
|
+
}
|
49
|
+
self
|
40
50
|
end
|
41
51
|
|
42
52
|
def compress(data, options = {})
|
@@ -58,27 +68,35 @@ module Minjs
|
|
58
68
|
@logger.info '* grouping_statement'
|
59
69
|
grouping_statement
|
60
70
|
|
61
|
-
@logger.info '* block_to_statement'
|
62
|
-
block_to_statement
|
63
|
-
|
64
71
|
@logger.info '* reduce_if'
|
65
72
|
reduce_if
|
66
73
|
|
74
|
+
@logger.info '* block_to_statement'
|
75
|
+
block_to_statement
|
76
|
+
|
67
77
|
@logger.info '* if_to_cond'
|
68
78
|
if_to_cond
|
69
79
|
|
80
|
+
@logger.info '* optimize_if_return'
|
81
|
+
optimize_if_return
|
82
|
+
|
70
83
|
@logger.info '* compress_var'
|
84
|
+
compress_var(@prog, :longer => true)
|
71
85
|
compress_var
|
72
86
|
|
73
87
|
@logger.info '* reduce_exp'
|
74
88
|
reduce_exp
|
75
89
|
|
90
|
+
grouping_statement
|
91
|
+
block_to_statement
|
92
|
+
if_to_cond
|
93
|
+
|
94
|
+
#feature
|
95
|
+
optimize_if_return2
|
96
|
+
|
76
97
|
@logger.info '* remove_paren'
|
77
98
|
remove_paren
|
78
99
|
|
79
|
-
@logger.info '* return_to_exp'
|
80
|
-
return_to_exp
|
81
|
-
|
82
100
|
@heading_comments.reverse.each do |c|
|
83
101
|
@prog.source_elements.source_elements.unshift(c)
|
84
102
|
end
|
@@ -97,12 +115,14 @@ module Minjs
|
|
97
115
|
nil
|
98
116
|
}
|
99
117
|
@prog = source_elements(@lex, @global_context)
|
100
|
-
@prog
|
101
|
-
end
|
102
118
|
|
103
|
-
#
|
104
|
-
#
|
105
|
-
|
119
|
+
#a = @prog.deep_dup
|
120
|
+
#a == @prog
|
121
|
+
|
122
|
+
remove_empty_statement
|
123
|
+
#@prog
|
124
|
+
self
|
125
|
+
end
|
106
126
|
|
107
127
|
def next_sym(s)
|
108
128
|
def c2i(c)
|
@@ -186,19 +206,81 @@ module Minjs
|
|
186
206
|
node.traverse(nil) {|st, parent|
|
187
207
|
if st.kind_of? ECMA262::Prog
|
188
208
|
vars = nil
|
189
|
-
context =
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
209
|
+
context = st.context
|
210
|
+
#
|
211
|
+
# collect all of var variable in this function
|
212
|
+
#
|
213
|
+
var_vars = {}
|
214
|
+
context.var_env.record.binding.each do|k, v|
|
215
|
+
if v and v[:_parameter_list].nil? and !v[:value].kind_of?(ECMA262::StFunc)
|
216
|
+
var_vars[k] = true
|
217
|
+
end
|
218
|
+
end
|
219
|
+
#
|
220
|
+
# traverse block and convert var statement to assignment expression
|
221
|
+
# if variable has initializer
|
222
|
+
#
|
223
|
+
st.traverse(parent){|st2, parent2|
|
224
|
+
if st2.kind_of? ECMA262::StVar and st2.context.var_env == context.var_env
|
225
|
+
exp = nil
|
226
|
+
st2.vars.each do |name, initializer|
|
227
|
+
if initializer
|
228
|
+
if exp.nil?
|
229
|
+
exp = ECMA262::ExpAssign.new(name, initializer)
|
230
|
+
else
|
231
|
+
exp = ECMA262::ExpComma.new(exp, ECMA262::ExpAssign.new(name, initializer))
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
if exp
|
236
|
+
parent2.replace(st2, ECMA262::StExp.new(exp))
|
237
|
+
else
|
238
|
+
parent2.replace(st2, ECMA262::StEmpty.new())
|
239
|
+
end
|
240
|
+
elsif st2.kind_of? ECMA262::StForVar and st2.context.var_env == context.var_env
|
241
|
+
parent2.replace(st2, st2.to_st_for)
|
242
|
+
elsif st2.kind_of? ECMA262::StForInVar and st2.context.var_env == context.var_env
|
243
|
+
parent2.replace(st2, st2.to_st_for_in)
|
244
|
+
end
|
245
|
+
}
|
246
|
+
if var_vars.length > 0
|
247
|
+
elems = st.source_elements.source_elements
|
248
|
+
v = ECMA262::StVar.new(
|
249
|
+
context,
|
250
|
+
var_vars.collect do |k, v|
|
251
|
+
[ECMA262::IdentifierName.new(context, k)]
|
252
|
+
end
|
253
|
+
)
|
254
|
+
|
255
|
+
idx = 0
|
256
|
+
elems.each do |e|
|
257
|
+
found = false
|
258
|
+
e.traverse(nil){|ee, pp|
|
259
|
+
if ee.kind_of? ECMA262::IdentifierName and var_vars[ee.val.to_sym]
|
260
|
+
found = true
|
261
|
+
break
|
262
|
+
end
|
263
|
+
}
|
264
|
+
break if found
|
265
|
+
idx += 1
|
266
|
+
end
|
267
|
+
|
268
|
+
if idx == 0
|
269
|
+
elems.unshift(v)
|
270
|
+
else
|
271
|
+
elems[idx..0] = v
|
272
|
+
end
|
273
|
+
st.source_elements.remove_empty_statement
|
274
|
+
end
|
275
|
+
end
|
276
|
+
self
|
277
|
+
}
|
278
|
+
=begin
|
201
279
|
st.traverse(parent) {|st2, parent2|
|
280
|
+
#
|
281
|
+
#if var statment has initializer,
|
282
|
+
#
|
283
|
+
#
|
202
284
|
if st2.kind_of? ECMA262::StVar and st2.context.var_env == @context.var_env
|
203
285
|
st2.instance_eval{
|
204
286
|
blk = []
|
@@ -216,13 +298,12 @@ module Minjs
|
|
216
298
|
parent2.replace(st2, st2.to_st_for_in)
|
217
299
|
end
|
218
300
|
}
|
219
|
-
|
220
|
-
@source_elements.source_elements.unshift ECMA262::StVar.new(@context, vars)
|
221
|
-
end
|
301
|
+
|
222
302
|
}
|
223
303
|
end
|
224
304
|
}
|
225
305
|
remove_block_in_block
|
306
|
+
=end
|
226
307
|
self
|
227
308
|
end
|
228
309
|
|
@@ -255,123 +336,194 @@ module Minjs
|
|
255
336
|
end
|
256
337
|
|
257
338
|
def block_to_statement(node = @prog)
|
339
|
+
node.traverse(nil) {|st, parent|
|
340
|
+
if st.kind_of? ECMA262::StBlock and !parent.kind_of?(ECMA262::StTry) and !parent.kind_of?(ECMA262::StIf)
|
341
|
+
if st.to_statement?
|
342
|
+
parent.replace(st, st.to_statement)
|
343
|
+
end
|
344
|
+
end
|
345
|
+
}
|
346
|
+
if_block_to_statement
|
347
|
+
end
|
348
|
+
|
349
|
+
#
|
350
|
+
# To determine removing "if block" is available or not is difficult.
|
351
|
+
# For example, next codes block must not be removed, because
|
352
|
+
# "else" cluase combined to second "if" statement.
|
353
|
+
#
|
354
|
+
#
|
355
|
+
# if(a){ //<= this block must not be removed
|
356
|
+
# while(true)
|
357
|
+
# if(b){
|
358
|
+
# ;
|
359
|
+
# }
|
360
|
+
# }
|
361
|
+
# else{
|
362
|
+
# ;
|
363
|
+
# }
|
364
|
+
def if_block_to_statement(node = @prog)
|
365
|
+
# The "else" cluase's block can be removed always
|
258
366
|
node.traverse(nil) {|st, parent|
|
259
367
|
if st.kind_of? ECMA262::StIf
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
#
|
265
|
-
#
|
266
|
-
# if(a){ //<= this block must not be removed
|
267
|
-
# while(true)
|
268
|
-
# if(b){
|
269
|
-
# ;
|
270
|
-
# }
|
271
|
-
# }
|
272
|
-
# else{
|
273
|
-
# ;
|
274
|
-
# }
|
275
|
-
|
276
|
-
# The "else" cluase's block can be removed without condition.
|
368
|
+
if st.else_st and st.else_st.kind_of? ECMA262::StBlock
|
369
|
+
st.else_st.remove_empty_statement
|
370
|
+
end
|
371
|
+
|
277
372
|
if st.else_st and st.else_st.kind_of? ECMA262::StBlock and st.else_st.to_statement?
|
278
373
|
st.replace(st.else_st, st.else_st.to_statement)
|
279
374
|
end
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
375
|
+
end
|
376
|
+
}
|
377
|
+
node.traverse(nil) {|st0, parent|
|
378
|
+
st = st0.deep_dup
|
379
|
+
if st.kind_of? ECMA262::StIf
|
380
|
+
if st.then_st and st.then_st.kind_of? ECMA262::StBlock
|
381
|
+
st.then_st.remove_empty_statement
|
382
|
+
end
|
383
|
+
|
384
|
+
if st.then_st and st.then_st.kind_of? ECMA262::StBlock and st.then_st.to_statement?
|
284
385
|
st.replace(st.then_st, st.then_st.to_statement)
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
last_st = st.then_st.last_statement.map{|x|
|
293
|
-
if x.kind_of? ECMA262::StIf and x.else_st.nil?
|
294
|
-
deblock = false
|
295
|
-
end
|
296
|
-
}
|
297
|
-
if deblock
|
298
|
-
st.replace(st.then_st, st.then_st.to_statement)
|
299
|
-
end
|
386
|
+
end
|
387
|
+
|
388
|
+
_lex = Minjs::Lex.new(st.to_js)
|
389
|
+
_context = ECMA262::Context.new
|
390
|
+
_if = if_statement(_lex, _context)
|
391
|
+
if _if == st #
|
392
|
+
parent.replace(st0, st)
|
300
393
|
end
|
301
394
|
end
|
302
395
|
}
|
396
|
+
self
|
397
|
+
end
|
398
|
+
|
399
|
+
#
|
400
|
+
# if(a)b;else c;
|
401
|
+
# =>
|
402
|
+
# a?b:c
|
403
|
+
#
|
404
|
+
# if(a)b
|
405
|
+
# =>
|
406
|
+
# a&&b;
|
407
|
+
#
|
408
|
+
def if_to_cond(node = @prog)
|
303
409
|
node.traverse(nil) {|st, parent|
|
304
|
-
if st.kind_of? ECMA262::
|
305
|
-
|
306
|
-
|
410
|
+
if st.kind_of? ECMA262::StIf
|
411
|
+
if st.to_exp?
|
412
|
+
t = ECMA262::StExp.new(st.to_exp({}))
|
413
|
+
remove_paren(t)
|
414
|
+
if t.to_js.length <= st.to_js.length
|
415
|
+
parent.replace(st, t)
|
307
416
|
end
|
417
|
+
end
|
308
418
|
end
|
309
419
|
}
|
420
|
+
if_to_return(node)
|
310
421
|
self
|
311
422
|
end
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
def
|
317
|
-
node = @prog if node.nil?
|
423
|
+
#
|
424
|
+
# if(a)return b;else return c;
|
425
|
+
# => return a?b:c;
|
426
|
+
#
|
427
|
+
def if_to_return(node = @prog)
|
318
428
|
node.traverse(nil) {|st, parent|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
if st.kind_of? ECMA262::StIf and parent.kind_of? ECMA262::StatementList
|
328
|
-
i = parent.index(st)
|
329
|
-
if parent[i+1].nil? and !parent.kind_of?(ECMA262::SourceElements)
|
330
|
-
next
|
429
|
+
if st.kind_of? ECMA262::StIf
|
430
|
+
if st.to_return?
|
431
|
+
t = st.to_return
|
432
|
+
remove_paren(t)
|
433
|
+
if t.to_js.length <= st.to_js.length
|
434
|
+
parent.replace(st, t)
|
435
|
+
end
|
331
436
|
end
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
437
|
+
end
|
438
|
+
}
|
439
|
+
self
|
440
|
+
end
|
441
|
+
|
442
|
+
#
|
443
|
+
# if(a)return b;
|
444
|
+
# return c;
|
445
|
+
#
|
446
|
+
# => if(a)return b;else return c;
|
447
|
+
# => return a?b:c;
|
448
|
+
#
|
449
|
+
def optimize_if_return(node = @prog)
|
450
|
+
retry_flag = true
|
451
|
+
while retry_flag
|
452
|
+
retry_flag = false
|
453
|
+
node.traverse(nil) {|st0, parent0|
|
454
|
+
if st0.kind_of? ECMA262::StIf and parent0.kind_of? ECMA262::StatementList
|
455
|
+
i = parent0.index(st0)
|
456
|
+
break if i.nil?
|
457
|
+
parent = parent0.deep_dup
|
458
|
+
st = parent[i]
|
459
|
+
#
|
460
|
+
if parent[i+1].nil? and !parent.kind_of?(ECMA262::SourceElements)
|
461
|
+
next
|
336
462
|
end
|
337
|
-
if
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
463
|
+
if parent[i+1].nil? or parent[i+1].to_return?
|
464
|
+
s = st
|
465
|
+
while s.kind_of? ECMA262::StIf and s.else_st and s.then_st.to_return?
|
466
|
+
s = s.else_st
|
467
|
+
end
|
468
|
+
if s and s.kind_of? ECMA262::StIf and s.then_st.to_return?
|
469
|
+
if parent[i+1]
|
470
|
+
s.replace(s.else_st, parent[i+1])
|
471
|
+
parent.replace(parent[i+1], ECMA262::StEmpty.new)
|
472
|
+
else
|
473
|
+
s.replace(s.else_st, ECMA262::StReturn.new(ECMA262::ExpVoid.new(ECMA262::ECMA262Numeric.new(0))))
|
474
|
+
end
|
475
|
+
if_to_cond(parent)
|
476
|
+
if parent.to_js(:no_debug => true).length <= parent0.to_js(:no_debug => true).length
|
477
|
+
parent0.replace(st0, st)
|
478
|
+
if parent[i+1]
|
479
|
+
parent0.replace(parent0[i+1], ECMA262::StEmpty.new)
|
480
|
+
end
|
481
|
+
retry_flag = true
|
482
|
+
node = parent0
|
483
|
+
end
|
343
484
|
end
|
344
485
|
end
|
345
486
|
end
|
346
|
-
|
347
|
-
|
487
|
+
}
|
488
|
+
end
|
489
|
+
self
|
490
|
+
end
|
491
|
+
|
492
|
+
#
|
493
|
+
# if(a)return b;else c;
|
494
|
+
# =>
|
495
|
+
# if(a)return b;c;
|
496
|
+
#
|
497
|
+
def optimize_if_return2(node = @prog)
|
348
498
|
node.traverse(nil) {|st, parent|
|
349
|
-
if st.kind_of? ECMA262::StIf and st.
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
parent.replace(st, st.to_return)
|
499
|
+
if st.kind_of? ECMA262::StIf and st.else_st and parent.kind_of? ECMA262::StatementList
|
500
|
+
st.remove_empty_statement
|
501
|
+
if (st.then_st.kind_of? ECMA262::StBlock and st.then_st[-1].kind_of? ECMA262::StReturn) or
|
502
|
+
st.then_st.kind_of? ECMA262::StReturn
|
503
|
+
idx = parent.index(st)
|
504
|
+
parent[idx+1..0] = st.else_st
|
505
|
+
st.replace(st.else_st, nil)
|
357
506
|
end
|
358
507
|
end
|
359
508
|
}
|
360
|
-
remove_paren
|
361
509
|
self
|
362
510
|
end
|
363
511
|
|
364
|
-
def compress_var(node = @prog)
|
512
|
+
def compress_var(node = @prog, options = {})
|
513
|
+
if options[:longer]
|
514
|
+
var_sym = :aaaaaaaaaa
|
515
|
+
end
|
516
|
+
|
365
517
|
#
|
366
518
|
#traverse all statemtns and expression
|
367
519
|
#
|
520
|
+
scopes = []
|
368
521
|
node.traverse(nil) {|st, parent|
|
369
|
-
var_sym = :a
|
370
522
|
if st.kind_of? ECMA262::StTry and st.catch
|
371
523
|
_context = st.catch_context
|
372
524
|
_parent = st
|
373
525
|
_st = st.catch[1]
|
374
|
-
elsif st.kind_of? ECMA262::StFunc
|
526
|
+
elsif st.kind_of? ECMA262::StFunc
|
375
527
|
_context = st.context
|
376
528
|
_parent = parent
|
377
529
|
_st = st
|
@@ -380,9 +532,19 @@ module Minjs
|
|
380
532
|
_context = nil
|
381
533
|
_st = nil
|
382
534
|
end
|
535
|
+
if _parent and _context and _st
|
536
|
+
scopes.push([st, parent, _parent, _context, _st])
|
537
|
+
end
|
538
|
+
}
|
539
|
+
#node.traverse(nil) {|st, parent|
|
540
|
+
scopes.reverse.each {|st, parent, _parent, _context, _st|
|
541
|
+
#p "*#{st.name.to_js}"
|
542
|
+
if !options[:longer]
|
543
|
+
var_sym = :a
|
544
|
+
end
|
383
545
|
if _parent and _context and _st
|
384
546
|
#
|
385
|
-
# collect all variables under this function/catch
|
547
|
+
# collect and counting all variables under this function/catch
|
386
548
|
#
|
387
549
|
vars = {}
|
388
550
|
if st.kind_of? ECMA262::StTry
|
@@ -402,13 +564,6 @@ module Minjs
|
|
402
564
|
_context.var_env.record.binding.each do|k, v|
|
403
565
|
var_vars[k] = (vars[k] || 1)
|
404
566
|
end
|
405
|
-
_st.traverse(parent) {|st2|
|
406
|
-
if st2.kind_of? ECMA262::StFunc
|
407
|
-
st2.context.var_env.record.binding.each do|k, v|
|
408
|
-
var_vars[k] = (vars[k] || 1)
|
409
|
-
end
|
410
|
-
end
|
411
|
-
}
|
412
567
|
end
|
413
568
|
#
|
414
569
|
# collect all lexical variables under this catch clause
|
@@ -440,6 +595,7 @@ module Minjs
|
|
440
595
|
# sort var_vars
|
441
596
|
#
|
442
597
|
var_vars = var_vars.sort {|(k1,v1), (k2,v2)| v2 <=> v1}
|
598
|
+
#p var_vars
|
443
599
|
#
|
444
600
|
# check var_vars
|
445
601
|
#
|
@@ -450,22 +606,38 @@ module Minjs
|
|
450
606
|
while(vars[var_sym])
|
451
607
|
var_sym = next_sym(var_sym)
|
452
608
|
end
|
453
|
-
if name.to_s.bytesize
|
609
|
+
if (!options[:longer] && name.to_s.bytesize >= var_sym.to_s.bytesize) or
|
610
|
+
(options[:longer] && name.to_s.bytesize <= var_sym.to_s.bytesize)
|
454
611
|
#
|
455
612
|
# rename `name' to `var_sym'
|
456
613
|
#
|
614
|
+
func_name = nil
|
615
|
+
if _st.kind_of? ECMA262::StFunc and _st.decl?
|
616
|
+
func_name = _st.name
|
617
|
+
end
|
457
618
|
_st.traverse(_parent){|st2|
|
458
619
|
if st2.kind_of? ECMA262::IdentifierName and st2.context.nil?
|
459
|
-
;#
|
620
|
+
;# this
|
460
621
|
elsif st2.kind_of? ECMA262::IdentifierName and st2.context.var_env.outer == nil # global scope
|
461
622
|
;
|
462
623
|
elsif st2.kind_of? ECMA262::IdentifierName and st2.val == name
|
463
|
-
|
464
|
-
|
465
|
-
|
624
|
+
# scope of function's name is outer
|
625
|
+
if st2.eql?(func_name)
|
626
|
+
else
|
627
|
+
st2.instance_eval{
|
628
|
+
@val = var_sym
|
629
|
+
}
|
630
|
+
end
|
466
631
|
elsif st2.kind_of? ECMA262::StFunc
|
467
|
-
|
468
|
-
|
632
|
+
if st2.context.var_env.record.binding[name]
|
633
|
+
st2.context.var_env.record.binding[var_sym] = st2.context.var_env.record.binding[name]
|
634
|
+
st2.context.var_env.record.binding.delete(name)
|
635
|
+
end
|
636
|
+
elsif st2.kind_of? ECMA262::StTry
|
637
|
+
if st2.catch_context.lex_env.record.binding[name]
|
638
|
+
st2.catch_context.lex_env.record.binding[var_sym] = st2.catch_context.lex_env.record.binding[name]
|
639
|
+
st2.catch_context.lex_env.record.binding.delete(name)
|
640
|
+
end
|
469
641
|
end
|
470
642
|
}
|
471
643
|
end
|
@@ -498,6 +670,16 @@ module Minjs
|
|
498
670
|
st.catch[0].instance_eval{
|
499
671
|
@val = var_sym
|
500
672
|
}
|
673
|
+
elsif st2.kind_of? ECMA262::StFunc
|
674
|
+
if st2.context.var_env.record.binding[name]
|
675
|
+
st2.context.var_env.record.binding[var_sym] = st2.context.var_env.record.binding[name]
|
676
|
+
st2.context.var_env.record.binding.delete(name)
|
677
|
+
end
|
678
|
+
elsif st2.kind_of? ECMA262::StTry
|
679
|
+
if st2.catch_context.lex_env.record.binding[name]
|
680
|
+
st2.catch_context.lex_env.record.binding[var_sym] = st2.catch_context.lex_env.record.binding[name]
|
681
|
+
st2.catch_context.lex_env.record.binding.delete(name)
|
682
|
+
end
|
501
683
|
end
|
502
684
|
end
|
503
685
|
end
|
@@ -533,7 +715,20 @@ module Minjs
|
|
533
715
|
#if(true){<then>}else{<else>} => then
|
534
716
|
#
|
535
717
|
elsif st.kind_of? ECMA262::StIf
|
536
|
-
if
|
718
|
+
#if(a)z;else;
|
719
|
+
#if(a)z;else{}
|
720
|
+
# => {if(a)z;}
|
721
|
+
if st.else_st and st.else_st.empty?
|
722
|
+
st.replace(st.else_st, nil)
|
723
|
+
parent.replace(st, ECMA262::StBlock.new([st]))
|
724
|
+
end
|
725
|
+
#if(a);
|
726
|
+
# => a
|
727
|
+
#if(a){}
|
728
|
+
# => a
|
729
|
+
if st.then_st.empty? and st.else_st.nil?
|
730
|
+
parent.replace(st, ECMA262::StExp.new(st.cond))
|
731
|
+
elsif st.cond.respond_to? :to_ecma262_boolean
|
537
732
|
if st.cond.to_ecma262_boolean
|
538
733
|
parent.replace(st, st.then_st)
|
539
734
|
elsif st.else_st
|
@@ -557,61 +752,6 @@ module Minjs
|
|
557
752
|
self
|
558
753
|
end
|
559
754
|
|
560
|
-
def return_to_exp(node = @prog)
|
561
|
-
node.traverse(nil) {|st, parent|
|
562
|
-
if st.kind_of? ECMA262::StReturn
|
563
|
-
if parent.kind_of? ECMA262::StatementList
|
564
|
-
parent.remove_empty_statement
|
565
|
-
if parent.statement_list[-1] == st and (prev=parent.statement_list[-2]).class == ECMA262::StExp
|
566
|
-
if st.exp
|
567
|
-
st.replace(st.exp, ECMA262::ExpComma.new(prev.exp, st.exp))
|
568
|
-
parent.replace(prev, ECMA262::StEmpty.new())
|
569
|
-
end
|
570
|
-
end
|
571
|
-
parent.remove_empty_statement
|
572
|
-
end
|
573
|
-
end
|
574
|
-
}
|
575
|
-
block_to_statement
|
576
|
-
if_to_cond
|
577
|
-
self
|
578
|
-
end
|
579
|
-
#
|
580
|
-
# var a; a=1
|
581
|
-
# => var a=1
|
582
|
-
#
|
583
|
-
def assignment_after_var_old(node = @prog)
|
584
|
-
node.traverse(nil) {|st, parent|
|
585
|
-
if st.kind_of? ECMA262::StExp and parent.kind_of? ECMA262::SourceElements
|
586
|
-
if st.exp.kind_of? ECMA262::ExpAssign
|
587
|
-
idx = parent.index(st)
|
588
|
-
while idx > 0
|
589
|
-
idx -= 1
|
590
|
-
prevst = parent[idx]
|
591
|
-
if prevst.kind_of? ECMA262::StEmpty
|
592
|
-
next
|
593
|
-
elsif prevst.kind_of? ECMA262::StVar
|
594
|
-
i = 0
|
595
|
-
prevst.normalization
|
596
|
-
prevst.vars.each do |name, init|
|
597
|
-
if st.exp.val == name and init.nil?
|
598
|
-
prevst.vars[i] = [name, st.exp.val2]
|
599
|
-
parent.replace(st, ECMA262::StEmpty.new())
|
600
|
-
break
|
601
|
-
end
|
602
|
-
i += 1
|
603
|
-
end
|
604
|
-
prevst.normalization
|
605
|
-
break
|
606
|
-
else
|
607
|
-
break
|
608
|
-
end
|
609
|
-
end
|
610
|
-
end
|
611
|
-
end
|
612
|
-
}
|
613
|
-
self
|
614
|
-
end
|
615
755
|
#
|
616
756
|
# reduce_if
|
617
757
|
#
|
@@ -653,58 +793,63 @@ module Minjs
|
|
653
793
|
end
|
654
794
|
false
|
655
795
|
end
|
656
|
-
node.traverse(nil) {|st, parent|
|
657
|
-
if st.kind_of? ECMA262::StVar and parent.kind_of? ECMA262::SourceElements
|
658
|
-
#
|
659
|
-
# index of 'var statement' is 0, after calling reorder_var
|
660
|
-
#
|
661
|
-
catch(:break){
|
662
|
-
idx = 1
|
663
|
-
while true
|
664
|
-
st2 = parent[idx]
|
665
|
-
if st2.kind_of? ECMA262::StEmpty
|
666
|
-
idx +=1
|
667
|
-
next
|
668
|
-
elsif st2.kind_of? ECMA262::StExp and st2.exp.kind_of? ECMA262::ExpAssign
|
669
|
-
if rewrite_var(st, st2.exp.val, st2.exp.val2)
|
670
|
-
parent.replace(st2, ECMA262::StEmpty.new())
|
671
|
-
else
|
672
|
-
throw :break
|
673
|
-
end
|
674
|
-
idx += 1
|
675
|
-
next
|
676
|
-
elsif st2.kind_of? ECMA262::StFor and st2.exp1.kind_of? ECMA262::ExpAssign
|
677
|
-
if rewrite_var(st, st2.exp1.val, st2.exp1.val2)
|
678
|
-
st2.replace(st2.exp1, nil)
|
679
|
-
else
|
680
|
-
throw :break
|
681
|
-
end
|
682
|
-
throw :break
|
683
|
-
elsif st2.kind_of? ECMA262::StExp and st2.exp.kind_of? ECMA262::ExpComma
|
684
|
-
exp_parent = st2
|
685
|
-
exp = st2.exp
|
686
|
-
|
687
|
-
while exp.val.kind_of? ECMA262::ExpComma
|
688
|
-
exp_parent = exp
|
689
|
-
exp = exp.val
|
690
|
-
end
|
691
796
|
|
692
|
-
|
693
|
-
|
694
|
-
|
797
|
+
retry_flag = true
|
798
|
+
while retry_flag
|
799
|
+
retry_flag = false
|
800
|
+
node.traverse(nil) {|st, parent|
|
801
|
+
if st.kind_of? ECMA262::StVar and parent.kind_of? ECMA262::SourceElements
|
802
|
+
catch(:break){
|
803
|
+
idx = parent.index(st) + 1
|
804
|
+
while true
|
805
|
+
st2 = parent[idx]
|
806
|
+
if st2.kind_of? ECMA262::StEmpty or (st2.kind_of? ECMA262::StFunc and st2.decl?)
|
807
|
+
idx +=1
|
808
|
+
next
|
809
|
+
elsif st2.kind_of? ECMA262::StExp and st2.exp.kind_of? ECMA262::ExpAssign
|
810
|
+
if rewrite_var(st, st2.exp.val, st2.exp.val2)
|
811
|
+
parent.replace(st2, ECMA262::StEmpty.new())
|
812
|
+
retry_flag = true
|
813
|
+
else
|
814
|
+
throw :break
|
815
|
+
end
|
816
|
+
idx += 1
|
817
|
+
next
|
818
|
+
elsif st2.kind_of? ECMA262::StFor and st2.exp1.kind_of? ECMA262::ExpAssign
|
819
|
+
if rewrite_var(st, st2.exp1.val, st2.exp1.val2)
|
820
|
+
st2.replace(st2.exp1, nil)
|
821
|
+
retry_flag = true
|
822
|
+
else
|
823
|
+
throw :break
|
824
|
+
end
|
825
|
+
throw :break
|
826
|
+
elsif st2.kind_of? ECMA262::StExp and st2.exp.kind_of? ECMA262::ExpComma
|
827
|
+
exp_parent = st2
|
828
|
+
exp = st2.exp
|
829
|
+
|
830
|
+
while exp.val.kind_of? ECMA262::ExpComma
|
831
|
+
exp_parent = exp
|
832
|
+
exp = exp.val
|
833
|
+
end
|
834
|
+
|
835
|
+
if exp.val.kind_of? ECMA262::ExpAssign
|
836
|
+
if rewrite_var(st, exp.val.val, exp.val.val2)
|
837
|
+
exp_parent.replace(exp, exp.val2)
|
838
|
+
retry_flag = true
|
839
|
+
else
|
840
|
+
throw :break
|
841
|
+
end
|
695
842
|
else
|
696
843
|
throw :break
|
697
844
|
end
|
698
845
|
else
|
699
846
|
throw :break
|
700
847
|
end
|
701
|
-
else
|
702
|
-
throw :break
|
703
848
|
end
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
849
|
+
}
|
850
|
+
end
|
851
|
+
}
|
852
|
+
end
|
708
853
|
self
|
709
854
|
end
|
710
855
|
end
|
@@ -716,7 +861,7 @@ if $0 == __FILE__
|
|
716
861
|
argv.each do |x|
|
717
862
|
f.push(open(x.to_s).read())
|
718
863
|
end
|
719
|
-
|
720
|
-
|
721
|
-
puts
|
864
|
+
comp = Minjs::Compressor.new(:debug => false)
|
865
|
+
comp.compress(f.join("\n"))
|
866
|
+
puts comp.to_js({})
|
722
867
|
end
|