edits for clarity

This commit is contained in:
Jeremy Ashkenas
2010-01-17 14:55:06 -05:00
parent 8647b54a61
commit 2d90a751f7

View File

@@ -60,7 +60,8 @@ module CoffeeScript
@indent = (o[:indent] = idt(1)) @indent = (o[:indent] = idt(1))
pass_this = !o[:closure] && contains? {|node| node.is_a?(ThisNode) } pass_this = !o[:closure] && contains? {|node| node.is_a?(ThisNode) }
param = pass_this ? '__this' : '' param = pass_this ? '__this' : ''
"(function(#{param}) {\n#{compile_node(o.merge(:return => true, :closure => true))}\n#{indent}})(#{pass_this ? 'this' : ''})" body = compile_node(o.merge(:return => true, :closure => true))
"(function(#{param}) {\n#{body}\n#{indent}})(#{pass_this ? 'this' : ''})"
end end
# Quick short method for the current indentation level, plus tabbing in. # Quick short method for the current indentation level, plus tabbing in.
@@ -254,35 +255,25 @@ module CoffeeScript
def initialize(variable, arguments=[]) def initialize(variable, arguments=[])
@variable, @arguments = variable, arguments @variable, @arguments = variable, arguments
@prefix = ''
end end
def new_instance def new_instance
@new = true @prefix = "new "
self self
end end
def super?
@variable == 'super'
end
def prefix
@new ? "new " : ''
end
def splat?
@arguments.any? {|a| a.is_a?(SplatNode) }
end
def <<(argument) def <<(argument)
@arguments << argument @arguments << argument
self
end end
# Compile a vanilla function call. # Compile a vanilla function call.
def compile_node(o) def compile_node(o)
return write(compile_splat(o)) if splat? return write(compile_splat(o)) if @arguments.any? {|a| a.is_a?(SplatNode) }
args = @arguments.map{|a| a.compile(o) }.join(', ') args = @arguments.map{|a| a.compile(o) }.join(', ')
return write(compile_super(args, o)) if super? return write(compile_super(args, o)) if @variable == 'super'
write("#{prefix}#{@variable.compile(o)}(#{args})") write("#{@prefix}#{@variable.compile(o)}(#{args})")
end end
# Compile a call against the superclass's implementation of the current function. # Compile a call against the superclass's implementation of the current function.
@@ -304,7 +295,7 @@ module CoffeeScript
code = arg.is_a?(SplatNode) ? code : "[#{code}]" code = arg.is_a?(SplatNode) ? code : "[#{code}]"
arg.equal?(@arguments.first) ? code : ".concat(#{code})" arg.equal?(@arguments.first) ? code : ".concat(#{code})"
end end
"#{prefix}#{meth}.apply(#{obj}, #{args.join('')})" "#{@prefix}#{meth}.apply(#{obj}, #{args.join('')})"
end end
# If the code generation wished to use the result of a function call # If the code generation wished to use the result of a function call
@@ -663,12 +654,13 @@ module CoffeeScript
@body.unshift(splat) @body.unshift(splat)
end end
@params.each {|id| o[:scope].parameter(id.to_s) } @params.each {|id| o[:scope].parameter(id.to_s) }
code = @body.empty? ? "" : "\n#{@body.compile_with_declarations(o)}\n" code = @body.empty? ? "" : "\n#{@body.compile_with_declarations(o)}\n"
name_part = @name ? " #{@name}" : '' name_part = @name ? " #{@name}" : ''
func = "function#{@bound ? '' : name_part}(#{@params.join(', ')}) {#{code}#{idt(@bound ? 1 : 0)}}" func = "function#{@bound ? '' : name_part}(#{@params.join(', ')}) {#{code}#{idt(@bound ? 1 : 0)}}"
func = "(#{func})" if top && !@bound func = "(#{func})" if top && !@bound
return write(func) unless @bound return write(func) unless @bound
write("(function(__this) {\n#{idt(1)}var __func = #{func};\n#{idt(1)}return (function#{name_part}() {\n#{idt(2)}return __func.apply(__this, arguments);\n#{idt(1)}});\n#{idt}})(this)") inner = "(function#{name_part}() {\n#{idt(2)}return __func.apply(__this, arguments);\n#{idt(1)}});"
write("(function(__this) {\n#{idt(1)}var __func = #{func};\n#{idt(1)}return #{inner}\n#{idt}})(this)")
end end
end end
@@ -683,7 +675,7 @@ module CoffeeScript
end end
def compile_node(o={}) def compile_node(o={})
write(@index ? compile_param(o) : compile_arg(o)) write(@index ? compile_param(o) : @name.compile(o))
end end
def compile_param(o) def compile_param(o)
@@ -691,10 +683,6 @@ module CoffeeScript
"#{@name} = Array.prototype.slice.call(arguments, #{@index})" "#{@name} = Array.prototype.slice.call(arguments, #{@index})"
end end
def compile_arg(o)
@name.compile(o)
end
def compile_value(o, name, index) def compile_value(o, name, index)
"Array.prototype.slice.call(#{name}, #{index})" "Array.prototype.slice.call(#{name}, #{index})"
end end
@@ -849,10 +837,11 @@ module CoffeeScript
if @object if @object
o[:scope].assign("__hasProp", "Object.prototype.hasOwnProperty", true) o[:scope].assign("__hasProp", "Object.prototype.hasOwnProperty", true)
body = Expressions.wrap(IfNode.new( body = Expressions.wrap(IfNode.new(
CallNode.new(ValueNode.new(LiteralNode.wrap("__hasProp"), [AccessorNode.new(Value.new('call'))]), [LiteralNode.wrap(svar), LiteralNode.wrap(ivar)]), CallNode.new(
Expressions.wrap(body), ValueNode.new(LiteralNode.wrap("__hasProp"), [AccessorNode.new(Value.new('call'))]),
nil, [LiteralNode.wrap(svar), LiteralNode.wrap(ivar)]
{:statement => true} ),
Expressions.wrap(body), nil, {:statement => true}
)) ))
end end
@@ -1010,7 +999,8 @@ module CoffeeScript
if_dent = child ? '' : idt if_dent = child ? '' : idt
com_dent = child ? idt : '' com_dent = child ? idt : ''
prefix = @comment ? @comment.compile(cond_o) + "\n#{com_dent}" : '' prefix = @comment ? @comment.compile(cond_o) + "\n#{com_dent}" : ''
if_part = "#{prefix}#{if_dent}if (#{compile_condition(cond_o)}) {\n#{Expressions.wrap(@body).compile(o)}\n#{idt}}" body = Expressions.wrap(@body).compile(o)
if_part = "#{prefix}#{if_dent}if (#{compile_condition(cond_o)}) {\n#{body}\n#{idt}}"
return if_part unless @else_body return if_part unless @else_body
else_part = chain? ? else_part = chain? ?
" else #{@else_body.compile(o.merge(:indent => idt, :chain_child => true))}" : " else #{@else_body.compile(o.merge(:indent => idt, :chain_child => true))}" :