jtor 0.1.1-java → 0.1.2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bb6efd191fb3dab0c19ebe356c3a24e5cc1f8534
4
- data.tar.gz: c33f0bc1150ace2e5db228e055e6f04593439888
3
+ metadata.gz: eb0a35641aa58e399585b02e4bd5f0107ade213b
4
+ data.tar.gz: a513aa40d6a8f46a72d6131a2f19c6398feb52e6
5
5
  SHA512:
6
- metadata.gz: 9629eefddac483afd218996e24ed53bf0b44d3198e4d37af1b802544dd579a9192ea15478dca39f477eb8e1019185796bc11d9cc57cebfa8e30090b11dff94e4
7
- data.tar.gz: 295d55812f342355919eef6691d957164d868feabbed06e376de4011de1e61de3318c922488e4a2ee4e9a6496fe9d2e22def698d31c1ec08ab0f67824eba9c48
6
+ metadata.gz: 83bbc5dd9b936d8e3d0635c650179b57e82ad54e70ea49230fe51bf3ab64c2e42e67d3b590df51c8dabd2486e549cfc441984217f6db72678eee93ff2b4f0436
7
+ data.tar.gz: 8e3eddf4b2b7f05974b3741cc8c301dc62c23cbcaef62b373163f75c19369d4d1669579dbd5321e836b4637455e7350194c85a9d9c6c02efc08750f81a7e91be
@@ -65,8 +65,12 @@ module Jtor
65
65
  when FieldAccessExpr
66
66
  scoped_expression(expr) { expr.field }
67
67
  when VariableDeclarationExpr
68
- # I think we don't need to do anything, but I might be missing some scoping
69
- # particularity. We'll see
68
+ expr.vars.map do |var|
69
+ # If only declaring and not assigning, we don't need to translate it
70
+ # (I think)
71
+ next unless var.init
72
+ "#{var.id} = #{translate_expression(var.init)}"
73
+ end.compact.join('; ')
70
74
  when QualifiedNameExpr
71
75
  "#{translate_expression(expr.qualifier)}.#{expr.name}"
72
76
  when NameExpr
@@ -84,8 +88,18 @@ module Jtor
84
88
  op = expr.operator.to_s.to_sym
85
89
  operator = UNARY_OPERATORS[op]
86
90
  value = translate_expression(expr.expr)
87
- if [:posIncrement, :posDecrement].include?(op)
88
- "#{value}#{operator}"
91
+ case op
92
+ when :posIncrement
93
+ # For preIncrement and preDecrement we record the old value first,
94
+ # then execute the operation and then return the old value
95
+ "(__old = #{value}; #{value} += 1; __old)"
96
+ when :posDecrement
97
+ "(__old = #{value}; #{value} -= 1; __old)"
98
+ when :preIncrement
99
+ # No ++/-- in ruby
100
+ "(#{value} += 1)"
101
+ when :preDecrement
102
+ "(#{value} -= 1)"
89
103
  else
90
104
  "#{operator}#{value}"
91
105
  end
@@ -121,6 +135,10 @@ module Jtor
121
135
  when ThisExpr
122
136
  # TODO: Handle class expressions on `this`
123
137
  'self'
138
+ when SuperExpr
139
+ # Return our trusty `sup` helper object which encapsulates super methods
140
+ # TODO: Handle class expressions on `super`
141
+ 'sup'
124
142
  when ClassExpr
125
143
  "#{translate_type(expr.type)}.class"
126
144
  when EnclosedExpr
@@ -137,13 +155,27 @@ module Jtor
137
155
  expressions.map { |expr| translate_expression(expr) }.join('; ')
138
156
  end
139
157
 
140
- private
141
-
142
158
  def translate_arguments(args)
143
- return '' unless args
159
+ return '' unless args && args.any?
144
160
  "(#{args.map { |arg| translate_expression(arg) }.join(', ')})"
145
161
  end
146
162
 
