lib/ruby2js/converter/class2.rb in ruby2js-3.0.15 vs lib/ruby2js/converter/class2.rb in ruby2js-3.1.0

- old
+ new

@@ -31,25 +31,83 @@ begin class_name, @class_name = @class_name, name class_parent, @class_parent = @class_parent, inheritance @rbstack.push({}) + constructor = [] + index = 0 - # capture method names for automatic self referencing - body.each_with_index do |m, index| + # capture constructor, method names for automatic self referencing + body.each do |m| if m.type == :def prop = m.children.first - unless prop == :initialize or prop.to_s.end_with? '=' + if prop == :initialize + constructor = m.children[2..-1] + elsif not prop.to_s.end_with? '=' @rbstack.last[prop] = s(:self) end end end + # private variable declarations + if es2020 + ivars = Set.new + cvars = Set.new + + # find ivars and cvars + walk = proc do |ast| + ivars << ast.children.first if ast.type === :ivar + cvars << ast.children.first if ast.type === :cvar + ast.children.each do |child| + walk[child] if child.is_a? Parser::AST::Node + end + end + walk[@ast] + + # process leading initializers in constructor + while constructor.length == 1 and constructor.first.type == :begin + constructor = constructor.first.children.dup + end + + # emit additional class declarations + unless cvars.empty? + body.each do |m| + cvars.delete m.children.first if m.type == :cvasgn + end + end + cvars.to_a.sort.each do |cvar| + put(index == 0 ? @nl : @sep) + index += 1 + put 'static #' + cvar.to_s[2..-1] + end + + while constructor.length > 0 and constructor.first.type == :ivasgn + put(index == 0 ? @nl : @sep) + index += 1 + statement = constructor.shift + put '#' + put statement.children.first.to_s[1..-1] + put ' = ' + parse statement.children.last + + ivars.delete statement.children.first + end + + # emit additional instance declarations + ivars.to_a.sort.each do |ivar| + put(index == 0 ? @nl : @sep) + index += 1 + put '#' + ivar.to_s[1..-1] + end + end + + # process class definition post = [] skipped = false - body.each_with_index do |m, index| + body.each do |m| put(index == 0 ? @nl : @sep) unless skipped + index += 1 comments = comments(m) location = output_location skipped = false # intercept async definitions @@ -65,11 +123,17 @@ if m.type == :def || m.type == :async @prop = m.children.first if @prop == :initialize @prop = :constructor - m = m.updated(m.type, [@prop, *m.children[1..2]]) + + if constructor == [] or constructor == [(:super)] + skipped = true + next + end + + m = m.updated(m.type, [@prop, m.children[1], *constructor]) elsif not m.is_method? @prop = "get #{@prop}" m = m.updated(m.type, [*m.children[0..1], s(:autoreturn, m.children[2])]) elsif @prop.to_s.end_with? '=' @@ -81,11 +145,11 @@ m = m.updated(m.type, [@prop, *m.children[1..2]]) end begin @instance_method = m - parse m + parse m # unless skipped ensure @instance_method = nil end elsif @@ -141,13 +205,24 @@ skipped = true end else - skipped = true + if m.type == :cvasgn and es2020 + put 'static #'; put m.children[0].to_s[2..-1]; put ' = ' + parse m.children[1] + else + skipped = true + end if m.type == :casgn and m.children[0] == nil @rbstack.last[m.children[1]] = name + + if es2020 + put 'static '; put m.children[1].to_s; put ' = ' + parse m.children[2] + skipped = false + end elsif m.type == :alias @rbstack.last[m.children[0]] = name end end