jtor 0.1.1-java → 0.1.2-java

Sign up to get free protection for your applications and to get access to all the features.
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