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,369 @@
1
+ require 'duby/ast'
2
+ require 'duby/transform'
3
+
4
+ module Duby
5
+ module Typer
6
+ class << self
7
+ attr_accessor :verbose
8
+
9
+ def log(message)
10
+ puts "* [#{name}] #{message}" if Typer.verbose
11
+ end
12
+ end
13
+
14
+ class InferenceError < Exception
15
+ attr_accessor :node
16
+ def initialize(msg, node = nil)
17
+ super(msg)
18
+ @node = node
19
+ end
20
+ end
21
+
22
+ class BaseTyper
23
+ include Duby
24
+
25
+ def log(message); Typer.log(message); end
26
+
27
+ def to_s
28
+ name
29
+ end
30
+ end
31
+
32
+ class Simple < BaseTyper
33
+ attr_accessor :known_types, :errors
34
+
35
+ def initialize(self_type)
36
+ @known_types = {}
37
+
38
+ @known_types["self"] = type_reference(self_type)
39
+ @known_types["fixnum"] = type_reference("fixnum")
40
+ @known_types["float"] = type_reference("float")
41
+ @known_types["string"] = type_reference("string")
42
+ @known_types["boolean"] = type_reference("boolean")
43
+ @errors = []
44
+ end
45
+
46
+ def name
47
+ "Simple"
48
+ end
49
+
50
+ def self_type
51
+ known_types["self"]
52
+ end
53
+
54
+ def default_type
55
+ nil
56
+ end
57
+
58
+ def fixnum_type
59
+ known_types["fixnum"]
60
+ end
61
+
62
+ def float_type
63
+ known_types["float"]
64
+ end
65
+
66
+ def string_type
67
+ known_types["string"]
68
+ end
69
+
70
+ def boolean_type
71
+ known_types["boolean"]
72
+ end
73
+
74
+ def null_type
75
+ AST::TypeReference::NullType
76
+ end
77
+
78
+ def no_type
79
+ AST::TypeReference::NoType
80
+ end
81
+
82
+ # to be overridden
83
+ def array_type
84
+ AST::TypeReference::NullType
85
+ end
86
+
87
+ # to be overridden
88
+ def hash_type
89
+ AST::TypeReference::NullType
90
+ end
91
+
92
+ def define_type(name, superclass, interfaces)
93
+ log "New type defined: '#{name}' < '#{superclass}'"
94
+ known_types[name] = type_definition(name, superclass, interfaces)
95
+
96
+ old_self, known_types["self"] = known_types["self"], known_types[name]
97
+ yield
98
+ known_types["self"] = old_self
99
+
100
+ known_types[name]
101
+ end
102
+
103
+ def learn_local_type(scope, name, type)
104
+ log "Learned local type under #{scope} : #{name} = #{type}"
105
+
106
+ # TODO check for compatibility?
107
+ local_type_hash(scope)[name] ||= known_types[type] || type
108
+
109
+ type
110
+ end
111
+
112
+ def local_type(scope, name)
113
+ log "Retrieved local type in #{scope} : #{name} = #{local_type_hash(scope)[name]}"
114
+
115
+ local_type_hash(scope)[name]
116
+ end
117
+
118
+ def local_types
119
+ @local_types ||= {}
120
+ end
121
+
122
+ def local_type_hash(scope)
123
+ local_types[scope] ||= {}
124
+ end
125
+
126
+ def field_types
127
+ @field_types ||= {}
128
+ end
129
+
130
+ def field_type_hash(cls)
131
+ field_types[cls] ||= {}
132
+ end
133
+
134
+ def infer_signature(method_def)
135
+ end
136
+
137
+ def learn_field_type(cls, name, type)
138
+ log "Learned field type under #{cls} : #{name} = #{type}"
139
+
140
+ # TODO check for compatibility?
141
+ field_type_hash(cls)[name] ||= known_types[type] || type
142
+
143
+ type
144
+ end
145
+
146
+ def field_type(cls, name)
147
+ field_type_hash(cls)[name]
148
+ end
149
+
150
+ def learn_method_type(target_type, name, parameter_types, type, exceptions)
151
+ log "Learned method #{name} (#{parameter_types}) on #{target_type} = #{type}"
152
+
153
+ get_method_type_hash(target_type, name, parameter_types)[:type] = known_types[type] || type
154
+
155
+ # if it's any args are imported types, also add a mapping for the expanded name
156
+ imported_types = parameter_types.map {|param| known_types[param] || param}
157
+ get_method_type_hash(target_type, name, imported_types)[:type] = type
158
+ end
159
+
160
+ def method_type(target_type, name, parameter_types)
161
+ if (target_type && target_type.error?) ||
162
+ parameter_types.any? {|t| t && t.error?}
163
+ return AST.error_type
164
+ end
165
+ constructor = (name == 'new' && target_type && target_type.meta?)
166
+
167
+ if constructor
168
+ # constructor handled different from other methods
169
+ simple_type = get_method_type_hash(target_type.unmeta, 'initialize', parameter_types)[:type]
170
+ else
171
+ simple_type = get_method_type_hash(target_type, name, parameter_types)[:type]
172
+ end
173
+
174
+
175
+ if !simple_type
176
+ log "Method type for \"#{name}\" #{parameter_types} on #{target_type} not found."
177
+
178
+ # allow plugins a go if we're in the inference phase
179
+ simple_type = plugins do |plugin|
180
+ plugin.method_type(self, target_type, name, parameter_types)
181
+ end
182
+ end
183
+
184
+ return nil unless simple_type
185
+
186
+ if constructor
187
+ log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{target_type}"
188
+ target_type.unmeta
189
+ else
190
+ log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{simple_type}"
191
+ simple_type
192
+ end
193
+ end
194
+
195
+ def plugins
196
+ if cycling?
197
+ Duby.typer_plugins.each do |plugin|
198
+ log "Invoking plugin: #{plugin}"
199
+
200
+ result = yield plugin
201
+ return result if result
202
+ end
203
+ end
204
+
205
+ nil
206
+ end
207
+
208
+ def cycling?
209
+ @cycling
210
+ end
211
+
212
+ def cycling=(c)
213
+ @cycling = c
214
+ end
215
+
216
+ def cycle(count)
217
+ @cycling = true
218
+ count.times do |i|
219
+ begin
220
+ log "[Cycle #{i}]: Started..."
221
+ yield i
222
+ ensure
223
+ log "[Cycle #{i}]: Complete!"
224
+ end
225
+ end
226
+ ensure
227
+ @cycling = false
228
+ end
229
+
230
+ def method_types
231
+ @method_types ||= {}
232
+ end
233
+
234
+ def get_method_type_hash(target_type, name, parameter_types)
235
+ method_types[target_type] ||= {}
236
+ method_types[target_type][name] ||= {}
237
+ method_types[target_type][name][parameter_types.size] ||= {}
238
+
239
+ current = method_types[target_type][name][parameter_types.size]
240
+
241
+ parameter_types.each {|type| current[type] ||= {}; current = current[type]}
242
+
243
+ current
244
+ end
245
+
246
+ def type_reference(name, array=false, meta=false)
247
+ AST::TypeReference.new(name, array, meta)
248
+ end
249
+
250
+ def type_definition(name, superclass, interfaces)
251
+ AST::TypeDefinition.new(name, AST::TypeReference.new(superclass), interfaces)
252
+ end
253
+
254
+ def alias_type(short, long)
255
+ @known_types[type_reference(short, false, false)] = type_reference(long, false, false)
256
+ @known_types[type_reference(short, false, true)] = type_reference(long, false, true)
257
+ end
258
+
259
+ def deferred_nodes
260
+ @deferred_nodes ||= []
261
+ end
262
+
263
+ def infer(node)
264
+ begin
265
+ node.infer(self)
266
+ rescue InferenceError => ex
267
+ ex.node ||= node
268
+ error(node, ex)
269
+ rescue Exception => ex
270
+ error(node, ex.message, ex.backtrace)
271
+ end
272
+ end
273
+
274
+ def error(node, error_or_msg=nil, backtrace=nil)
275
+ if error_or_msg.kind_of? InferenceError
276
+ error = error_or_msg
277
+ elsif error_or_msg
278
+ error = InferenceError.new(error_or_msg, node)
279
+ error.set_backtrace(backtrace) if backtrace
280
+ else
281
+ error = InferenceError.new("Unable to infer type.", node)
282
+ end
283
+ @errors << error
284
+ node.resolve_if(self) do
285
+ AST.error_type
286
+ end
287
+ end
288
+
289
+ def defer(node)
290
+ if @error_next
291
+ log "Marking #{node} as an error"
292
+ @error_next = false
293
+ error(node)
294
+ else
295
+ return if deferred_nodes.include? node
296
+ log "Deferring inference for #{node}"
297
+
298
+ deferred_nodes << node
299
+ end
300
+ end
301
+
302
+ def resolve(raise = false)
303
+ count = deferred_nodes.size + 1
304
+
305
+ log "Entering type inference cycle"
306
+
307
+ retried = false
308
+ cycle(count) do |i|
309
+ old_deferred = @deferred_nodes
310
+ @deferred_nodes = deferred_nodes.select do |node|
311
+ type = infer(node)
312
+
313
+ log "[Cycle #{i}]: Inferred type for #{node}: #{type || 'FAILED'}"
314
+
315
+ type == default_type
316
+ end
317
+
318
+ if @deferred_nodes.size == 0
319
+ log "[Cycle #{i}]: Resolved all types, exiting"
320
+ break
321
+ elsif old_deferred == @deferred_nodes
322
+ if @error_next || retried
323
+ log "[Cycle #{i}]: Made no progress, bailing out"
324
+ break
325
+ else
326
+ # Retry this iteration, and mark the first deferred
327
+ # type as an error.
328
+ retried = true
329
+ @error_next = true
330
+ redo
331
+ end
332
+ end
333
+ retried = false
334
+ end
335
+
336
+ # done with n sweeps, if any remain raise errors
337
+ error_nodes = @errors.map {|e| e.node} + deferred_nodes
338
+ if raise && !error_nodes.empty?
339
+ msg = "Could not infer typing for nodes:"
340
+ error_nodes.map do |e|
341
+ msg << "\n "
342
+ msg << "#{e} at line #{e.line_number} (child of #{e.parent})"
343
+ end
344
+ raise InferenceError.new(msg)
345
+ end
346
+ end
347
+ end
348
+ end
349
+
350
+ def self.typer_plugins
351
+ @typer_plugins ||= []
352
+ end
353
+ end
354
+
355
+ if __FILE__ == $0
356
+ Duby::AST.verbose = true
357
+ Duby::Typer.verbose = true
358
+ ast = Duby::AST.parse(File.read(ARGV[0]))
359
+ typer = Duby::Typer::Simple.new("script")
360
+ typer.infer(ast)
361
+ begin
362
+ typer.resolve(true)
363
+ rescue Duby::Typer::InferenceError => e
364
+ puts e.message
365
+ end
366
+
367
+ puts "\nAST:"
368
+ p ast
369
+ end
Binary file
@@ -0,0 +1,391 @@
1
+ require 'duby'
2
+ require 'test/unit'
3
+ require 'jruby'
4
+
5
+ class TestAst < Test::Unit::TestCase
6
+ include Duby
7
+
8
+ def test_args
9
+ new_ast = AST.parse("def foo(a, *c, &d); end").body
10
+ arguments = new_ast.arguments
11
+
12
+ assert_not_nil(arguments)
13
+ inspected = "Arguments\n RequiredArgument(a)\n RestArgument(c)\n BlockArgument(d)"
14
+ assert_equal(inspected, arguments.inspect)
15
+
16
+ assert(AST::Arguments === arguments)
17
+ children = arguments.children
18
+ assert_not_nil(children)
19
+ assert_equal(4, children.size)
20
+ assert(Array === children[0])
21
+ assert(AST::RequiredArgument === children[0][0])
22
+ assert_equal("a", children[0][0].name)
23
+ assert_equal(arguments, children[0][0].parent)
24
+ assert(AST::RestArgument === children[2])
25
+ assert_equal("c", children[2].name)
26
+ assert_equal(arguments, children[2].parent)
27
+ assert(AST::BlockArgument === children[3])
28
+ assert_equal("d", children[3].name)
29
+ assert_equal(arguments, children[3].parent)
30
+ end
31
+
32
+ def test_locals
33
+ new_ast = AST.parse("a = 1; a").body
34
+
35
+ assert_not_nil(new_ast)
36
+ assert(AST::Body === new_ast)
37
+ inspected = "Body\n LocalAssignment(name = a, scope = Script, captured = false)\n Fixnum(1)\n Local(name = a, scope = Script, captured = false)"
38
+ assert_equal(inspected, new_ast.inspect)
39
+ assert(!new_ast.newline)
40
+
41
+ asgn = new_ast[0]
42
+ var = new_ast[1]
43
+
44
+ assert(AST::LocalAssignment === asgn)
45
+ assert(asgn.newline)
46
+ assert_equal("a", asgn.name)
47
+ assert(AST::Fixnum === asgn.value)
48
+ assert(!asgn.value.newline)
49
+ assert(AST::Local === var)
50
+ assert(var.newline)
51
+ assert_equal("a", var.name)
52
+ end
53
+
54
+ def test_fields
55
+ new_ast = AST.parse("@a = 1; @a").body
56
+
57
+ assert_not_nil(new_ast)
58
+ assert(AST::Body === new_ast)
59
+ inspected = "Body\n FieldAssignment(@a)\n Fixnum(1)\n Field(@a)"
60
+ assert_equal(inspected, new_ast.inspect)
61
+ assert(!new_ast.newline)
62
+
63
+ asgn = new_ast[0]
64
+ var = new_ast[1]
65
+
66
+ assert(AST::FieldAssignment === asgn)
67
+ assert(asgn.newline)
68
+ assert_equal("@a", asgn.name)
69
+ assert(AST::Fixnum === asgn.value)
70
+ assert(!asgn.value.newline)
71
+ assert(AST::Field === var)
72
+ assert(var.newline)
73
+ assert_equal("@a", var.name)
74
+ end
75
+
76
+ def test_array
77
+ new_ast = AST.parse("[a = 1, 1]").body
78
+
79
+ assert_not_nil(new_ast)
80
+ assert(AST::Array === new_ast)
81
+ assert_equal("Array\n LocalAssignment(name = a, scope = Script, captured = false)\n Fixnum(1)\n Fixnum(1)", new_ast.inspect)
82
+
83
+ assert(AST::LocalAssignment === new_ast[0])
84
+ assert(AST::Fixnum === new_ast[1])
85
+ end
86
+
87
+ def test_call
88
+ new_ast = AST.parse("1.foo(1)").body
89
+
90
+ assert_not_nil(new_ast)
91
+ assert(AST::Call === new_ast)
92
+ assert_equal("Call(foo)\n Fixnum(1)\n Fixnum(1)", new_ast.inspect)
93
+
94
+ assert_equal("foo", new_ast.name)
95
+ assert(AST::Fixnum === new_ast.target)
96
+ assert_not_nil(new_ast.parameters)
97
+ assert_equal(1, new_ast.parameters.size)
98
+ assert(AST::Fixnum === new_ast.parameters[0])
99
+ end
100
+
101
+ def test_fcall
102
+ new_ast = AST.parse("foo(1)").body
103
+
104
+ assert_not_nil(new_ast)
105
+ assert(AST::FunctionalCall === new_ast)
106
+ assert_equal("FunctionalCall(foo)\n Fixnum(1)", new_ast.inspect)
107
+
108
+ assert_equal("foo", new_ast.name)
109
+ assert_not_nil(new_ast.parameters)
110
+ assert_equal(1, new_ast.parameters.size)
111
+ assert(AST::Fixnum === new_ast.parameters[0])
112
+ end
113
+
114
+ def test_if
115
+ new_ast = AST.parse("if 1; 2; elsif !3; 4; else; 5; end").body
116
+
117
+ assert_not_nil(new_ast)
118
+ assert(AST::If === new_ast)
119
+ assert_equal("If\n Condition\n Fixnum(1)\n Fixnum(2)\n If\n Condition\n Not\n Fixnum(3)\n Fixnum(4)\n Fixnum(5)", new_ast.inspect)
120
+
121
+ assert(AST::Condition === new_ast.condition)
122
+ assert(AST::Fixnum === new_ast.condition.predicate)
123
+ assert(AST::Fixnum === new_ast.body)
124
+ assert(AST::If === new_ast.else)
125
+ assert(AST::Condition === new_ast.else.condition)
126
+ assert(AST::Not === new_ast.else.condition.predicate)
127
+ assert(AST::Fixnum === new_ast.else.body)
128
+ assert(AST::Fixnum === new_ast.else.else)
129
+ end
130
+
131
+ def test_begin
132
+ new_ast = AST.parse("begin; 1; 2; end").body
133
+
134
+ assert_not_nil(new_ast)
135
+ assert_equal("Body\n Fixnum(1)\n Fixnum(2)", new_ast.inspect)
136
+ assert(AST::Body === new_ast)
137
+ assert(AST::Fixnum === new_ast[0])
138
+
139
+ new_ast = AST.parse("begin; 1; end").body
140
+ assert(AST::Fixnum === new_ast)
141
+
142
+ new_ast = AST.parse("begin; end").body
143
+ assert(AST::Noop === new_ast)
144
+ end
145
+
146
+ def test_block
147
+ new_ast = AST.parse("1; 2").body
148
+
149
+ assert_not_nil(new_ast)
150
+ assert_equal("Body\n Fixnum(1)\n Fixnum(2)", new_ast.inspect)
151
+ assert(AST::Body === new_ast)
152
+ assert(AST::Fixnum === new_ast[0])
153
+
154
+ new_ast = AST.parse("1").body
155
+ assert(AST::Fixnum === new_ast)
156
+ end
157
+
158
+ def test_fixnum
159
+ new_ast = AST.parse("1").body
160
+
161
+ assert_not_nil(new_ast)
162
+ assert_equal("Fixnum(1)", new_ast.inspect)
163
+ assert(AST::Fixnum === new_ast)
164
+ assert_equal(1, new_ast.literal)
165
+ end
166
+
167
+ def test_float
168
+ new_ast = AST.parse("1.0").body
169
+
170
+ assert_not_nil(new_ast)
171
+ assert_equal("Float(1.0)", new_ast.inspect)
172
+ assert(AST::Float === new_ast)
173
+ assert_equal(1.0, new_ast.literal)
174
+ end
175
+
176
+ def test_class
177
+ new_ast = AST.parse("class Foo < Bar; 1; 2; end").body
178
+
179
+ assert_not_nil(new_ast)
180
+ assert_equal("ClassDefinition(Foo)\n Type(Bar)\n Body\n Fixnum(1)\n Fixnum(2)", new_ast.inspect)
181
+ assert(AST::ClassDefinition === new_ast)
182
+ assert_equal("Foo", new_ast.name)
183
+
184
+ assert(AST::TypeReference === new_ast.superclass)
185
+ assert(AST::Body === new_ast.body)
186
+ assert(AST::Fixnum === new_ast.body[0])
187
+
188
+ new_ast = AST.parse("class Foo < Bar; def foo; end; end").body
189
+
190
+ assert_not_nil(new_ast)
191
+ assert_equal("ClassDefinition(Foo)\n Type(Bar)\n MethodDefinition(foo)\n {:return=>nil}\n Arguments", new_ast.inspect)
192
+ assert_equal(new_ast, new_ast.body.parent)
193
+ end
194
+
195
+ def test_defn
196
+ new_ast = AST.parse("def foo(a, b); 1; end").body
197
+
198
+ assert_not_nil(new_ast)
199
+ assert_equal("MethodDefinition(foo)\n {:return=>nil}\n Arguments\n RequiredArgument(a)\n RequiredArgument(b)\n Fixnum(1)", new_ast.inspect)
200
+ assert(AST::MethodDefinition === new_ast)
201
+ assert_equal("foo", new_ast.name)
202
+ assert_not_nil(new_ast.signature)
203
+ assert_equal(1, new_ast.signature.size)
204
+ assert(nil === new_ast.signature[:return])
205
+ assert(AST::Arguments === new_ast.arguments)
206
+ assert(AST::Fixnum === new_ast.body)
207
+
208
+ new_ast = AST.parse("def foo; end").body
209
+
210
+ assert_not_nil(new_ast)
211
+ assert_equal("MethodDefinition(foo)\n {:return=>nil}\n Arguments", new_ast.inspect)
212
+ assert_not_nil(new_ast.arguments)
213
+ assert_equal(nil, new_ast.arguments.args)
214
+ assert_equal(nil, new_ast.arguments.opt_args)
215
+ assert_equal(nil, new_ast.arguments.rest_arg)
216
+ assert_equal(nil, new_ast.arguments.block_arg)
217
+ assert_nil(new_ast.body)
218
+ end
219
+
220
+ def test_defs
221
+ new_ast = AST.parse("def self.foo(a, b); 1; end").body
222
+
223
+ assert_not_nil(new_ast)
224
+ inspected = "StaticMethodDefinition(foo)\n {:return=>nil}\n Arguments\n RequiredArgument(a)\n RequiredArgument(b)\n Fixnum(1)"
225
+ assert_equal(inspected, new_ast.inspect)
226
+ assert(AST::StaticMethodDefinition === new_ast)
227
+ assert_equal("foo", new_ast.name)
228
+ assert_not_nil(new_ast.signature)
229
+ assert_equal(1, new_ast.signature.size)
230
+ assert(nil === new_ast.signature[:return])
231
+ assert(AST::Arguments === new_ast.arguments)
232
+ assert(AST::Fixnum === new_ast.body)
233
+
234
+ new_ast = AST.parse("def self.foo; end").body
235
+
236
+ assert_not_nil(new_ast)
237
+ assert_equal("StaticMethodDefinition(foo)\n {:return=>nil}\n Arguments", new_ast.inspect)
238
+ assert_not_nil(new_ast.arguments)
239
+ assert_equal(nil, new_ast.arguments.args)
240
+ assert_equal(nil, new_ast.arguments.opt_args)
241
+ assert_equal(nil, new_ast.arguments.rest_arg)
242
+ assert_equal(nil, new_ast.arguments.block_arg)
243
+ assert_nil(new_ast.body)
244
+ end
245
+
246
+ def test_signature
247
+ new_ast = AST.parse("def self.foo(a, b); {a => :foo, b => :bar, :return => :baz}; 1; end").body
248
+
249
+ assert_not_nil(new_ast.signature)
250
+ inspected = "StaticMethodDefinition(foo)\n {:return=>Type(baz), :a=>Type(foo), :b=>Type(bar)}\n Arguments\n RequiredArgument(a)\n RequiredArgument(b)\n Body\n Noop\n Fixnum(1)"
251
+ assert_equal(inspected, new_ast.inspect)
252
+ signature = new_ast.signature
253
+ assert_equal(3, signature.size)
254
+ assert(AST::TypeReference === signature[:return])
255
+ assert_equal("baz", signature[:return].name)
256
+ assert(AST::TypeReference === signature[:a])
257
+ assert_equal("foo", signature[:a].name)
258
+ assert(AST::TypeReference === signature[:b])
259
+ assert_equal("bar", signature[:b].name)
260
+ end
261
+
262
+ def test_type_reference
263
+ signature = AST.parse_ruby("{a => :foo, b => java.lang.Object, :return => ArrayList}").child_nodes[0].signature(nil)
264
+
265
+ inspected = "{:return=>Type(ArrayList), :a=>Type(foo), :b=>Type(java.lang.Object)}"
266
+ assert_equal(inspected, signature.inspect)
267
+ assert_equal(3, signature.size)
268
+ assert(AST::TypeReference === signature[:return])
269
+ assert_equal("ArrayList", signature[:return].name)
270
+ assert(AST::TypeReference === signature[:a])
271
+ assert_equal("foo", signature[:a].name)
272
+ assert(AST::TypeReference === signature[:b])
273
+ assert_equal("java.lang.Object", signature[:b].name)
274
+ end
275
+
276
+ def test_return
277
+ new_ast = AST.parse("return 1").body
278
+
279
+ assert_not_nil(new_ast)
280
+ inspected = "Return\n Fixnum(1)"
281
+ assert_equal(inspected, new_ast.inspect)
282
+ assert(AST::Return === new_ast)
283
+ assert(AST::Fixnum === new_ast.value)
284
+ end
285
+
286
+ def test_vcall
287
+ new_ast = AST.parse("foo").body
288
+
289
+ assert_not_nil(new_ast)
290
+ assert(AST::FunctionalCall === new_ast)
291
+ assert_equal("FunctionalCall(foo)", new_ast.inspect)
292
+
293
+ assert_equal("foo", new_ast.name)
294
+ assert_not_nil(new_ast.parameters)
295
+ assert_equal(0, new_ast.parameters.size)
296
+ end
297
+
298
+ def test_while
299
+ new_ast = AST.parse("while 1; 2; end").body
300
+
301
+ assert_not_nil(new_ast)
302
+ assert(AST::Loop === new_ast)
303
+ assert_equal("Loop(check_first = true, negative = false)\n Body\n Condition\n Fixnum(1)\n Body\n Body\n Fixnum(2)", new_ast.inspect)
304
+ assert(new_ast.check_first?)
305
+ assert(!new_ast.negative?)
306
+ assert(AST::Condition === new_ast.condition)
307
+ assert(AST::Fixnum === new_ast.condition.predicate)
308
+ assert(AST::Fixnum === new_ast.body)
309
+
310
+ new_ast = AST.parse("begin; 2; end while 1").body
311
+
312
+ assert_not_nil(new_ast)
313
+ assert(AST::Loop === new_ast)
314
+ assert_equal("Loop(check_first = false, negative = false)\n Body\n Condition\n Fixnum(1)\n Body\n Body\n Fixnum(2)", new_ast.inspect)
315
+ assert(!new_ast.check_first?)
316
+ assert(!new_ast.negative?)
317
+ assert(AST::Condition === new_ast.condition)
318
+ assert(AST::Fixnum === new_ast.condition.predicate)
319
+ assert(AST::Fixnum === new_ast.body)
320
+ end
321
+
322
+ def test_until
323
+ new_ast = AST.parse("until 1; 2; end").body
324
+
325
+ assert_not_nil(new_ast)
326
+ assert(AST::Loop === new_ast)
327
+ assert_equal("Loop(check_first = true, negative = true)\n Body\n Condition\n Fixnum(1)\n Body\n Body\n Fixnum(2)", new_ast.inspect)
328
+ assert(new_ast.check_first?)
329
+ assert(new_ast.negative?)
330
+ assert(AST::Condition === new_ast.condition)
331
+ assert(AST::Fixnum === new_ast.condition.predicate)
332
+ assert(AST::Fixnum === new_ast.body)
333
+
334
+ new_ast = AST.parse("begin; 2; end until 1").body
335
+
336
+ assert_not_nil(new_ast)
337
+ assert(AST::Loop === new_ast)
338
+ assert_equal("Loop(check_first = false, negative = true)\n Body\n Condition\n Fixnum(1)\n Body\n Body\n Fixnum(2)", new_ast.inspect)
339
+ assert(!new_ast.check_first?)
340
+ assert(new_ast.negative?)
341
+ assert(AST::Condition === new_ast.condition)
342
+ assert(AST::Fixnum === new_ast.condition.predicate)
343
+ assert(AST::Fixnum === new_ast.body)
344
+ end
345
+
346
+ def test_string
347
+ new_ast = AST.parse("'foo'").body
348
+
349
+ assert_not_nil(new_ast)
350
+ assert(AST::String === new_ast)
351
+ assert_equal("String(\"foo\")", new_ast.inspect)
352
+ assert_equal("foo", new_ast.literal)
353
+ end
354
+
355
+ def test_root
356
+ new_ast = AST.parse("1").body
357
+
358
+ assert_not_nil(new_ast)
359
+ assert(AST::Fixnum === new_ast)
360
+ end
361
+
362
+ def test_boolean
363
+ new_ast1 = AST.parse("true").body
364
+ new_ast2 = AST.parse("false").body
365
+
366
+ assert_not_nil(new_ast1)
367
+ assert_not_nil(new_ast2)
368
+ assert(AST::Boolean === new_ast1)
369
+ assert(AST::Boolean === new_ast2)
370
+ assert(new_ast1.literal)
371
+ assert(!new_ast2.literal)
372
+ end
373
+
374
+ def test_return
375
+ new_ast = AST.parse("return 1").body
376
+
377
+ assert_not_nil(new_ast)
378
+ assert(AST::Return === new_ast)
379
+ assert(AST::Fixnum === new_ast.value)
380
+ assert(1, new_ast.value.literal)
381
+ end
382
+
383
+ def test_empty_array
384
+ new_ast = AST.parse("int[5]").body
385
+
386
+ assert_not_nil(new_ast)
387
+ assert(AST::EmptyArray === new_ast)
388
+ assert_equal(5, new_ast.size.literal)
389
+ assert_equal(AST.type(:int), new_ast.inferred_type)
390
+ end
391
+ end