module Ruby2JS class Converter # (kwbegin # (ensure # (rescue # (send nil :a) # (resbody nil nil # (send nil :b)) nil) # (send nil :c))) handle :kwbegin do |*children| block = children.first if block.type == :ensure block, finally = block.children else finally = nil end if block and block.type == :rescue body, *recovers, otherwise = block.children raise NotImplementedError, "block else" if otherwise if recovers.any? {|recover| not recover.children[1]} raise NotImplementedError, "recover without exception variable" end var = recovers.first.children[1] if recovers.any? {|recover| recover.children[1] != var} raise NotImplementedError, "multiple recovers with different exception variables" end else body = block end output = "try {#@nl#{ parse body, :statement }#@nl}" if recovers if recovers.length == 1 and not recovers.first.children.first # single catch with no exception named output += " catch (#{ parse var }) " + "{#@nl#{ parse recovers.first.children.last, :statement }#@nl}" else output += " catch (#{ parse var }) {#@nl" first = true recovers.each do |recover| exceptions, var, recovery = recover.children if exceptions tests = exceptions.children.map do |exception| "#{ parse var} instanceof #{ parse exception }" end output += "} else " if not first first = false output += "if (#{ tests.join(' || ') }) {#@nl" else output += "} else {#@nl" end output += "#{ parse recovery, :statement }#@nl" end if recovers.last.children.first output += "} else {#{@nl}throw #{ parse var }#@nl" end output += "}#@nl}" end end output += " finally {#@nl#{ parse finally, :statement }#@nl}" if finally if recovers or finally output else parse s(:begin, *children) end end end end