163
+ def translate_constructor_call_args(params, args)
164
+ # These arguments will be `eval`ed in Jtor::StdLib::Base. There the
165
+ # arguments are in an array called `args`. We'll translate any reference
166
+ # to a name defined in `params` to `args[i]`, where `i` is the index of
167
+ # that parameter in `params`
168
+ arguments = translate_arguments(args)
169
+ params.each_with_index do |param, index|
170
+ replacement = "\\1args[#{index}]\\2"
171
+ # Only replace unscoped names matching the param name
172
+ arguments.gsub!(/([ \(])#{param.id.name}([., \)])/, replacement)
173
+ end
174
+ arguments
175
+ end
176
+
177
+ private
178
+
147
179
  def translate_type(type)
148
180
  case type
149
181
  when ClassOrInterfaceType
@@ -152,7 +184,9 @@ module Jtor
152
184
  while (scope = scope.scope)
153
185
  module_string = "#{scope.name.to_constant_name}#{module_string}"
154
186
  end
155
- module_string = "Java::#{module_string}::"
187
+ module_string += '::'
188
+ elsif %w(Exception String Math Class Object).include?(type.name)
189
+ module_string = 'JavaLang::'
156
190
  end
157
191
  "#{module_string}#{type.name}"
158
192
  when PrimitiveType
@@ -160,7 +194,7 @@ module Jtor
160
194
  # https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby#java-to-ruby
161
195
  case type.type
162
196
  when PrimitiveType::Primitive::Boolean
163
- 'Java::JavaLang::Boolean'
197
+ 'JavaLang::Boolean'
164
198
  when PrimitiveType::Primitive::Byte, PrimitiveType::Primitive::Short,
165
199
  PrimitiveType::Primitive::Char, PrimitiveType::Primitive::Int,
166
200
  PrimitiveType::Primitive::Long
@@ -5,6 +5,9 @@ java_import com.github.javaparser.JavaParser
5
5
 
6
6
  module Jtor
7
7
  class JavaParser
8
+ include_package 'com.github.javaparser.ast.stmt'
9
+ include_package 'com.github.javaparser.ast.body'
10
+
8
11
  include Jtor::Expressions
9
12
 
10
13
  attr_accessor :indentator
@@ -17,13 +20,16 @@ module Jtor
17
20
 
18
21
  def translate(file)
19
22
  parser = ::JavaParser.parse(FileInputStream.new(file))
20
- parser.imports.each do |import|
21
- fputs("jtor_import '#{translate_expression(import.name)}'")
22
- end
23
+ # In Java, other classes on the same package are automatically accessible,
24
+ # we do that manually here.
25
+ fputs("jtor_import '#{parser.package.name}.*'")
23
26
  fputs('module Java')
24
27
  indented do
25
28
  fputs("module #{module_name(parser.package.name)}")
26
29
  indented do
30
+ parser.imports.each do |import|
31
+ fputs("jtor_import '#{translate_expression(import.name)}'")
32
+ end
27
33
  parser.types.each { |type| translate_class_or_interface(type) }
28
34
  end
29
35
  fputs('end')
@@ -47,16 +53,99 @@ module Jtor
47
53
  outdent
48
54
  end
49
55
 
56
+ def indented_string(s)
57
+ # If we last used a `write` or if the string passed is empty, we don't
58
+ # want indentation
59
+ if @prev_write || !s
60
+ s
61
+ else
62
+ "#{@indentator * @level}#{s}"
63
+ end
64
+ end
65
+
50
66
  def fwrite(s)
51
- @f.write "#{@indentator * @level}#{s}"
67
+ @f.write(indented_string(s))
68
+ @prev_write = true
52
69
  end
53
70
 
54
- def fputs(s)
55
- @f.puts "#{@indentator * @level}#{s}"
71
+ def fputs(s = nil)
72
+ @f.puts(indented_string(s))
73
+ @prev_write = false
56
74
  end
57
75
 
58
76
  def translate_statement(stmt)
59
- # TODO: Translate statement
77
+ case stmt
78
+ when BlockStmt
79
+ translate_block_statement(stmt)
80
+ when ExpressionStmt
81
+ translated_expression = translate_expression(stmt.expression)
82
+ fputs(translated_expression) if translated_expression
83
+ when IfStmt
84
+ fputs("if #{translate_expression(stmt.condition)}")
85
+ indented { translate_statement(stmt.then_stmt) }
86
+ if stmt.else_stmt
87
+ if stmt.else_stmt.is_a?(IfStmt)
88
+ fwrite('els')
89
+ translate_statement(stmt.else_stmt)
90
+ else
91
+ fputs('else')
92
+ indented { translate_statement(stmt.then_stmt) }
93
+ fputs('end')
94
+ end
95
+ else
96
+ fputs('end')
97
+ end
98
+ when TryStmt
99
+ fputs('begin')
100
+ indented { translate_block_statement(stmt.try_block) }
101
+ stmt.catchs.each do |catch_clause|
102
+ except = catch_clause.except
103
+ fputs("rescue #{except.types[0].type.name} => #{except.id.name}")
104
+ indented { translate_block_statement(catch_clause.catch_block) }
105
+ end
106
+ if stmt.finally_block
107
+ fputs('ensure')
108
+ indented { translate_block_statement(stmt.finally_block) }
109
+ end
110
+ fputs('end')
111
+ when ForStmt
112
+ fputs(translate_expressions(stmt.init)) if stmt.init.any?
113
+ fputs("while #{translate_expression(stmt.compare)} do")
114
+ indented do
115
+ translate_statement(stmt.body)
116
+ fputs(translate_expressions(stmt.update)) if stmt.update.any?
117
+ end
118
+ fputs('end')
119
+ when ForeachStmt
120
+ iterable = translate_expression(stmt.iterable)
121
+ var = stmt.variable.vars.first.id.to_s
122
+ fputs("#{iterable}.each do |#{var}|")
123
+ indented { translate_statement(stmt.body) }
124
+ fputs('end')
125
+ when ReturnStmt
126
+ "return #{translate_expression(stmt.expr)}"
127
+ when ThrowStmt
128
+ "fail #{translate_expression(stmt.expr)}"
129
+ when BreakStmt
130
+ # TODO: Handle labeled `break`s
131
+ 'break'
132
+ when ContinueStmt
133
+ # TODO: Handle labeled `continue`s
134
+ 'next'
135
+ when DoStmt
136
+ fputs('begin')
137
+ indented { translate_statement(stmt.body) }
138
+ fputs("end while #{translate_expression(stmt.condition)}")
139
+ when SwitchStmt
140
+ fputs("case #{translate_expression(stmt.selector)}")
141
+ stmt.entries.each do |entry|
142
+ fputs(entry.label ? "when #{entry.label}" : 'else')
143
+ indented do
144
+ entry.stmts.each { |stmt| translate_statement(stmt) }
145
+ end
146
+ end
147
+ fputs('end')
148
+ end
60
149
  end
61
150
 
62
151
  def translate_block_statement(block_stmt)
@@ -71,20 +160,56 @@ module Jtor
71
160
  params.any? ? " |#{params.map { |p| p.id.name }.join(', ')}|" : ''
72
161
  end
73
162
 
74
- def write_method(name, params, body)
75
- types = translate_param_types(params)
76
- param_list = translate_param_list(params)
77
- fputs("add_java_method(:#{name}, #{types}) do#{param_list}")
78
- indented { translate_block_statement(body) } if body
163
+ def write_method(method)
164
+ types = translate_param_types(method.parameters)
165
+ param_list = translate_param_list(method.parameters)
166
+ declarer_method = if ModifierSet.static?(method.modifiers)
167
+ 'add_static_java_method'
168
+ else
169
+ 'add_java_method'
170
+ end
171
+ fputs("#{declarer_method}(:#{method.name}, #{types}) do#{param_list}")
172
+ indented { translate_block_statement(method.body) } if method.body
173
+ fputs('end')
174
+ end
175
+
176
+ def write_constructor(constructor)
177
+ types = translate_param_types(constructor.parameters)
178
+ param_list = translate_param_list(constructor.parameters)
179
+ stmts = constructor.block && constructor.block.stmts
180
+ if stmts && stmts.any? && stmts.first.is_a?(ExplicitConstructorInvocationStmt)
181
+ constructor_stmt = stmts.first
182
+ stmts = stmts.size > 1 ? stmts.sub_list(1, stmts.size - 1) : []
183
+ super_call = constructor_stmt.this? ? 'initialize' : 'super'
184
+ super_call += translate_constructor_call_args(constructor.parameters,
185
+ constructor_stmt.args)
186
+ end
187
+ # Using `#` as the delimiter, as it can't appear on Java expressions
188
+ fputs("add_java_constructor(#{types}, %q##{super_call}#) do#{param_list}")
189
+ indented do
190
+ stmts.each { |stmt| translate_statement(stmt) }
191
+ end if stmts
79
192
  fputs('end')
80
193
  end
81
194
 
195
+ def write_field(field)
196
+ field.variables.each do |var|
197
+ fputs "attr_accessor :#{var.id}"
198
+ next unless var.init
199
+ fputs "add_java_initializer do"
200
+ indented { fputs "self.#{var.id} ||= #{translate_expression(var.init)}" }
201
+ fputs "end"
202
+ end
203
+ end
204
+
82
205
  def translate_member(member)
83
206
  case member
84
- when Java::ComGithubJavaparserAstBody::MethodDeclaration
85
- write_method(member.name, member.parameters, member.body)
86
- when Java::ComGithubJavaparserAstBody::ConstructorDeclaration
87
- write_method(:initialize, member.parameters, member.block)
207
+ when MethodDeclaration
208
+ write_method(member)
209
+ when ConstructorDeclaration
210
+ write_constructor(member)
211
+ when FieldDeclaration
212
+ write_field(member)
88
213
  end
89
214
  end
90
215
 
@@ -94,7 +219,7 @@ module Jtor
94
219
  end
95
220
  fputs("class #{type.name.to_constant_name}#{extends}")
96
221
  indented do
97
- fputs('extend Jtor::StdLib::Base')
222
+ fputs('include Jtor::StdLib::Base')
98
223
  type.members.each { |member| translate_member(member) }
99
224
  end
100
225
  fputs('end')
@@ -1,4 +1,4 @@
1
1
  module Jtor
2
- VERSION = '0.1.1'
3
- JTOR_STDLIB_VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
+ JTOR_STDLIB_VERSION = '0.1.5'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jtor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: java
6
6
  authors:
7
7
  - Alejandro Rodríguez