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