coffee-script 0.2.1 → 0.2.2
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.
- data/README +3 -0
- data/coffee-script.gemspec +2 -2
- data/examples/code.coffee +3 -3
- data/examples/poignant.coffee +3 -3
- data/examples/underscore.coffee +16 -15
- data/lib/coffee-script.rb +1 -1
- data/lib/coffee_script/CoffeeScript.tmbundle/Syntaxes/CoffeeScript.tmLanguage +9 -5
- data/lib/coffee_script/command_line.rb +12 -2
- data/lib/coffee_script/grammar.y +30 -19
- data/lib/coffee_script/lexer.rb +11 -9
- data/lib/coffee_script/narwhal/coffee-script.coffee +5 -5
- data/lib/coffee_script/narwhal/lib/coffee-script.js +15 -15
- data/lib/coffee_script/narwhal/lib/coffee-script/loader.js +2 -2
- data/lib/coffee_script/nodes.rb +114 -72
- data/lib/coffee_script/parser.rb +1128 -1063
- data/lib/coffee_script/rewriter.rb +4 -0
- data/lib/coffee_script/value.rb +1 -1
- data/package.json +1 -1
- metadata +2 -3
- data/lib/coffee_script/parser.output +0 -11407
@@ -29,7 +29,7 @@ exports.run: args =>
|
|
29
29
|
while true
|
30
30
|
try
|
31
31
|
system.stdout.write('coffee> ').flush()
|
32
|
-
result: exports.evalCS(Readline.readline())
|
32
|
+
result: exports.evalCS(Readline.readline(), ['--globals'])
|
33
33
|
print(result) if result isnt undefined
|
34
34
|
catch e
|
35
35
|
print(e)
|
@@ -41,15 +41,15 @@ exports.compileFile: path =>
|
|
41
41
|
coffee.stdout.read()
|
42
42
|
|
43
43
|
# Compile a string of CoffeeScript into JavaScript.
|
44
|
-
exports.compile: source =>
|
45
|
-
coffee: OS.popen([coffeePath, "--eval", "--no-wrap"])
|
44
|
+
exports.compile: source, flags =>
|
45
|
+
coffee: OS.popen([coffeePath, "--eval", "--no-wrap"].concat(flags or []))
|
46
46
|
coffee.stdin.write(source).flush().close()
|
47
47
|
checkForErrors(coffee)
|
48
48
|
coffee.stdout.read()
|
49
49
|
|
50
50
|
# Evaluating a string of CoffeeScript first compiles it externally.
|
51
|
-
exports.evalCS: source =>
|
52
|
-
eval(exports.compile(source))
|
51
|
+
exports.evalCS: source, flags =>
|
52
|
+
eval(exports.compile(source, flags))
|
53
53
|
|
54
54
|
# Make a factory for the CoffeeScript environment.
|
55
55
|
exports.makeNarwhalFactory: path =>
|
@@ -20,25 +20,24 @@
|
|
20
20
|
// Run a simple REPL, round-tripping to the CoffeeScript compiler for every
|
21
21
|
// command.
|
22
22
|
exports.run = function run(args) {
|
23
|
-
var __a, __b,
|
23
|
+
var __a, __b, i, result;
|
24
24
|
if (args.length) {
|
25
25
|
__a = args;
|
26
|
-
__b =
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
}
|
26
|
+
__b = function(path, i) {
|
27
|
+
exports.evalCS(File.read(path));
|
28
|
+
delete args[i];
|
29
|
+
};
|
30
|
+
if (__a instanceof Array) {
|
31
|
+
for (i=0; i<__a.length; i++) __b(__a[i], i);
|
32
|
+
} else {
|
33
|
+
for (i in __a) { if (__a.hasOwnProperty(i)) __b(__a[i], i); }
|
34
34
|
}
|
35
|
-
__b;
|
36
35
|
return true;
|
37
36
|
}
|
38
37
|
while (true) {
|
39
38
|
try {
|
40
39
|
system.stdout.write('coffee> ').flush();
|
41
|
-
result = exports.evalCS(Readline.readline());
|
40
|
+
result = exports.evalCS(Readline.readline(), ['--globals']);
|
42
41
|
if (result !== undefined) {
|
43
42
|
print(result);
|
44
43
|
}
|
@@ -46,6 +45,7 @@
|
|
46
45
|
print(e);
|
47
46
|
}
|
48
47
|
}
|
48
|
+
return null;
|
49
49
|
};
|
50
50
|
// Compile a given CoffeeScript file into JavaScript.
|
51
51
|
exports.compileFile = function compileFile(path) {
|
@@ -55,16 +55,16 @@
|
|
55
55
|
return coffee.stdout.read();
|
56
56
|
};
|
57
57
|
// Compile a string of CoffeeScript into JavaScript.
|
58
|
-
exports.compile = function compile(source) {
|
58
|
+
exports.compile = function compile(source, flags) {
|
59
59
|
var coffee;
|
60
|
-
coffee = OS.popen([coffeePath, "--eval", "--no-wrap"]);
|
60
|
+
coffee = OS.popen([coffeePath, "--eval", "--no-wrap"].concat(flags || []));
|
61
61
|
coffee.stdin.write(source).flush().close();
|
62
62
|
checkForErrors(coffee);
|
63
63
|
return coffee.stdout.read();
|
64
64
|
};
|
65
65
|
// Evaluating a string of CoffeeScript first compiles it externally.
|
66
|
-
exports.evalCS = function evalCS(source) {
|
67
|
-
return eval(exports.compile(source));
|
66
|
+
exports.evalCS = function evalCS(source, flags) {
|
67
|
+
return eval(exports.compile(source, flags));
|
68
68
|
};
|
69
69
|
// Make a factory for the CoffeeScript environment.
|
70
70
|
exports.makeNarwhalFactory = function makeNarwhalFactory(path) {
|
@@ -8,9 +8,9 @@
|
|
8
8
|
// Reload the coffee-script environment from source.
|
9
9
|
reload: function reload(topId, path) {
|
10
10
|
coffeescript = coffeescript || require('coffee-script');
|
11
|
-
return
|
11
|
+
return factories[topId] = function() {
|
12
12
|
return coffeescript.makeNarwhalFactory(path);
|
13
|
-
}
|
13
|
+
};
|
14
14
|
},
|
15
15
|
// Ensure that the coffee-script environment is loaded.
|
16
16
|
load: function load(topId, path) {
|
data/lib/coffee_script/nodes.rb
CHANGED
@@ -29,6 +29,7 @@ module CoffeeScript
|
|
29
29
|
# already been asked to return the result.
|
30
30
|
def compile(o={})
|
31
31
|
@options = o.dup
|
32
|
+
@indent = o[:indent]
|
32
33
|
top = self.is_a?(ForNode) ? @options[:top] : @options.delete(:top)
|
33
34
|
closure = statement? && !statement_only? && !top && !@options[:return]
|
34
35
|
closure ? compile_closure(@options) : compile_node(@options)
|
@@ -36,10 +37,15 @@ module CoffeeScript
|
|
36
37
|
|
37
38
|
def compile_closure(o={})
|
38
39
|
indent = o[:indent]
|
39
|
-
o[:indent]
|
40
|
+
@indent = (o[:indent] = idt(1))
|
40
41
|
"(function() {\n#{compile_node(o.merge(:return => true))}\n#{indent}})()"
|
41
42
|
end
|
42
43
|
|
44
|
+
# Quick method for the current indentation level, plus tabs out.
|
45
|
+
def idt(tabs=0)
|
46
|
+
@indent + (TAB * tabs)
|
47
|
+
end
|
48
|
+
|
43
49
|
# Default implementations of the common node methods.
|
44
50
|
def unwrap; self; end
|
45
51
|
def statement?; false; end
|
@@ -95,16 +101,22 @@ module CoffeeScript
|
|
95
101
|
def compile_node(options={})
|
96
102
|
compiled = @expressions.map do |node|
|
97
103
|
o = options.dup
|
104
|
+
@indent = o[:indent]
|
98
105
|
returns = o.delete(:return)
|
99
106
|
if last?(node) && returns && !node.statement_only?
|
100
107
|
if node.statement?
|
101
108
|
node.compile(o.merge(:return => true))
|
102
109
|
else
|
103
|
-
|
110
|
+
if o[:top] && o[:last_assign] && o[:last_assign][0..0][/[A-Z]/]
|
111
|
+
temp = o[:scope].free_variable
|
112
|
+
"#{idt}#{temp} = #{node.compile(o)};\n#{idt}return #{o[:last_assign]} === this.constructor ? this : #{temp};"
|
113
|
+
else
|
114
|
+
"#{idt}return #{node.compile(o)};"
|
115
|
+
end
|
104
116
|
end
|
105
117
|
else
|
106
118
|
ending = node.statement? ? '' : ';'
|
107
|
-
indent = node.statement? ? '' :
|
119
|
+
indent = node.statement? ? '' : idt
|
108
120
|
"#{indent}#{node.compile(o.merge(:top => true))}#{ending}"
|
109
121
|
end
|
110
122
|
end
|
@@ -114,8 +126,9 @@ module CoffeeScript
|
|
114
126
|
# If this is the top-level Expressions, wrap everything in a safety closure.
|
115
127
|
def compile_root(o={})
|
116
128
|
indent = o[:no_wrap] ? '' : TAB
|
129
|
+
@indent = indent
|
117
130
|
o.merge!(:indent => indent, :scope => Scope.new(nil, self))
|
118
|
-
code = o[:
|
131
|
+
code = o[:globals] ? compile_node(o) : compile_with_declarations(o)
|
119
132
|
code.gsub!(STRIP_TRAILING_WHITESPACE, '')
|
120
133
|
o[:no_wrap] ? code : "(function(){\n#{code}\n})();"
|
121
134
|
end
|
@@ -123,7 +136,7 @@ module CoffeeScript
|
|
123
136
|
def compile_with_declarations(o={})
|
124
137
|
code = compile_node(o)
|
125
138
|
decls = ''
|
126
|
-
decls = "#{
|
139
|
+
decls = "#{idt}var #{o[:scope].declared_variables.join(', ')};\n" if o[:scope].declarations?(self)
|
127
140
|
decls + code
|
128
141
|
end
|
129
142
|
|
@@ -140,6 +153,10 @@ module CoffeeScript
|
|
140
153
|
|
141
154
|
attr_reader :value
|
142
155
|
|
156
|
+
def self.wrap(string)
|
157
|
+
self.new(Value.new(string))
|
158
|
+
end
|
159
|
+
|
143
160
|
def initialize(value)
|
144
161
|
@value = value
|
145
162
|
end
|
@@ -151,7 +168,7 @@ module CoffeeScript
|
|
151
168
|
|
152
169
|
def compile_node(o)
|
153
170
|
val = CONVERSIONS[@value.to_s] || @value.to_s
|
154
|
-
indent = statement? ?
|
171
|
+
indent = statement? ? idt : ''
|
155
172
|
ending = statement? ? ';' : ''
|
156
173
|
write("#{indent}#{val}#{ending}")
|
157
174
|
end
|
@@ -170,7 +187,7 @@ module CoffeeScript
|
|
170
187
|
def compile_node(o)
|
171
188
|
return write(@expression.compile(o.merge(:return => true))) if @expression.statement?
|
172
189
|
compiled = @expression.compile(o)
|
173
|
-
write(@expression.statement? ? "#{compiled}\n#{
|
190
|
+
write(@expression.statement? ? "#{compiled}\n#{idt}return null;" : "#{idt}return #{compiled};")
|
174
191
|
end
|
175
192
|
end
|
176
193
|
|
@@ -184,7 +201,7 @@ module CoffeeScript
|
|
184
201
|
end
|
185
202
|
|
186
203
|
def compile_node(o={})
|
187
|
-
delimiter = "\n#{
|
204
|
+
delimiter = "\n#{idt}//"
|
188
205
|
comment = "#{delimiter}#{@lines.join(delimiter)}"
|
189
206
|
write(comment)
|
190
207
|
end
|
@@ -231,7 +248,9 @@ module CoffeeScript
|
|
231
248
|
def compile_super(args, o)
|
232
249
|
methname = o[:last_assign]
|
233
250
|
arg_part = args.empty? ? '' : ", #{args}"
|
234
|
-
"#{o[:proto_assign]}.__superClass__.#{methname}
|
251
|
+
meth = o[:proto_assign] ? "#{o[:proto_assign]}.__superClass__.#{methname}" :
|
252
|
+
"#{methname}.__superClass__.constructor"
|
253
|
+
"#{meth}.call(this#{arg_part})"
|
235
254
|
end
|
236
255
|
|
237
256
|
def compile_splat(o)
|
@@ -257,9 +276,12 @@ module CoffeeScript
|
|
257
276
|
end
|
258
277
|
|
259
278
|
def compile_node(o={})
|
279
|
+
constructor = o[:scope].free_variable
|
260
280
|
sub, sup = @sub_object.compile(o), @super_object.compile(o)
|
261
|
-
"#{
|
262
|
-
"#{
|
281
|
+
"#{idt}#{constructor} = function(){};\n#{idt}" +
|
282
|
+
"#{constructor}.prototype = #{sup}.prototype;\n#{idt}" +
|
283
|
+
"#{sub}.__superClass__ = #{sup}.prototype;\n#{idt}" +
|
284
|
+
"#{sub}.prototype = new #{constructor}();\n#{idt}" +
|
263
285
|
"#{sub}.prototype.constructor = #{sub};"
|
264
286
|
end
|
265
287
|
|
@@ -302,12 +324,13 @@ module CoffeeScript
|
|
302
324
|
class AccessorNode < Node
|
303
325
|
attr_reader :name
|
304
326
|
|
305
|
-
def initialize(name)
|
306
|
-
@name = name
|
327
|
+
def initialize(name, prototype=false)
|
328
|
+
@name, @prototype = name, prototype
|
307
329
|
end
|
308
330
|
|
309
331
|
def compile_node(o)
|
310
|
-
|
332
|
+
proto = @prototype ? "prototype." : ''
|
333
|
+
write(".#{proto}#{@name}")
|
311
334
|
end
|
312
335
|
end
|
313
336
|
|
@@ -346,15 +369,15 @@ module CoffeeScript
|
|
346
369
|
end
|
347
370
|
|
348
371
|
def compile_variables(o)
|
349
|
-
|
372
|
+
@indent = o[:indent]
|
350
373
|
@from_var, @to_var = o[:scope].free_variable, o[:scope].free_variable
|
351
374
|
from_val, to_val = @from.compile(o), @to.compile(o)
|
352
|
-
write("#{
|
375
|
+
write("#{@from_var} = #{from_val}; #{@to_var} = #{to_val};\n#{idt}")
|
353
376
|
end
|
354
377
|
|
355
378
|
def compile_node(o)
|
356
379
|
idx, step = o.delete(:index), o.delete(:step)
|
357
|
-
|
380
|
+
return compile_array(o) unless idx
|
358
381
|
vars = "#{idx}=#{@from_var}"
|
359
382
|
step = step ? step.compile(o) : '1'
|
360
383
|
compare = "(#{@from_var} <= #{@to_var} ? #{idx} #{less_operator} #{@to_var} : #{idx} #{greater_operator} #{@to_var})"
|
@@ -362,6 +385,15 @@ module CoffeeScript
|
|
362
385
|
write("#{vars}; #{compare}; #{incr}")
|
363
386
|
end
|
364
387
|
|
388
|
+
# Expand the range into the equivalent array, if it's not being used as
|
389
|
+
# part of a comprehension, slice, or splice.
|
390
|
+
# TODO: This generates pretty ugly code ... shrink it.
|
391
|
+
def compile_array(o)
|
392
|
+
body = Expressions.wrap(LiteralNode.wrap('i'))
|
393
|
+
arr = Expressions.wrap(ForNode.new(body, {:source => ValueNode.new(self)}, Value.new('i')))
|
394
|
+
ParentheticalNode.new(CallNode.new(CodeNode.new([], arr))).compile(o)
|
395
|
+
end
|
396
|
+
|
365
397
|
end
|
366
398
|
|
367
399
|
# An array slice literal. Unlike JavaScript's Array#slice, the second parameter
|
@@ -385,7 +417,7 @@ module CoffeeScript
|
|
385
417
|
# Setting the value of a local variable, or the value of an object property.
|
386
418
|
class AssignNode < Node
|
387
419
|
PROTO_ASSIGN = /\A(\S+)\.prototype/
|
388
|
-
LEADING_DOT = /\A
|
420
|
+
LEADING_DOT = /\A\.(prototype\.)?/
|
389
421
|
|
390
422
|
attr_reader :variable, :value, :context
|
391
423
|
|
@@ -403,7 +435,7 @@ module CoffeeScript
|
|
403
435
|
return write("#{name}: #{@value.compile(o)}") if @context == :object
|
404
436
|
o[:scope].find(name) unless @variable.properties?
|
405
437
|
val = "#{name} = #{@value.compile(o)}"
|
406
|
-
write(o[:return] ? "#{
|
438
|
+
write(o[:return] ? "#{idt}return (#{val})" : val)
|
407
439
|
end
|
408
440
|
|
409
441
|
def compile_splice(o)
|
@@ -473,12 +505,12 @@ module CoffeeScript
|
|
473
505
|
|
474
506
|
def compile_node(o)
|
475
507
|
shared_scope = o.delete(:shared_scope)
|
476
|
-
indent = o[:indent]
|
477
508
|
o[:scope] = shared_scope || Scope.new(o[:scope], @body)
|
478
509
|
o[:return] = true
|
479
510
|
o[:top] = true
|
480
|
-
o[:indent]
|
511
|
+
o[:indent] = idt(1)
|
481
512
|
o.delete(:no_wrap)
|
513
|
+
o.delete(:globals)
|
482
514
|
name = o.delete(:immediate_assign)
|
483
515
|
if @params.last.is_a?(ParamSplatNode)
|
484
516
|
splat = @params.pop
|
@@ -488,7 +520,7 @@ module CoffeeScript
|
|
488
520
|
@params.each {|id| o[:scope].parameter(id.to_s) }
|
489
521
|
code = @body.compile_with_declarations(o)
|
490
522
|
name_part = name ? " #{name}" : ''
|
491
|
-
write("function#{name_part}(#{@params.join(', ')}) {\n#{code}\n#{
|
523
|
+
write("function#{name_part}(#{@params.join(', ')}) {\n#{code}\n#{idt}}")
|
492
524
|
end
|
493
525
|
end
|
494
526
|
|
@@ -532,18 +564,17 @@ module CoffeeScript
|
|
532
564
|
# AssignNodes get interleaved correctly, with no trailing commas or
|
533
565
|
# commas affixed to comments. TODO: Extract this and add it to ArrayNode.
|
534
566
|
def compile_node(o)
|
535
|
-
|
536
|
-
o[:indent] += TAB
|
567
|
+
o[:indent] = idt(1)
|
537
568
|
joins = Hash.new("\n")
|
538
569
|
non_comments = @properties.select {|p| !p.is_a?(CommentNode) }
|
539
570
|
non_comments.each {|p| joins[p] = p == non_comments.last ? "\n" : ",\n" }
|
540
571
|
props = @properties.map { |prop|
|
541
572
|
join = joins[prop]
|
542
573
|
join = '' if prop == @properties.last
|
543
|
-
|
544
|
-
"#{
|
574
|
+
indent = prop.is_a?(CommentNode) ? '' : idt(1)
|
575
|
+
"#{indent}#{prop.compile(o)}#{join}"
|
545
576
|
}.join('')
|
546
|
-
write("{\n#{props}\n#{
|
577
|
+
write("{\n#{props}\n#{idt}}")
|
547
578
|
end
|
548
579
|
end
|
549
580
|
|
@@ -556,14 +587,13 @@ module CoffeeScript
|
|
556
587
|
end
|
557
588
|
|
558
589
|
def compile_node(o)
|
559
|
-
|
560
|
-
o[:indent] += TAB
|
590
|
+
o[:indent] = idt(1)
|
561
591
|
objects = @objects.map { |obj|
|
562
592
|
code = obj.compile(o)
|
563
593
|
obj.is_a?(CommentNode) ? "\n#{code}\n#{o[:indent]}" :
|
564
594
|
obj == @objects.last ? code : "#{code}, "
|
565
595
|
}.join('')
|
566
|
-
ending = objects.include?("\n") ? "\n#{
|
596
|
+
ending = objects.include?("\n") ? "\n#{idt}]" : ']'
|
567
597
|
write("[#{objects}#{ending}")
|
568
598
|
end
|
569
599
|
end
|
@@ -581,12 +611,12 @@ module CoffeeScript
|
|
581
611
|
|
582
612
|
def compile_node(o)
|
583
613
|
returns = o.delete(:return)
|
584
|
-
|
585
|
-
o[:indent] += TAB
|
614
|
+
o[:indent] = idt(1)
|
586
615
|
o[:top] = true
|
587
616
|
cond = @condition.compile(o)
|
588
|
-
post = returns ? "\n#{
|
589
|
-
write("#{
|
617
|
+
post = returns ? "\n#{idt}return null;" : ''
|
618
|
+
return write("#{idt}while (#{cond}) null;#{post}") if @body.nil?
|
619
|
+
write("#{idt}while (#{cond}) {\n#{@body.compile(o)}\n#{idt}}#{post}")
|
590
620
|
end
|
591
621
|
end
|
592
622
|
|
@@ -604,56 +634,63 @@ module CoffeeScript
|
|
604
634
|
@source = source[:source]
|
605
635
|
@filter = source[:filter]
|
606
636
|
@step = source[:step]
|
637
|
+
@object = !!source[:object]
|
638
|
+
@name, @index = @index, @name if @object
|
607
639
|
end
|
608
640
|
|
609
641
|
def compile_node(o)
|
610
642
|
top_level = o.delete(:top) && !o[:return]
|
611
|
-
range = @source.is_a?(RangeNode)
|
643
|
+
range = @source.is_a?(ValueNode) && @source.literal.is_a?(RangeNode) && @source.properties.empty?
|
644
|
+
source = range ? @source.literal : @source
|
612
645
|
scope = o[:scope]
|
613
|
-
name_found = scope.find(@name)
|
646
|
+
name_found = @name && scope.find(@name)
|
614
647
|
index_found = @index && scope.find(@index)
|
648
|
+
body_dent = idt(1)
|
615
649
|
svar = scope.free_variable
|
616
650
|
ivar = range ? name : @index ? @index : scope.free_variable
|
617
651
|
rvar = scope.free_variable unless top_level
|
618
|
-
tvar = scope.free_variable
|
619
652
|
if range
|
620
|
-
body_dent = o[:indent] + TAB
|
621
|
-
var_part, pre_cond, post_cond = '', '', ''
|
622
653
|
index_var = scope.free_variable
|
623
|
-
source_part =
|
624
|
-
for_part = "#{index_var}=0, #{
|
654
|
+
source_part = source.compile_variables(o)
|
655
|
+
for_part = "#{index_var}=0, #{source.compile(o.merge(:index => ivar, :step => @step))}, #{index_var}++"
|
656
|
+
var_part = ''
|
625
657
|
else
|
626
658
|
index_var = nil
|
627
|
-
|
628
|
-
|
629
|
-
for_part = "#{ivar} in #{svar}"
|
630
|
-
|
631
|
-
var_part = "\n#{body_dent}#{@name} = #{svar}[#{ivar}];"
|
632
|
-
post_cond = "\n#{o[:indent] + TAB}}"
|
659
|
+
source_part = "#{svar} = #{source.compile(o)};\n#{idt}"
|
660
|
+
for_part = "#{ivar}=0; #{ivar}<#{svar}.length; #{ivar}++"
|
661
|
+
for_part = "#{ivar} in #{svar}" if @object
|
662
|
+
var_part = @name ? "#{body_dent}#{@name} = #{svar}[#{ivar}];\n" : ''
|
633
663
|
end
|
634
664
|
body = @body
|
635
|
-
set_result = rvar ? "#{rvar} = []
|
665
|
+
set_result = rvar ? "#{idt}#{rvar} = []; " : idt
|
636
666
|
return_result = rvar || ''
|
637
|
-
temp_var = ValueNode.new(LiteralNode.new(tvar))
|
638
667
|
if top_level
|
639
668
|
body = Expressions.wrap(body)
|
640
669
|
else
|
641
|
-
body = Expressions.wrap(
|
642
|
-
|
643
|
-
|
644
|
-
)
|
670
|
+
body = Expressions.wrap(CallNode.new(
|
671
|
+
ValueNode.new(LiteralNode.new(rvar), [AccessorNode.new('push')]), [body.unwrap]
|
672
|
+
))
|
645
673
|
end
|
646
674
|
if o[:return]
|
647
675
|
return_result = "return #{return_result}" if o[:return]
|
648
676
|
o.delete(:return)
|
649
677
|
body = IfNode.new(@filter, body, nil, :statement => true) if @filter
|
650
678
|
elsif @filter
|
651
|
-
body = Expressions.wrap(IfNode.new(@filter,
|
679
|
+
body = Expressions.wrap(IfNode.new(@filter, body))
|
680
|
+
end
|
681
|
+
if @object
|
682
|
+
body = Expressions.wrap(IfNode.new(
|
683
|
+
CallNode.new(ValueNode.new(LiteralNode.wrap(svar), [AccessorNode.new(Value.new('hasOwnProperty'))]), [LiteralNode.wrap(ivar)]),
|
684
|
+
Expressions.wrap(body),
|
685
|
+
nil,
|
686
|
+
{:statement => true}
|
687
|
+
))
|
652
688
|
end
|
653
689
|
|
654
|
-
return_result = "\n#{
|
690
|
+
return_result = "\n#{idt}#{return_result};" unless top_level
|
655
691
|
body = body.compile(o.merge(:indent => body_dent, :top => true))
|
656
|
-
|
692
|
+
vars = range ? @name : "#{@name}, #{ivar}"
|
693
|
+
return write(set_result + source_part + "for (#{for_part}) {\n#{var_part}#{body}\n#{idt}}\n#{idt}#{return_result}")
|
657
694
|
end
|
658
695
|
end
|
659
696
|
|
@@ -668,13 +705,12 @@ module CoffeeScript
|
|
668
705
|
end
|
669
706
|
|
670
707
|
def compile_node(o)
|
671
|
-
|
672
|
-
o[:indent] += TAB
|
708
|
+
o[:indent] = idt(1)
|
673
709
|
o[:top] = true
|
674
710
|
error_part = @error ? " (#{@error}) " : ' '
|
675
|
-
catch_part = @recovery && " catch#{error_part}{\n#{@recovery.compile(o)}\n#{
|
676
|
-
finally_part = @finally && " finally {\n#{@finally.compile(o.merge(:return => nil))}\n#{
|
677
|
-
write("#{
|
711
|
+
catch_part = @recovery && " catch#{error_part}{\n#{@recovery.compile(o)}\n#{idt}}"
|
712
|
+
finally_part = @finally && " finally {\n#{@finally.compile(o.merge(:return => nil))}\n#{idt}}"
|
713
|
+
write("#{idt}try {\n#{@try.compile(o)}\n#{idt}}#{catch_part}#{finally_part}")
|
678
714
|
end
|
679
715
|
end
|
680
716
|
|
@@ -689,7 +725,7 @@ module CoffeeScript
|
|
689
725
|
end
|
690
726
|
|
691
727
|
def compile_node(o)
|
692
|
-
write("#{
|
728
|
+
write("#{idt}throw #{@expression.compile(o)};")
|
693
729
|
end
|
694
730
|
end
|
695
731
|
|
@@ -746,6 +782,11 @@ module CoffeeScript
|
|
746
782
|
self
|
747
783
|
end
|
748
784
|
|
785
|
+
def add_comment(comment)
|
786
|
+
@comment = comment
|
787
|
+
self
|
788
|
+
end
|
789
|
+
|
749
790
|
def force_statement
|
750
791
|
@tags[:statement] = true
|
751
792
|
self
|
@@ -772,7 +813,7 @@ module CoffeeScript
|
|
772
813
|
# The IfNode only compiles into a statement if either of the bodies needs
|
773
814
|
# to be a statement.
|
774
815
|
def statement?
|
775
|
-
@is_statement ||= !!(@tags[:statement] || @body.statement? || (@else_body && @else_body.statement?))
|
816
|
+
@is_statement ||= !!(@comment || @tags[:statement] || @body.statement? || (@else_body && @else_body.statement?))
|
776
817
|
end
|
777
818
|
|
778
819
|
def compile_node(o)
|
@@ -782,18 +823,19 @@ module CoffeeScript
|
|
782
823
|
# Compile the IfNode as a regular if-else statement. Flattened chains
|
783
824
|
# force sub-else bodies into statement form.
|
784
825
|
def compile_statement(o)
|
785
|
-
|
786
|
-
|
787
|
-
cond_o = o.dup
|
826
|
+
child = o.delete(:chain_child)
|
827
|
+
cond_o = o.dup
|
788
828
|
cond_o.delete(:return)
|
789
|
-
o[:indent]
|
790
|
-
o[:top]
|
791
|
-
if_dent
|
792
|
-
|
829
|
+
o[:indent] = idt(1)
|
830
|
+
o[:top] = true
|
831
|
+
if_dent = child ? '' : idt
|
832
|
+
com_dent = child ? idt : ''
|
833
|
+
prefix = @comment ? @comment.compile(cond_o) + "\n#{com_dent}" : ''
|
834
|
+
if_part = "#{prefix}#{if_dent}if (#{@condition.compile(cond_o)}) {\n#{Expressions.wrap(@body).compile(o)}\n#{idt}}"
|
793
835
|
return if_part unless @else_body
|
794
836
|
else_part = chain? ?
|
795
|
-
" else #{@else_body.compile(o.merge(:indent =>
|
796
|
-
" else {\n#{Expressions.wrap(@else_body).compile(o)}\n#{
|
837
|
+
" else #{@else_body.compile(o.merge(:indent => idt, :chain_child => true))}" :
|
838
|
+
" else {\n#{Expressions.wrap(@else_body).compile(o)}\n#{idt}}"
|
797
839
|
if_part + else_part
|
798
840
|
end
|
799
841
|
|