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 +4 -4
- data/lib/jtor/expressions.rb +43 -9
- data/lib/jtor/java_parser.rb +142 -17
- data/lib/jtor/version.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb0a35641aa58e399585b02e4bd5f0107ade213b
|
4
|
+
data.tar.gz: a513aa40d6a8f46a72d6131a2f19c6398feb52e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83bbc5dd9b936d8e3d0635c650179b57e82ad54e70ea49230fe51bf3ab64c2e42e67d3b590df51c8dabd2486e549cfc441984217f6db72678eee93ff2b4f0436
|
7
|
+
data.tar.gz: 8e3eddf4b2b7f05974b3741cc8c301dc62c23cbcaef62b373163f75c19369d4d1669579dbd5321e836b4637455e7350194c85a9d9c6c02efc08750f81a7e91be
|
data/lib/jtor/expressions.rb
CHANGED
@@ -65,8 +65,12 @@ module Jtor
|
|
65
65
|
when FieldAccessExpr
|
66
66
|
scoped_expression(expr) { expr.field }
|
67
67
|
when VariableDeclarationExpr
|
68
|
-
|
69
|
-
|
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
|
-
|
88
|
-
|
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
|
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
|
-
'
|
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
|
data/lib/jtor/java_parser.rb
CHANGED
@@ -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
|
-
|
21
|
-
|
22
|
-
|
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
|
67
|
+
@f.write(indented_string(s))
|
68
|
+
@prev_write = true
|
52
69
|
end
|
53
70
|
|
54
|
-
def fputs(s)
|
55
|
-
@f.puts
|
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
|
-
|
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(
|
75
|
-
types = translate_param_types(
|
76
|
-
param_list = translate_param_list(
|
77
|
-
|
78
|
-
|
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
|
85
|
-
write_method(member
|
86
|
-
when
|
87
|
-
|
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('
|
222
|
+
fputs('include Jtor::StdLib::Base')
|
98
223
|
type.members.each { |member| translate_member(member) }
|
99
224
|
end
|
100
225
|
fputs('end')
|
data/lib/jtor/version.rb
CHANGED