jtor 0.1.0-java → 0.1.1-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: ca5126acd5831041982af13ccfaa6d53a8725c6a
4
- data.tar.gz: 8e09af5305d4109c2708563b0be9c00d9ec130ab
3
+ metadata.gz: bb6efd191fb3dab0c19ebe356c3a24e5cc1f8534
4
+ data.tar.gz: c33f0bc1150ace2e5db228e055e6f04593439888
5
5
  SHA512:
6
- metadata.gz: c8fe1028b34ca30c698ee1732b6d97865ebac35b5e591dd60bfe93c60e8497d7397526099bd10a39009195bf0105329087c1e18067a7ec0a9d1a44921b89e064
7
- data.tar.gz: a44d00a8f8be8c383d3964c173256b094d4cd91f203131043b93fc96a106de9d8659cd934fa32525f6fe3dd093e448df5e34112e8583e6d1c7873fd92f7a2dbe
6
+ metadata.gz: 9629eefddac483afd218996e24ed53bf0b44d3198e4d37af1b802544dd579a9192ea15478dca39f477eb8e1019185796bc11d9cc57cebfa8e30090b11dff94e4
7
+ data.tar.gz: 295d55812f342355919eef6691d957164d868feabbed06e376de4011de1e61de3318c922488e4a2ee4e9a6496fe9d2e22def698d31c1ec08ab0f67824eba9c48
data/lib/jtor.rb CHANGED
@@ -1,6 +1,11 @@
1
+ warn 'Loading jtor in a non-JRuby interpreter' unless defined? JRUBY_VERSION
2
+
3
+ require 'java'
4
+
1
5
  require 'ext/string'
2
6
 
3
- require 'jtor/load'
7
+ require 'jtor_jars.rb'
4
8
 
9
+ require 'jtor/version'
5
10
  require 'jtor/java_parser'
6
11
  require 'jtor/translator'
@@ -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
@@ -1,53 +1,107 @@
1
- require 'java'
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.types.each { |type| translate_type(0, type) }
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 write(i_level, s)
24
- @f.puts "#{@indentator * i_level}#{s}"
36
+ def indent
37
+ @level += 1
25
38
  end
26
39
 
27
- def translate_type(i_level, type)
28
- write(i_level, "class #{type.name.to_constant_name}")
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 translate_method(i_level, name, parameters)
34
- params = if parameters.any?
35
- "(#{parameters.map { |p| p.id.name }.join(', ')})"
36
- else
37
- ''
38
- end
39
- write(i_level, "def #{name}#{params}")
40
- # TODO: Translate method body
41
- write(i_level, 'end')
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 translate_member(i_level, member)
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
- translate_method(i_level, member.name, member.parameters)
85
+ write_method(member.name, member.parameters, member.body)
48
86
  when Java::ComGithubJavaparserAstBody::ConstructorDeclaration
49
- translate_method(i_level, 'initialize', member.parameters)
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
@@ -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
@@ -0,0 +1,4 @@
1
+ module Jtor
2
+ VERSION = '0.1.1'
3
+ JTOR_STDLIB_VERSION = '0.1.1'
4
+ end
data/lib/jtor_jars.rb ADDED
@@ -0,0 +1,4 @@
1
+ # this is a generated file, to avoid over-writing it just delete this comment
2
+ require 'jar_dependencies'
3
+
4
+ require_jar( 'com.github.javaparser', 'javaparser-core', '2.3.0' )
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.0
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.1.0
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
@@ -1,4 +0,0 @@
1
- warn 'Loading jtor in a non-JRuby interpreter' unless defined? JRUBY_VERSION
2
-
3
- require 'jar-dependencies'
4
- require_jar('com.github.javaparser', 'javaparser-core', '2.1.0')