jtor 0.1.0-java → 0.1.1-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.rb +6 -1
- data/lib/jtor/expressions.rb +182 -0
- data/lib/jtor/java_parser.rb +75 -21
- data/lib/jtor/translator.rb +9 -0
- data/lib/jtor/version.rb +4 -0
- data/lib/jtor_jars.rb +4 -0
- metadata +5 -3
- data/lib/jtor/load.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb6efd191fb3dab0c19ebe356c3a24e5cc1f8534
|
4
|
+
data.tar.gz: c33f0bc1150ace2e5db228e055e6f04593439888
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9629eefddac483afd218996e24ed53bf0b44d3198e4d37af1b802544dd579a9192ea15478dca39f477eb8e1019185796bc11d9cc57cebfa8e30090b11dff94e4
|
7
|
+
data.tar.gz: 295d55812f342355919eef6691d957164d868feabbed06e376de4011de1e61de3318c922488e4a2ee4e9a6496fe9d2e22def698d31c1ec08ab0f67824eba9c48
|
data/lib/jtor.rb
CHANGED
@@ -0,0 +1,182 @@
|
|
1
|
+
module Jtor
|
2
|
+
module Expressions
|
3
|
+
include_package 'com.github.javaparser.ast.expr'
|
4
|
+
include_package 'com.github.javaparser.ast.type'
|
5
|
+
|
6
|
+
ASSINGMENT_OPERATORS = {
|
7
|
+
assign: '=',
|
8
|
+
plus: '+=',
|
9
|
+
minus: '-=',
|
10
|
+
star: '*=',
|
11
|
+
slash: '/=',
|
12
|
+
and: '&=',
|
13
|
+
or: '|=',
|
14
|
+
xor: '^=',
|
15
|
+
rem: '%=',
|
16
|
+
lShift: '<<=',
|
17
|
+
rSignedShift: '>>=',
|
18
|
+
rUnsignedShift: '>>>='
|
19
|
+
}
|
20
|
+
|
21
|
+
UNARY_OPERATORS = {
|
22
|
+
positive: '+',
|
23
|
+
negative: '-',
|
24
|
+
preIncrement: '++',
|
25
|
+
preDecrement: '--',
|
26
|
+
not: '!',
|
27
|
+
inverse: '~',
|
28
|
+
posIncrement: '++',
|
29
|
+
posDecrement: '--'
|
30
|
+
}
|
31
|
+
|
32
|
+
BINARY_OPERATORS = {
|
33
|
+
or: '||',
|
34
|
+
and: '&&',
|
35
|
+
binOr: '|',
|
36
|
+
binAnd: '&',
|
37
|
+
xor: '^',
|
38
|
+
equals: '==',
|
39
|
+
notEquals: '!=',
|
40
|
+
less: '<',
|
41
|
+
greater: '>',
|
42
|
+
lessEquals: '<=',
|
43
|
+
greaterEquals: '>=',
|
44
|
+
lShift: '<<',
|
45
|
+
rSignedShift: '>>',
|
46
|
+
rUnsignedShift: '>>>',
|
47
|
+
plus: '+',
|
48
|
+
minus: '-',
|
49
|
+
times: '*',
|
50
|
+
divide: '/',
|
51
|
+
remainder: '%'
|
52
|
+
}
|
53
|
+
|
54
|
+
def translate_expression(expr)
|
55
|
+
case expr
|
56
|
+
when MethodCallExpr
|
57
|
+
scoped_expression(expr) do
|
58
|
+
"#{expr.name}#{translate_arguments(expr.args)}"
|
59
|
+
end
|
60
|
+
when AssignExpr
|
61
|
+
target = translate_expression(expr.target)
|
62
|
+
operator = ASSINGMENT_OPERATORS[expr.operator.to_s.to_sym]
|
63
|
+
value = translate_expression(expr.value)
|
64
|
+
"#{target} #{operator} #{value}"
|
65
|
+
when FieldAccessExpr
|
66
|
+
scoped_expression(expr) { expr.field }
|
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
|
70
|
+
when QualifiedNameExpr
|
71
|
+
"#{translate_expression(expr.qualifier)}.#{expr.name}"
|
72
|
+
when NameExpr
|
73
|
+
expr.name
|
74
|
+
when ArrayAccessExpr
|
75
|
+
"#{translate_expression(expr.name)}[#{translate_expression(expr.index)}]"
|
76
|
+
when ArrayCreationExpr
|
77
|
+
if expr.initializer
|
78
|
+
values = expr.initializer.values.map { |value| translate_expression(value) }
|
79
|
+
"[#{values.join(', ')}]"
|
80
|
+
else
|
81
|
+
"Array.new(#{expr.array_count})"
|
82
|
+
end
|
83
|
+
when UnaryExpr
|
84
|
+
op = expr.operator.to_s.to_sym
|
85
|
+
operator = UNARY_OPERATORS[op]
|
86
|
+
value = translate_expression(expr.expr)
|
87
|
+
if [:posIncrement, :posDecrement].include?(op)
|
88
|
+
"#{value}#{operator}"
|
89
|
+
else
|
90
|
+
"#{operator}#{value}"
|
91
|
+
end
|
92
|
+
when BinaryExpr
|
93
|
+
left = translate_expression(expr.left)
|
94
|
+
operator = BINARY_OPERATORS[expr.operator.to_s.to_sym]
|
95
|
+
right = translate_expression(expr.right)
|
96
|
+
"#{left} #{operator} #{right}"
|
97
|
+
when IntegerLiteralExpr
|
98
|
+
# NOTE: `IntegerLiteralExpr` is a subclass of `StringLiteralExpr`, so
|
99
|
+
# this case must be before the latter
|
100
|
+
expr.value
|
101
|
+
when StringLiteralExpr
|
102
|
+
expr.value.inspect
|
103
|
+
when BooleanLiteralExpr
|
104
|
+
expr.value
|
105
|
+
when ObjectCreationExpr
|
106
|
+
# TODO: Handle object creations with anonymous classes
|
107
|
+
scoped_expression(expr) do
|
108
|
+
type = translate_type(expr.type)
|
109
|
+
"#{type}.new#{translate_arguments(expr.args)}"
|
110
|
+
end
|
111
|
+
when InstanceOfExpr
|
112
|
+
# No `instanceof` operator in ruby, but every expression is an object
|
113
|
+
# with the `is_a?` method, which serves the same purpose. We wrap the
|
114
|
+
# expression in parenthesis just in case it's not atomic.
|
115
|
+
"(#{translate_expression(expr.expr)}).is_a?(#{translate_type(expr.type)})"
|
116
|
+
when NullLiteralExpr
|
117
|
+
'nil'
|
118
|
+
when CastExpr
|
119
|
+
# No need to cast anything :P
|
120
|
+
translate_expression(expr.expr)
|
121
|
+
when ThisExpr
|
122
|
+
# TODO: Handle class expressions on `this`
|
123
|
+
'self'
|
124
|
+
when ClassExpr
|
125
|
+
"#{translate_type(expr.type)}.class"
|
126
|
+
when EnclosedExpr
|
127
|
+
"(#{translate_expression(expr.inner)})"
|
128
|
+
when ConditionalExpr
|
129
|
+
condition = translate_expression(expr.condition)
|
130
|
+
then_expr = translate_expression(expr.then_expr)
|
131
|
+
else_expr = translate_expression(expr.else_expr)
|
132
|
+
"#{condition} ? #{then_expr} : #{else_expr}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def translate_expressions(expressions)
|
137
|
+
expressions.map { |expr| translate_expression(expr) }.join('; ')
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def translate_arguments(args)
|
143
|
+
return '' unless args
|
144
|
+
"(#{args.map { |arg| translate_expression(arg) }.join(', ')})"
|
145
|
+
end
|
146
|
+
|
147
|
+
def translate_type(type)
|
148
|
+
case type
|
149
|
+
when ClassOrInterfaceType
|
150
|
+
if type.scope
|
151
|
+
scope = type
|
152
|
+
while (scope = scope.scope)
|
153
|
+
module_string = "#{scope.name.to_constant_name}#{module_string}"
|
154
|
+
end
|
155
|
+
module_string = "Java::#{module_string}::"
|
156
|
+
end
|
157
|
+
"#{module_string}#{type.name}"
|
158
|
+
when PrimitiveType
|
159
|
+
# Mapping from
|
160
|
+
# https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby#java-to-ruby
|
161
|
+
case type.type
|
162
|
+
when PrimitiveType::Primitive::Boolean
|
163
|
+
'Java::JavaLang::Boolean'
|
164
|
+
when PrimitiveType::Primitive::Byte, PrimitiveType::Primitive::Short,
|
165
|
+
PrimitiveType::Primitive::Char, PrimitiveType::Primitive::Int,
|
166
|
+
PrimitiveType::Primitive::Long
|
167
|
+
'Fixnum'
|
168
|
+
when PrimitiveType::Primitive::Float, PrimitiveType::Primitive::Double
|
169
|
+
'Float'
|
170
|
+
end
|
171
|
+
when ReferenceType
|
172
|
+
# Integer[], String[], Float[][] all translates to Array in ruby
|
173
|
+
type.array_count == 0 ? translate_type(type.type) : 'Array'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def scoped_expression(expr)
|
178
|
+
scope = "#{translate_expression(expr.scope)}." if expr.scope
|
179
|
+
"#{scope}#{yield}"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
data/lib/jtor/java_parser.rb
CHANGED
@@ -1,53 +1,107 @@
|
|
1
|
-
|
2
|
-
require 'jbundler'
|
1
|
+
require_relative 'expressions'
|
3
2
|
|
4
3
|
java_import java.io.FileInputStream
|
5
4
|
java_import com.github.javaparser.JavaParser
|
6
5
|
|
7
6
|
module Jtor
|
8
7
|
class JavaParser
|
8
|
+
include Jtor::Expressions
|
9
|
+
|
9
10
|
attr_accessor :indentator
|
10
11
|
|
11
12
|
def initialize(f)
|
12
13
|
@indentator = ' '
|
14
|
+
@level = 0
|
13
15
|
@f = f
|
14
16
|
end
|
15
17
|
|
16
18
|
def translate(file)
|
17
19
|
parser = ::JavaParser.parse(FileInputStream.new(file))
|
18
|
-
parser.
|
20
|
+
parser.imports.each do |import|
|
21
|
+
fputs("jtor_import '#{translate_expression(import.name)}'")
|
22
|
+
end
|
23
|
+
fputs('module Java')
|
24
|
+
indented do
|
25
|
+
fputs("module #{module_name(parser.package.name)}")
|
26
|
+
indented do
|
27
|
+
parser.types.each { |type| translate_class_or_interface(type) }
|
28
|
+
end
|
29
|
+
fputs('end')
|
30
|
+
end
|
31
|
+
fputs('end')
|
19
32
|
end
|
20
33
|
|
21
34
|
private
|
22
35
|
|
23
|
-
def
|
24
|
-
@
|
36
|
+
def indent
|
37
|
+
@level += 1
|
25
38
|
end
|
26
39
|
|
27
|
-
def
|
28
|
-
|
29
|
-
type.members.each { |member| translate_member(i_level + 1, member) }
|
30
|
-
write(i_level, 'end')
|
40
|
+
def outdent
|
41
|
+
@level -= 1
|
31
42
|
end
|
32
43
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
#
|
41
|
-
|
44
|
+
def indented
|
45
|
+
indent
|
46
|
+
yield
|
47
|
+
outdent
|
48
|
+
end
|
49
|
+
|
50
|
+
def fwrite(s)
|
51
|
+
@f.write "#{@indentator * @level}#{s}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def fputs(s)
|
55
|
+
@f.puts "#{@indentator * @level}#{s}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def translate_statement(stmt)
|
59
|
+
# TODO: Translate statement
|
60
|
+
end
|
61
|
+
|
62
|
+
def translate_block_statement(block_stmt)
|
63
|
+
block_stmt.stmts.each { |stmt| translate_statement(stmt) }
|
42
64
|
end
|
43
65
|
|
44
|
-
def
|
66
|
+
def translate_param_types(params)
|
67
|
+
"[#{params.map { |p| translate_type(p.type) }.join(', ')}]"
|
68
|
+
end
|
69
|
+
|
70
|
+
def translate_param_list(params)
|
71
|
+
params.any? ? " |#{params.map { |p| p.id.name }.join(', ')}|" : ''
|
72
|
+
end
|
73
|
+
|
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
|
79
|
+
fputs('end')
|
80
|
+
end
|
81
|
+
|
82
|
+
def translate_member(member)
|
45
83
|
case member
|
46
84
|
when Java::ComGithubJavaparserAstBody::MethodDeclaration
|
47
|
-
|
85
|
+
write_method(member.name, member.parameters, member.body)
|
48
86
|
when Java::ComGithubJavaparserAstBody::ConstructorDeclaration
|
49
|
-
|
87
|
+
write_method(:initialize, member.parameters, member.block)
|
50
88
|
end
|
51
89
|
end
|
90
|
+
|
91
|
+
def translate_class_or_interface(type)
|
92
|
+
if type.extends.any?
|
93
|
+
extends = " < #{type.extends.map { |e| translate_type(e) }.join(', ')}"
|
94
|
+
end
|
95
|
+
fputs("class #{type.name.to_constant_name}#{extends}")
|
96
|
+
indented do
|
97
|
+
fputs('extend Jtor::StdLib::Base')
|
98
|
+
type.members.each { |member| translate_member(member) }
|
99
|
+
end
|
100
|
+
fputs('end')
|
101
|
+
end
|
102
|
+
|
103
|
+
def module_name(name_expr)
|
104
|
+
name_expr.name.split('.').map(&:to_constant_name).join
|
105
|
+
end
|
52
106
|
end
|
53
107
|
end
|
data/lib/jtor/translator.rb
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'erb'
|
2
3
|
|
3
4
|
module Jtor
|
4
5
|
class Translator
|
5
6
|
def self.run(src, dest)
|
7
|
+
gemfile_template = ERB.new(File.read('templates/Gemfile.erb'))
|
6
8
|
Dir.chdir(src)
|
9
|
+
# Write Gemfile
|
10
|
+
File.open(File.join(dest, 'Gemfile'), 'w') do |f|
|
11
|
+
f.puts(gemfile_template.result(binding))
|
12
|
+
end
|
13
|
+
|
14
|
+
# Translate files
|
7
15
|
Dir.glob('**/*.java').each do |file|
|
8
16
|
dest_file = File.join(dest, file.gsub(/java$/, 'rb'))
|
9
17
|
FileUtils.mkdir_p(File.dirname(dest_file))
|
10
18
|
File.open(dest_file, 'w') do |f|
|
19
|
+
f.puts("require 'jtor-stdlib'")
|
11
20
|
JavaParser.new(f).translate(File.join(src, file))
|
12
21
|
end
|
13
22
|
end
|
data/lib/jtor/version.rb
ADDED
data/lib/jtor_jars.rb
ADDED
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.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Alejandro Rodríguez
|
@@ -34,9 +34,11 @@ files:
|
|
34
34
|
- bin/jtor
|
35
35
|
- lib/ext/string.rb
|
36
36
|
- lib/jtor.rb
|
37
|
+
- lib/jtor/expressions.rb
|
37
38
|
- lib/jtor/java_parser.rb
|
38
|
-
- lib/jtor/load.rb
|
39
39
|
- lib/jtor/translator.rb
|
40
|
+
- lib/jtor/version.rb
|
41
|
+
- lib/jtor_jars.rb
|
40
42
|
homepage: https://gitlab.com/eReGeBe/jtor
|
41
43
|
licenses:
|
42
44
|
- MIT
|
@@ -56,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
58
|
- !ruby/object:Gem::Version
|
57
59
|
version: '0'
|
58
60
|
requirements:
|
59
|
-
- jar com.github.javaparser:javaparser-core, 2.
|
61
|
+
- jar com.github.javaparser:javaparser-core, 2.3.0
|
60
62
|
rubyforge_project:
|
61
63
|
rubygems_version: 2.5.0
|
62
64
|
signing_key:
|
data/lib/jtor/load.rb
DELETED