diff --git a/lib/coffee_script/nodes.rb b/lib/coffee_script/nodes.rb index c446a601..f462336a 100644 --- a/lib/coffee_script/nodes.rb +++ b/lib/coffee_script/nodes.rb @@ -24,6 +24,12 @@ module CoffeeScript class_eval "def statement_only?; true; end" end + # This node needs to know if it's being compiled as a top-level statement, + # in order to compile without special expression conversion. + def self.top_sensitive + class_eval "def top_sensitive?; true; end" + end + # Provide a quick implementation of a children method. def self.children(*attributes) attr_reader(*attributes) @@ -474,6 +480,7 @@ module CoffeeScript # Setting the value of a local variable, or the value of an object property. class AssignNode < Node + top_sensitive children :variable, :value PROTO_ASSIGN = /\A(\S+)\.prototype/ @@ -484,6 +491,7 @@ module CoffeeScript end def compile_node(o) + top = o.delete(:top) return compile_pattern_match(o) if statement? return compile_splice(o) if value? && @variable.splice? stmt = o.delete(:as_statement) @@ -498,7 +506,9 @@ module CoffeeScript o[:scope].find(name) unless value? && @variable.properties? val = "#{name} = #{@value.compile(o)}" return write("#{idt}#{val};") if stmt - write(o[:return] ? "#{idt}return (#{val})" : val) + val = "(#{val})" if !top || o[:return] + val = "#{idt}return #{val}" if o[:return] + write(val) end def value? @@ -616,6 +626,7 @@ module CoffeeScript # A function definition. The only node that creates a new Scope. # A CodeNode does not have any children -- they're within the new scope. class CodeNode < Node + top_sensitive attr_reader :params, :body, :bound attr_accessor :name, :proto @@ -628,10 +639,6 @@ module CoffeeScript @bound = tag == :boundfunc end - def top_sensitive? - true - end - def constructor? @name && @name[0..0][UPPERCASE] end @@ -753,6 +760,7 @@ module CoffeeScript # A while loop, the only sort of low-level loop exposed by CoffeeScript. From # it, all other loops can be manufactured. class WhileNode < Node + top_sensitive children :condition, :body statement @@ -760,10 +768,6 @@ module CoffeeScript @condition, @body = condition, body end - def top_sensitive? - true - end - def compile_node(o) returns = o.delete(:return) top = o.delete(:top) && !returns @@ -787,6 +791,7 @@ module CoffeeScript # of the comprehenion. Unlike Python array comprehensions, it's able to pass # the current index of the loop as a second parameter. class ForNode < Node + top_sensitive children :body, :source, :filter attr_reader :name, :index, :step statement @@ -800,10 +805,6 @@ module CoffeeScript @name, @index = @index, @name if @object end - def top_sensitive? - true - end - def compile_node(o) top_level = o.delete(:top) && !o[:return] range = @source.is_a?(ValueNode) && @source.base.is_a?(RangeNode) && @source.properties.empty? diff --git a/test/fixtures/execution/test_assign_to_try_catch.coffee b/test/fixtures/execution/test_assign_to_try_catch.coffee deleted file mode 100644 index 9de8178f..00000000 --- a/test/fixtures/execution/test_assign_to_try_catch.coffee +++ /dev/null @@ -1,8 +0,0 @@ -result: try - nonexistent * missing -catch error - true - -result2: try nonexistent * missing catch error then true - -print(result is true and result2 is true) \ No newline at end of file diff --git a/test/fixtures/execution/test_assignment.coffee b/test/fixtures/execution/test_assignment.coffee new file mode 100644 index 00000000..550f7d5c --- /dev/null +++ b/test/fixtures/execution/test_assignment.coffee @@ -0,0 +1,23 @@ +# Assign to try/catch. + +result: try + nonexistent * missing +catch error + true + +result2: try nonexistent * missing catch error then true + +print(result is true and result2 is true) + + +# Assign to conditional. + +get_x: => 10 + +if x: get_x() then 100 + +print(x is 10) + +x: if get_x() then 100 + +print(x is 100) \ No newline at end of file