duby 0.0.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.
Files changed (77) hide show
  1. data/History.txt +8 -0
  2. data/README.txt +39 -0
  3. data/Rakefile +13 -0
  4. data/bin/duby +9 -0
  5. data/bin/dubyc +9 -0
  6. data/bin/dubyp +9 -0
  7. data/examples/README +16 -0
  8. data/examples/appengine/Rakefile +72 -0
  9. data/examples/appengine/Readme +27 -0
  10. data/examples/appengine/config.ru +7 -0
  11. data/examples/appengine/lib/duby/plugin/datastore.rb +171 -0
  12. data/examples/appengine/src/com/google/appengine/ext/duby/db/Model.duby +132 -0
  13. data/examples/appengine/src/com/ribrdb/DubyApp.duby +28 -0
  14. data/examples/appengine/src/com/ribrdb/list.dhtml +15 -0
  15. data/examples/construction.duby +8 -0
  16. data/examples/edb.duby +3 -0
  17. data/examples/fib.duby +24 -0
  18. data/examples/fields.duby +22 -0
  19. data/examples/fractal.duby +57 -0
  20. data/examples/java_thing.duby +13 -0
  21. data/examples/simple_class.duby +12 -0
  22. data/examples/swing.duby +20 -0
  23. data/examples/tak.duby +15 -0
  24. data/examples/test.edb +9 -0
  25. data/javalib/JRubyParser.jar +0 -0
  26. data/lib/duby.rb +168 -0
  27. data/lib/duby/ast.rb +386 -0
  28. data/lib/duby/ast/call.rb +145 -0
  29. data/lib/duby/ast/class.rb +154 -0
  30. data/lib/duby/ast/flow.rb +332 -0
  31. data/lib/duby/ast/intrinsics.rb +56 -0
  32. data/lib/duby/ast/literal.rb +97 -0
  33. data/lib/duby/ast/local.rb +92 -0
  34. data/lib/duby/ast/method.rb +244 -0
  35. data/lib/duby/ast/structure.rb +62 -0
  36. data/lib/duby/ast/type.rb +93 -0
  37. data/lib/duby/c/compiler.rb +134 -0
  38. data/lib/duby/compiler.rb +282 -0
  39. data/lib/duby/jvm/compiler.rb +766 -0
  40. data/lib/duby/jvm/method_lookup.rb +193 -0
  41. data/lib/duby/jvm/source_compiler.rb +605 -0
  42. data/lib/duby/jvm/source_generator/builder.rb +387 -0
  43. data/lib/duby/jvm/source_generator/loops.rb +110 -0
  44. data/lib/duby/jvm/source_generator/precompile.rb +170 -0
  45. data/lib/duby/jvm/source_generator/typer.rb +11 -0
  46. data/lib/duby/jvm/typer.rb +131 -0
  47. data/lib/duby/jvm/types.rb +331 -0
  48. data/lib/duby/jvm/types/basic_types.rb +19 -0
  49. data/lib/duby/jvm/types/boolean.rb +11 -0
  50. data/lib/duby/jvm/types/enumerable.rb +63 -0
  51. data/lib/duby/jvm/types/factory.rb +155 -0
  52. data/lib/duby/jvm/types/floats.rb +70 -0
  53. data/lib/duby/jvm/types/integers.rb +110 -0
  54. data/lib/duby/jvm/types/intrinsics.rb +230 -0
  55. data/lib/duby/jvm/types/literals.rb +82 -0
  56. data/lib/duby/jvm/types/methods.rb +381 -0
  57. data/lib/duby/jvm/types/number.rb +92 -0
  58. data/lib/duby/nbcompiler.rb +29 -0
  59. data/lib/duby/old/compiler_old.rb +845 -0
  60. data/lib/duby/old/declaration.rb +72 -0
  61. data/lib/duby/old/mapper.rb +72 -0
  62. data/lib/duby/old/signature.rb +52 -0
  63. data/lib/duby/old/typer_old.rb +163 -0
  64. data/lib/duby/plugin/edb.rb +25 -0
  65. data/lib/duby/plugin/java.rb +42 -0
  66. data/lib/duby/plugin/math.rb +84 -0
  67. data/lib/duby/transform.rb +1028 -0
  68. data/lib/duby/typer.rb +369 -0
  69. data/test/TestUser.class +0 -0
  70. data/test/test_ast.rb +391 -0
  71. data/test/test_compilation.rb +98 -0
  72. data/test/test_java_typer.rb +199 -0
  73. data/test/test_javac_compiler.rb +58 -0
  74. data/test/test_jvm_compiler.rb +1770 -0
  75. data/test/test_math_plugin.rb +87 -0
  76. data/test/test_typer.rb +246 -0
  77. metadata +156 -0
@@ -0,0 +1,145 @@
1
+ require 'delegate'
2
+
3
+ module Duby::AST
4
+ class NodeProxy < DelegateClass(Node)
5
+ def __inline__(node)
6
+ node.parent = parent
7
+ __setobj__(node)
8
+ end
9
+ end
10
+
11
+ class FunctionalCall < Node
12
+ include Named
13
+ attr_accessor :parameters, :block, :cast, :inlined, :proxy
14
+ alias cast? cast
15
+
16
+ def self.new(*args, &block)
17
+ real_node = super
18
+ real_node.proxy = NodeProxy.new(real_node)
19
+ end
20
+
21
+ def initialize(parent, line_number, name, &kids)
22
+ super(parent, line_number, &kids)
23
+ @parameters, @block = children
24
+ @name = name
25
+ @cast = false
26
+ end
27
+
28
+ def infer(typer)
29
+ @self_type ||= typer.self_type
30
+
31
+ unless @inferred_type
32
+ receiver_type = @self_type
33
+ should_defer = false
34
+
35
+ parameter_types = parameters.map do |param|
36
+ typer.infer(param) || should_defer = true
37
+ end
38
+
39
+ parameter_types << Duby::AST.block_type if @block
40
+
41
+ unless should_defer
42
+ if parameters.size == 1 && typer.known_types[name]
43
+ # cast operation
44
+ resolved!
45
+ self.cast = true
46
+ @inferred_type = typer.known_types[name]
47
+ else
48
+ @inferred_type = typer.method_type(receiver_type, name,
49
+ parameter_types)
50
+ if @inferred_type.kind_of? InlineCode
51
+ @inlined = @inferred_type.inline(typer.transformer, self)
52
+ proxy.__inline__(@inlined)
53
+ return proxy.infer(typer)
54
+ end
55
+ end
56
+ end
57
+
58
+ @inferred_type ? resolved! : typer.defer(proxy)
59
+ end
60
+
61
+ @inferred_type
62
+ end
63
+ end
64
+
65
+ class Call < Node
66
+ include Named
67
+ attr_accessor :target, :parameters, :block, :inlined, :proxy
68
+
69
+ def self.new(*args, &block)
70
+ real_node = super
71
+ real_node.proxy = NodeProxy.new(real_node)
72
+ end
73
+
74
+ def initialize(parent, line_number, name, &kids)
75
+ super(parent, line_number, children, &kids)
76
+ @target, @parameters, @block = children
77
+ @name = name
78
+ end
79
+
80
+ def infer(typer)
81
+ unless @inferred_type
82
+ receiver_type = typer.infer(target)
83
+ should_defer = receiver_type.nil?
84
+ parameter_types = parameters.map do |param|
85
+ typer.infer(param) || should_defer = true
86
+ end
87
+
88
+ parameter_types << Duby::AST.block_type if @block
89
+
90
+ unless should_defer
91
+ @inferred_type = typer.method_type(receiver_type, name,
92
+ parameter_types)
93
+ if @inferred_type.kind_of? InlineCode
94
+ @inlined = @inferred_type.inline(typer.transformer, self)
95
+ proxy.__inline__(@inlined)
96
+ return proxy.infer(typer)
97
+ end
98
+ end
99
+
100
+ @inferred_type ? resolved! : typer.defer(proxy)
101
+ end
102
+
103
+ @inferred_type
104
+ end
105
+ end
106
+
107
+ class Super < Node
108
+ include Named
109
+ attr_accessor :parameters, :method, :cast
110
+ alias :cast? :cast
111
+
112
+ def initialize(parent, line_number)
113
+ super(parent, line_number)
114
+ @parameters = children[0]
115
+ @call_parent = parent
116
+ @call_parent = (@call_parent = @call_parent.parent) until MethodDefinition === @call_parent
117
+ @cast = false
118
+ end
119
+
120
+ def name
121
+ @call_parent.name
122
+ end
123
+
124
+ def infer(typer)
125
+ @self_type ||= typer.self_type.superclass
126
+
127
+ unless @inferred_type
128
+ receiver_type = @call_parent.defining_class
129
+ should_defer = receiver_type.nil?
130
+ parameter_types = parameters.map do |param|
131
+ typer.infer(param) || should_defer = true
132
+ end
133
+
134
+ unless should_defer
135
+ @inferred_type = typer.method_type(receiver_type, name,
136
+ parameter_types)
137
+ end
138
+
139
+ @inferred_type ? resolved! : typer.defer(self)
140
+ end
141
+
142
+ @inferred_type
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,154 @@
1
+ module Duby::AST
2
+ class ClassDefinition < Node
3
+ include Annotated
4
+ include Named
5
+ include Scope
6
+ attr_accessor :superclass, :body, :interfaces
7
+
8
+ def initialize(parent, line_number, name, annotations=[], &block)
9
+ @annotations = annotations
10
+ @interfaces = []
11
+ @name = name
12
+ if Duby::AST.type_factory.respond_to? :declare_type
13
+ Duby::AST.type_factory.declare_type(self)
14
+ end
15
+ super(parent, line_number, &block)
16
+ @superclass, @body = children
17
+ end
18
+
19
+ def infer(typer)
20
+ unless resolved?
21
+ @inferred_type ||= typer.define_type(name, superclass, @interfaces) do
22
+ if body
23
+ typer.infer(body)
24
+ else
25
+ typer.no_type
26
+ end
27
+ end
28
+ @inferred_type ? resolved! : typer.defer(self)
29
+ end
30
+
31
+ @inferred_type
32
+ end
33
+
34
+ def implements(*types)
35
+ raise ArgumentError if types.any? {|x| x.nil?}
36
+ @interfaces.concat types
37
+ end
38
+ end
39
+
40
+ defmacro('implements') do |transformer, fcall, parent|
41
+ interfaces = fcall.args_node.child_nodes.map do |interface|
42
+ interface.type_reference(parent)
43
+ end
44
+ parent.parent.implements(*interfaces)
45
+ Noop.new(parent, fcall.position)
46
+ end
47
+
48
+ class InterfaceDeclaration < ClassDefinition
49
+ attr_accessor :superclass, :body, :interfaces
50
+
51
+ def initialize(parent, line_number, name, annotations)
52
+ super(parent, line_number, name, annotations) {|p| }
53
+ @interfaces = []
54
+ @name = name
55
+ @children = yield(self)
56
+ @interfaces, @body = children
57
+ end
58
+ end
59
+
60
+ defmacro('interface') do |transformer, fcall, parent|
61
+ raise "Interface name required" unless fcall.args_node
62
+ interfaces = fcall.args_node.child_nodes.to_a
63
+ interface_name = interfaces.shift
64
+ if (JRubyAst::CallNode === interface_name &&
65
+ interface_name.args_node.size == 1)
66
+ interfaces.unshift(interface_name.args_node.get(0))
67
+ interface_name = interface_name.receiver_node
68
+ end
69
+ raise 'Interface body required' unless fcall.iter_node
70
+ InterfaceDeclaration.new(parent, fcall.position,
71
+ interface_name.name,
72
+ transformer.annotations) do |interface|
73
+ [interfaces.map {|p| p.type_reference(interface)},
74
+ if fcall.iter_node.body_node
75
+ transformer.transform(fcall.iter_node.body_node, interface)
76
+ end
77
+ ]
78
+ end
79
+ end
80
+
81
+ class FieldDeclaration < Node
82
+ include Annotated
83
+ include Named
84
+ include ClassScoped
85
+ include Typed
86
+
87
+ def initialize(parent, line_number, name, annotations=[], &block)
88
+ @annotations = annotations
89
+ super(parent, line_number, &block)
90
+ @name = name
91
+ @type = children[0]
92
+ end
93
+
94
+ def infer(typer)
95
+ unless resolved?
96
+ resolved!
97
+ @inferred_type = typer.known_types[type]
98
+ if @inferred_type
99
+ resolved!
100
+ typer.learn_field_type(scope, name, @inferred_type)
101
+ else
102
+ typer.defer(self)
103
+ end
104
+ end
105
+ @inferred_type
106
+ end
107
+ end
108
+
109
+ class FieldAssignment < Node
110
+ include Annotated
111
+ include Named
112
+ include Valued
113
+ include ClassScoped
114
+
115
+ def initialize(parent, line_number, name, annotations=[], &block)
116
+ @annotations = annotations
117
+ super(parent, line_number, &block)
118
+ @value = children[0]
119
+ @name = name
120
+ end
121
+
122
+ def infer(typer)
123
+ unless resolved?
124
+ @inferred_type = typer.learn_field_type(scope, name, typer.infer(value))
125
+
126
+ @inferred_type ? resolved! : typer.defer(self)
127
+ end
128
+
129
+ @inferred_type
130
+ end
131
+ end
132
+
133
+ class Field < Node
134
+ include Annotated
135
+ include Named
136
+ include ClassScoped
137
+
138
+ def initialize(parent, line_number, name, annotations=[], &block)
139
+ @annotations = annotations
140
+ super(parent, line_number, &block)
141
+ @name = name
142
+ end
143
+
144
+ def infer(typer)
145
+ unless resolved?
146
+ @inferred_type = typer.field_type(scope, name)
147
+
148
+ @inferred_type ? resolved! : typer.defer(self)
149
+ end
150
+
151
+ @inferred_type
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,332 @@
1
+ module Duby
2
+ module AST
3
+ class Condition < Node
4
+ attr_accessor :predicate
5
+
6
+ def initialize(parent, line_number, &block)
7
+ super(parent, line_number, &block)
8
+ @predicate = children[0]
9
+ end
10
+
11
+ def infer(typer)
12
+ unless resolved?
13
+ @inferred_type = typer.infer(predicate)
14
+ if @inferred_type && !@inferred_type.primitive?
15
+ call = Call.new(parent, position, '!=') do |call|
16
+ @predicate.parent = call
17
+ [@predicate, [Null.new(call, position)]]
18
+ end
19
+ @predicate = children[0] = call
20
+ @inferred_type = typer.infer(predicate)
21
+ end
22
+
23
+ @inferred_type ? resolved! : typer.defer(self)
24
+ end
25
+
26
+ @inferred_type
27
+ end
28
+ end
29
+
30
+ class If < Node
31
+ attr_accessor :condition, :body, :else
32
+
33
+ def initialize(parent, line_number, &block)
34
+ super(parent, line_number, &block)
35
+ @condition, @body, @else = children
36
+ end
37
+
38
+ def infer(typer)
39
+ unless resolved?
40
+ condition_type = typer.infer(condition)
41
+ unless condition_type
42
+ typer.defer(condition)
43
+ end
44
+
45
+ # condition type is unrelated to body types, so we proceed with bodies
46
+ then_type = typer.infer(body) if body
47
+
48
+ if !then_type
49
+ # attempt to determine else branch
50
+ if self.else
51
+ else_type = typer.infer(self.else)
52
+
53
+ if !else_type
54
+ # we have neither type, defer until later
55
+ typer.defer(self)
56
+ else
57
+ # we have else but not then, defer only then and use else type for now
58
+ @inferred_type = else_type
59
+ typer.defer(self)
60
+ end
61
+ else
62
+ # no then type could be inferred and no else body, defer for now
63
+ typer.defer(self)
64
+ end
65
+ else
66
+ if self.else
67
+ else_type = typer.infer(self.else)
68
+
69
+ if !else_type
70
+ # we determined a then type, so we use that and defer the else body
71
+ @inferred_type = then_type
72
+ typer.defer(self)
73
+ else
74
+ # both then and else inferred, ensure they're compatible
75
+ if then_type.compatible?(else_type)
76
+ # types are compatible...if condition is resolved, we're done
77
+ @inferred_type = then_type.narrow(else_type)
78
+ resolved! if condition_type
79
+ else
80
+ raise Typer::InferenceError.new("if statement with incompatible result types")
81
+ end
82
+ end
83
+ else
84
+ # only then and type inferred, we're 100% resolved
85
+ @inferred_type = then_type
86
+ resolved! if condition_type
87
+ end
88
+ end
89
+ end
90
+
91
+ @inferred_type
92
+ end
93
+ end
94
+
95
+ class Loop < Node
96
+ attr_accessor :init, :condition, :pre, :post, :body
97
+ attr_accessor :check_first, :negative, :redo
98
+
99
+ def initialize(parent, position, check_first, negative, &block)
100
+ @check_first = check_first
101
+ @negative = negative
102
+ @init = Body.new(self, position)
103
+ @pre = Body.new(self, position)
104
+ @post = Body.new(self, position)
105
+ super(parent, position, &block)
106
+ @condition, @body = @children
107
+ end
108
+
109
+ def infer(typer)
110
+ unless resolved?
111
+ child_types = children.map do |c|
112
+ if c.nil? || (Body === c && c.empty?)
113
+ typer.no_type
114
+ else
115
+ typer.infer(c)
116
+ end
117
+ end
118
+ if child_types.any? {|t| t.nil?}
119
+ typer.defer(self)
120
+ else
121
+ resolved!
122
+ @inferred_type = typer.null_type
123
+ end
124
+ end
125
+
126
+ @inferred_type
127
+ end
128
+
129
+ def children
130
+ [init, condition, pre, post, body]
131
+ end
132
+
133
+ def check_first?; @check_first; end
134
+ def negative?; @negative; end
135
+
136
+ def redo?
137
+ if @redo.nil?
138
+ nodes = @children.dup
139
+ until nodes.empty?
140
+ node = nodes.shift
141
+ while node.respond_to?(:inlined) && node.inlined
142
+ node = node.inlined
143
+ end
144
+ next if node.nil? || Loop === node
145
+ if Redo === node
146
+ return @redo = true
147
+ end
148
+ nodes.insert(-1, *node.children.flatten)
149
+ end
150
+ return @redo = false
151
+ else
152
+ @redo
153
+ end
154
+ end
155
+
156
+ def init?
157
+ @init && !(@init.kind_of?(Body) && @init.empty?)
158
+ end
159
+
160
+ def pre?
161
+ @pre && !(@pre.kind_of?(Body) && @pre.empty?)
162
+ end
163
+
164
+ def post?
165
+ @post && !(@post.kind_of?(Body) && @post.empty?)
166
+ end
167
+
168
+ def to_s
169
+ "Loop(check_first = #{check_first?}, negative = #{negative?})"
170
+ end
171
+ end
172
+
173
+ class Not < Node
174
+ def initialize(parent, line_number, &block)
175
+ super(parent, line_number, &block)
176
+ end
177
+ end
178
+
179
+ class Return < Node
180
+ include Valued
181
+
182
+ def initialize(parent, line_number, &block)
183
+ super(parent, line_number, &block)
184
+ @value = children[0]
185
+ end
186
+
187
+ def infer(typer)
188
+ unless resolved?
189
+ @inferred_type = typer.infer(value)
190
+
191
+ (@inferred_type && value.resolved?) ? resolved! : typer.defer(self)
192
+ end
193
+
194
+ @inferred_type
195
+ end
196
+ end
197
+
198
+ class Break < Node;
199
+ def infer(typer)
200
+ unless resolved?
201
+ resolved!
202
+ @inferred_type = typer.null_type
203
+ end
204
+ end
205
+ end
206
+
207
+ class Next < Break; end
208
+
209
+ class Redo < Break; end
210
+
211
+ class Raise < Node
212
+ include Valued
213
+
214
+ def initialize(parent, line_number, &block)
215
+ super(parent, line_number, &block)
216
+ end
217
+
218
+ def infer(typer)
219
+ unless resolved?
220
+ @inferred_type = AST.unreachable_type
221
+ throwable = AST.type('java.lang.Throwable')
222
+ if children.size == 1
223
+ arg_type = typer.infer(children[0])
224
+ unless arg_type
225
+ typer.defer(self)
226
+ return
227
+ end
228
+ if throwable.assignable_from?(arg_type) && !arg_type.meta?
229
+ @exception = children[0]
230
+ resolved!
231
+ return @inferred_type
232
+ end
233
+ end
234
+
235
+ arg_types = children.map {|c| typer.infer(c)}
236
+ if arg_types.any? {|c| c.nil?}
237
+ typer.defer(self)
238
+ else
239
+ if arg_types[0] && throwable.assignable_from?(arg_types[0])
240
+ klass = children.shift
241
+ else
242
+ klass = Constant.new(self, position, 'RuntimeException')
243
+ end
244
+ @exception = Call.new(self, position, 'new') do
245
+ [klass, children, nil]
246
+ end
247
+ resolved!
248
+ @children = [@exception]
249
+ typer.infer(@exception)
250
+ end
251
+ end
252
+ @inferred_type
253
+ end
254
+ end
255
+
256
+ defmacro('raise') do |transformer, fcall, parent|
257
+ Raise.new(parent, fcall.position) do |raise_node|
258
+ if fcall.args_node
259
+ fcall.args_node.child_nodes.map do |arg|
260
+ transformer.transform(arg, raise_node)
261
+ end
262
+ end
263
+ end
264
+ end
265
+
266
+ class RescueClause < Node
267
+ include Scoped
268
+ attr_accessor :types, :body, :name, :type
269
+
270
+ def initialize(parent, position, &block)
271
+ super(parent, position, &block)
272
+ @types, @body = children
273
+ end
274
+
275
+ def infer(typer)
276
+ unless resolved?
277
+ if name
278
+ orig_type = typer.local_type(scope, name)
279
+ # TODO find the common parent Throwable
280
+ @type = types.size == 1 ? types[0] : AST.type('java.lang.Throwable')
281
+ typer.learn_local_type(scope, name, @type)
282
+ end
283
+ @inferred_type = typer.infer(body)
284
+
285
+ (@inferred_type && body.resolved?) ? resolved! : typer.defer(self)
286
+ typer.local_type_hash(scope)[name] = orig_type if name
287
+ end
288
+
289
+ @inferred_type
290
+ end
291
+ end
292
+
293
+ class Rescue < Node
294
+ attr_accessor :body, :clauses
295
+ def initialize(parent, position, &block)
296
+ super(parent, position, &block)
297
+ @body, @clauses = children
298
+ end
299
+
300
+ def infer(typer)
301
+ unless resolved?
302
+ types = [typer.infer(body)] + clauses.map {|c| typer.infer(c)}
303
+ if types.any? {|t| t.nil?}
304
+ typer.defer(self)
305
+ else
306
+ # TODO check types for compatibility (maybe only if an expression)
307
+ resolved!
308
+ @inferred_type = types[0]
309
+ end
310
+ end
311
+ @inferred_type
312
+ end
313
+ end
314
+
315
+ class Ensure < Node
316
+ attr_reader :body, :clause
317
+ attr_accessor :state # Used by the some compilers.
318
+
319
+ def initialize(parent, position, &block)
320
+ super(parent, position, &block)
321
+ @body, @clause = children
322
+ end
323
+
324
+ def infer(typer)
325
+ resolve_if(typer) do
326
+ typer.infer(clause)
327
+ typer.infer(body)
328
+ end
329
+ end
330
+ end
331
+ end
332
+ end