duby 0.0.2-java → 0.0.3-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 (72) hide show
  1. data/History.txt +7 -0
  2. data/README.txt +18 -7
  3. data/Rakefile +72 -0
  4. data/examples/ant/example-build.xml +7 -0
  5. data/examples/appengine/Rakefile +8 -67
  6. data/examples/appengine/Readme +4 -3
  7. data/examples/appengine/lib/duby/appengine_tasks.rb +173 -0
  8. data/examples/appengine/lib/duby/plugin/datastore.rb +92 -31
  9. data/examples/appengine/lib/duby_task.rb +61 -0
  10. data/examples/appengine/src/com/ribrdb/DubyApp.duby +32 -6
  11. data/examples/appengine/src/com/ribrdb/list.dhtml +2 -2
  12. data/examples/appengine/{config.ru → src/config.ru} +0 -0
  13. data/examples/bintrees.duby +66 -0
  14. data/examples/dynamic.duby +17 -0
  15. data/examples/fib.duby +3 -11
  16. data/examples/fields.duby +3 -3
  17. data/examples/fractal.duby +1 -3
  18. data/examples/sort_closure.duby +7 -0
  19. data/examples/swing.duby +11 -11
  20. data/javalib/duby-bootstrap.jar +0 -0
  21. data/javalib/dynalang-invoke-0.1.jar +0 -0
  22. data/lib/duby.rb +168 -35
  23. data/lib/duby/ast.rb +224 -27
  24. data/lib/duby/ast/call.rb +85 -25
  25. data/lib/duby/ast/class.rb +112 -28
  26. data/lib/duby/ast/flow.rb +65 -44
  27. data/lib/duby/ast/intrinsics.rb +223 -21
  28. data/lib/duby/ast/literal.rb +67 -16
  29. data/lib/duby/ast/local.rb +36 -40
  30. data/lib/duby/ast/method.rb +83 -67
  31. data/lib/duby/ast/structure.rb +105 -23
  32. data/lib/duby/compiler.rb +83 -28
  33. data/lib/duby/env.rb +33 -0
  34. data/lib/duby/jvm/base.rb +210 -0
  35. data/lib/duby/jvm/compiler.rb +293 -219
  36. data/lib/duby/jvm/method_lookup.rb +77 -67
  37. data/lib/duby/jvm/source_compiler.rb +250 -157
  38. data/lib/duby/jvm/source_generator/builder.rb +53 -49
  39. data/lib/duby/jvm/source_generator/loops.rb +9 -9
  40. data/lib/duby/jvm/source_generator/precompile.rb +35 -25
  41. data/lib/duby/jvm/typer.rb +19 -10
  42. data/lib/duby/jvm/types.rb +127 -68
  43. data/lib/duby/jvm/types/basic_types.rb +26 -13
  44. data/lib/duby/jvm/types/enumerable.rb +6 -4
  45. data/lib/duby/jvm/types/factory.rb +49 -13
  46. data/lib/duby/jvm/types/floats.rb +16 -0
  47. data/lib/duby/jvm/types/integers.rb +63 -2
  48. data/lib/duby/jvm/types/intrinsics.rb +43 -21
  49. data/lib/duby/jvm/types/methods.rb +326 -86
  50. data/lib/duby/jvm/types/number.rb +3 -0
  51. data/lib/duby/nbcompiler.rb +1 -1
  52. data/lib/duby/plugin/edb.rb +1 -1
  53. data/lib/duby/plugin/java.rb +10 -1
  54. data/lib/duby/transform.rb +134 -46
  55. data/lib/duby/typer.rb +75 -50
  56. data/test/test_ast.rb +106 -106
  57. data/test/test_compilation.rb +46 -32
  58. data/test/test_env.rb +42 -0
  59. data/test/test_java_typer.rb +35 -51
  60. data/test/test_javac_compiler.rb +4 -1
  61. data/test/test_jvm_compiler.rb +564 -133
  62. data/test/test_typer.rb +68 -92
  63. metadata +37 -21
  64. data/examples/README +0 -16
  65. data/lib/duby/c/compiler.rb +0 -134
  66. data/lib/duby/old/compiler_old.rb +0 -845
  67. data/lib/duby/old/declaration.rb +0 -72
  68. data/lib/duby/old/mapper.rb +0 -72
  69. data/lib/duby/old/signature.rb +0 -52
  70. data/lib/duby/old/typer_old.rb +0 -163
  71. data/lib/duby/plugin/math.rb +0 -84
  72. data/test/test_math_plugin.rb +0 -87
@@ -4,6 +4,10 @@ class Java::JavaMethod
4
4
  def static?
5
5
  java.lang.reflect.Modifier.static?(modifiers)
6
6
  end
7
+
8
+ def abstract?
9
+ java.lang.reflect.Modifier.abstract?(modifiers)
10
+ end
7
11
  end
8
12
 
9
13
  module Duby::JVM::Types
@@ -22,7 +26,7 @@ module Duby::JVM::Types
22
26
  end
23
27
  end
24
28
  end
25
-
29
+
26
30
  Type.send :include, ArgumentConversion
27
31
 
28
32
  class Intrinsic
@@ -41,26 +45,33 @@ module Duby::JVM::Types
41
45
  def call(builder, ast, expression)
42
46
  @block.call(builder, ast, expression)
43
47
  end
44
-
48
+
45
49
  def declaring_class
46
50
  @class
47
51
  end
48
-
52
+
49
53
  def constructor?
50
54
  false
51
55
  end
52
-
56
+
57
+ def abstract?
58
+ false
59
+ end
60
+
53
61
  def exceptions
54
62
  []
55
63
  end
56
-
64
+
57
65
  def actual_return_type
58
66
  return_type
59
67
  end
60
68
  end
61
-
62
- class JavaConstructor
69
+
70
+ class JavaCallable
63
71
  include ArgumentConversion
72
+
73
+ attr_accessor :member
74
+
64
75
  def initialize(member)
65
76
  @member = member
66
77
  end
@@ -68,31 +79,49 @@ module Duby::JVM::Types
68
79
  def name
69
80
  @name ||= @member.name
70
81
  end
71
-
82
+
83
+ def field?
84
+ false
85
+ end
86
+
87
+ def parameter_types
88
+ @member.parameter_types
89
+ end
90
+ end
91
+
92
+ class JavaConstructor < JavaCallable
72
93
  def argument_types
73
94
  @argument_types ||= @member.argument_types.map do |arg|
74
- AST.type(arg) if arg
95
+ if arg.kind_of?(AST::TypeReference) || arg.nil?
96
+ arg
97
+ else
98
+ AST.type(arg)
99
+ end
75
100
  end
76
101
  end
77
-
102
+
78
103
  def return_type
79
104
  declaring_class
80
105
  end
81
-
106
+
82
107
  def actual_return_type
83
108
  return_type
84
109
  end
85
110
 
86
111
  def exceptions
87
112
  @member.exception_types.map do |exception|
88
- AST.type(exception.name)
113
+ if exception.kind_of?(Duby::JVM::Types::Type)
114
+ exception
115
+ else
116
+ Duby::AST.type(exception.class_name)
117
+ end
89
118
  end
90
119
  end
91
120
 
92
121
  def declaring_class
93
122
  AST.type(@member.declaring_class)
94
123
  end
95
-
124
+
96
125
  def call(compiler, ast, expression)
97
126
  target = ast.target.inferred_type
98
127
  compiler.method.new target
@@ -101,9 +130,9 @@ module Duby::JVM::Types
101
130
  compiler.method.invokespecial(
102
131
  target,
103
132
  "<init>",
104
- [nil, *@member.argument_types])
133
+ [nil, *@member.argument_types])
105
134
  end
106
-
135
+
107
136
  def constructor?
108
137
  true
109
138
  end
@@ -112,38 +141,47 @@ module Duby::JVM::Types
112
141
  class JavaMethod < JavaConstructor
113
142
  def return_type
114
143
  @return_type ||= begin
115
- if @member.return_type
116
- AST.type(@member.return_type)
117
- else
144
+ if void?
118
145
  declaring_class
146
+ else
147
+ AST.type(@member.return_type)
119
148
  end
120
149
  end
121
150
  end
122
-
151
+
123
152
  def actual_return_type
124
- if @member.return_type
125
- return_type
126
- else
153
+ if void?
127
154
  Void
155
+ else
156
+ return_type
128
157
  end
129
158
  end
130
-
159
+
131
160
  def static?
132
161
  @member.static?
133
162
  end
134
-
163
+
164
+ def abstract?
165
+ @member.abstract?
166
+ end
167
+
135
168
  def void?
136
- @member.return_type.nil?
169
+ return_type = @member.return_type
170
+ return true if return_type.nil?
171
+ if return_type.respond_to?(:descriptor) && return_type.descriptor == 'V'
172
+ return true
173
+ end
174
+ false
137
175
  end
138
-
176
+
139
177
  def constructor?
140
178
  false
141
179
  end
142
-
180
+
143
181
  def call(compiler, ast, expression)
144
182
  target = ast.target.inferred_type
145
183
  ast.target.compile(compiler, true)
146
-
184
+
147
185
  # if expression, void methods return the called object,
148
186
  # for consistency and chaining
149
187
  # TODO: inference phase needs to track that signature is
@@ -151,7 +189,7 @@ module Duby::JVM::Types
151
189
  if expression && void?
152
190
  compiler.method.dup
153
191
  end
154
-
192
+
155
193
  convert_args(compiler, ast.parameters)
156
194
  if target.interface?
157
195
  compiler.method.invokeinterface(
@@ -164,7 +202,7 @@ module Duby::JVM::Types
164
202
  name,
165
203
  [@member.return_type, *@member.argument_types])
166
204
  end
167
-
205
+
168
206
  unless expression || void?
169
207
  compiler.method.pop
170
208
  end
@@ -197,18 +235,8 @@ module Duby::JVM::Types
197
235
  end
198
236
  end
199
237
  end
200
-
201
- class JavaStaticMethod < JavaMethod
202
- def return_type
203
- @return_type ||= begin
204
- if @member.return_type
205
- AST.type(@member.return_type)
206
- else
207
- Void
208
- end
209
- end
210
- end
211
238
 
239
+ class JavaStaticMethod < JavaMethod
212
240
  def call(compiler, ast, expression)
213
241
  target = ast.target.inferred_type
214
242
  convert_args(compiler, ast.parameters)
@@ -223,11 +251,117 @@ module Duby::JVM::Types
223
251
  compiler.method.pop unless expression || void?
224
252
  end
225
253
  end
226
-
254
+
255
+ class JavaDynamicMethod < JavaMethod
256
+ def initialize(name, *types)
257
+ @name = name
258
+ @types = types
259
+ end
260
+
261
+ def return_type
262
+ AST.type('dynamic')
263
+ end
264
+
265
+ def declaring_class
266
+ java.lang.Object
267
+ end
268
+
269
+ def argument_types
270
+ @types
271
+ end
272
+
273
+ def call(compiler, ast, expression)
274
+ target = ast.target.inferred_type
275
+ ast.target.compile(compiler, true)
276
+
277
+ ast.parameters.each do |param|
278
+ param.compile(compiler, true)
279
+ end
280
+ compiler.method.invokedynamic(
281
+ target,
282
+ "dyn:callPropWithThis:#{name}",
283
+ [return_type, target, *@types])
284
+
285
+ unless expression
286
+ compiler.method.pop
287
+ end
288
+
289
+ compiler.bootstrap_dynamic
290
+ end
291
+ end
292
+
293
+ class JavaFieldAccessor < JavaMethod
294
+ def field?
295
+ true
296
+ end
297
+
298
+ def return_type
299
+ AST.type(@member.type)
300
+ end
301
+
302
+ alias actual_return_type return_type
303
+
304
+ def public?
305
+ @member.public?
306
+ end
307
+
308
+ def final?
309
+ @member.final?
310
+ end
311
+ end
312
+
313
+ class JavaFieldGetter < JavaFieldAccessor
314
+ def argument_types
315
+ []
316
+ end
317
+
318
+ def call(compiler, ast, expression)
319
+ target = ast.target.inferred_type
320
+
321
+ # TODO: assert that no args are being passed, though that should have failed lookup
322
+
323
+ if expression
324
+ if @member.static?
325
+ compiler.method.getstatic(target, name, @member.type)
326
+ else
327
+ ast.target.compile(compiler, true)
328
+ compiler.method.getfield(target, name, @member.type)
329
+ end
330
+ end
331
+ end
332
+ end
333
+
334
+ class JavaFieldSetter < JavaFieldAccessor
335
+ def return_type
336
+ AST.type(@member.type)
337
+ end
338
+
339
+ def argument_types
340
+ [AST.type(@member.type)]
341
+ end
342
+
343
+ def call(compiler, ast, expression)
344
+ target = ast.target.inferred_type
345
+
346
+ # TODO: assert that no args are being passed, though that should have failed lookup
347
+
348
+ convert_args(compiler, ast.parameters)
349
+ if @member.static?
350
+ compiler.method.dup if expression
351
+ compiler.method.putstatic(target, name, @member.type)
352
+ else
353
+ ast.target.compile(compiler, true)
354
+ convert_args(compiler, ast.parameters)
355
+ compiler.method.dup_x2 if expression
356
+ compiler.method.putfield(target, name, @member.type)
357
+ end
358
+ end
359
+ end
360
+
227
361
  class DubyMember
228
362
  attr_reader :name, :argument_types, :declaring_class, :return_type
229
363
  attr_reader :exception_types
230
-
364
+
231
365
  def initialize(klass, name, args, return_type, static, exceptions)
232
366
  if return_type == Void
233
367
  return_type = nil
@@ -239,12 +373,16 @@ module Duby::JVM::Types
239
373
  @static = static
240
374
  @exception_types = exceptions || []
241
375
  end
242
-
376
+
243
377
  def static?
244
378
  @static
245
379
  end
380
+
381
+ def abstract?
382
+ @declaring_class.interface?
383
+ end
246
384
  end
247
-
385
+
248
386
  class Type
249
387
  def get_method(name, args)
250
388
  method = find_method(self, name, args, meta?)
@@ -254,111 +392,205 @@ module Duby::JVM::Types
254
392
  if args[-1].narrow!
255
393
  method = find_method(self, name, args, meta?)
256
394
  end
257
- end
395
+ end
258
396
  end
259
397
  method
260
398
  end
261
-
399
+
262
400
  def constructor(*types)
263
- types = types.map {|type| type.jvm_type}
264
- constructor = (jvm_type.constructor(*types) rescue nil)
265
- return JavaConstructor.new(constructor) if constructor
401
+ begin
402
+ descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
403
+ constructor = jvm_type.getConstructor(*descriptors)
404
+ return JavaConstructor.new(constructor) if constructor
405
+ rescue => ex
406
+ log(ex.message)
407
+ end
266
408
  raise NameError, "No constructor #{name}(#{types.join ', '})"
267
409
  end
268
-
410
+
269
411
  def java_method(name, *types)
270
412
  intrinsic = intrinsics[name][types]
271
413
  return intrinsic if intrinsic
272
- types = types.map {|type| type.jvm_type}
273
- method = (jvm_type.java_method(name, *types) rescue nil)
274
- if method && method.static? == meta?
275
- return JavaStaticMethod.new(method) if method.static?
276
- return JavaMethod.new(method)
414
+ jvm_types = types.map {|type| type.jvm_type}
415
+
416
+ return JavaDynamicMethod.new(name, *jvm_types) if dynamic?
417
+
418
+ begin
419
+ descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
420
+ method = jvm_type.getDeclaredMethod(name, *descriptors)
421
+
422
+ if method.nil? && superclass
423
+ method = superclass.java_method(name, *types) rescue nil
424
+ end
425
+
426
+ if method.nil? && jvm_type.abstract?
427
+ interfaces.each do |interface|
428
+ method = interface.java_method(name, *types) rescue nil
429
+ break if method
430
+ end
431
+ end
432
+
433
+ if method && method.static? == meta?
434
+ return JavaStaticMethod.new(method) if method.static?
435
+ return JavaMethod.new(method)
436
+ end
437
+ rescue => ex
438
+ log(ex.message)
277
439
  end
278
440
  raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
279
441
  end
280
442
 
281
- def declared_instance_methods
443
+ def declared_instance_methods(name=nil)
444
+ methods = []
282
445
  if jvm_type && !array?
283
- methods = jvm_type.declared_instance_methods.map do |method|
284
- JavaMethod.new(method)
446
+ jvm_type.getDeclaredMethods(name).each do |method|
447
+ methods << JavaMethod.new(method) unless method.static?
285
448
  end
286
- else
287
- methods = []
288
449
  end
289
- methods.concat((meta? ? unmeta : self).declared_intrinsics)
450
+ methods.concat((meta? ? unmeta : self).declared_intrinsics(name))
290
451
  end
291
452
 
292
- def declared_class_methods
293
- methods = jvm_type.declared_class_methods.map do |method|
294
- JavaStaticMethod.new(method)
453
+ def declared_class_methods(name=nil)
454
+ methods = []
455
+ jvm_type.getDeclaredMethods(name).each do |method|
456
+ methods << JavaStaticMethod.new(method) if method.static?
295
457
  end
296
- methods.concat(meta.declared_intrinsics)
458
+ methods.concat(meta.declared_intrinsics(name))
297
459
  end
298
460
 
299
461
  def declared_constructors
300
- jvm_type.declared_constructors.map do |method|
462
+ jvm_type.getConstructors.map do |method|
301
463
  JavaConstructor.new(method)
302
464
  end
303
465
  end
466
+
467
+ def field_getter(name)
468
+ if jvm_type
469
+ field = jvm_type.getField(name)
470
+ JavaFieldGetter.new(field) if field
471
+ else
472
+ nil
473
+ end
474
+ end
475
+
476
+ def field_setter(name)
477
+ if jvm_type
478
+ field = jvm_type.getField(name)
479
+ JavaFieldSetter.new(field) if field
480
+ else
481
+ nil
482
+ end
483
+ end
484
+
485
+ def inner_class_getter(name)
486
+ full_name = "#{self.name}$#{name}"
487
+ inner_class = Duby::AST.type(full_name) rescue nil
488
+ return unless inner_class
489
+ inner_class.inner_class = true
490
+ add_macro(name) do |transformer, call|
491
+ Duby::AST::Constant.new(call.parent, call.position, full_name)
492
+ end
493
+ intrinsics[name][[]]
494
+ end
304
495
  end
305
496
 
306
497
  class TypeDefinition
307
498
  def java_method(name, *types)
308
499
  method = instance_methods[name].find {|m| m.argument_types == types}
309
500
  return method if method
501
+ intrinsic = intrinsics[name][types]
502
+ return intrinsic if intrinsic
310
503
  raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
311
504
  end
312
-
505
+
313
506
  def java_static_method(name, *types)
314
507
  method = static_methods[name].find {|m| m.argument_types == types}
315
508
  return method if method
509
+ intrinsic = meta.intrinsics[name][types]
510
+ return intrinsic if intrinsic
316
511
  raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
317
512
  end
318
-
513
+
319
514
  def constructor(*types)
320
515
  constructor = constructors.find {|c| c.argument_types == types}
321
516
  return constructor if constructor
322
517
  raise NameError, "No constructor #{name}(#{types.join ', '})"
323
518
  end
324
519
 
325
- def declared_instance_methods
326
- instance_methods.values.flatten
520
+ def declared_instance_methods(name=nil)
521
+ declared_intrinsics(name) + if name.nil?
522
+ instance_methods.values.flatten
523
+ else
524
+ instance_methods[name]
525
+ end
327
526
  end
328
527
 
329
- def declared_class_methods
330
- static_methods.values.flatten
528
+ def declared_class_methods(name=nil)
529
+ meta.declared_intrinsics(name) + if name.nil?
530
+ static_methods.values.flatten
531
+ else
532
+ static_methods[name]
533
+ end
331
534
  end
332
-
535
+
333
536
  def declared_constructors
334
537
  constructors
335
538
  end
336
-
539
+
337
540
  def constructors
338
541
  @constructors ||= []
339
542
  end
340
-
543
+
544
+ def default_constructor
545
+ if constructors.empty?
546
+ declare_method('initialize', [], self, [])
547
+ @default_constructor_added = true
548
+ constructors[0]
549
+ else
550
+ constructor
551
+ end
552
+ end
553
+
341
554
  def instance_methods
342
555
  @instance_methods ||= Hash.new {|h, k| h[k] = []}
343
556
  end
344
-
557
+
345
558
  def static_methods
346
559
  @static_methods ||= Hash.new {|h, k| h[k] = []}
347
560
  end
348
-
561
+
349
562
  def declare_method(name, arguments, type, exceptions)
563
+ raise "Bad args" unless arguments.all?
350
564
  member = DubyMember.new(self, name, arguments, type, false, exceptions)
351
565
  if name == 'initialize'
352
- constructors << JavaConstructor.new(member)
566
+ if @default_constructor_added
567
+ unless arguments.empty?
568
+ raise "Can't add constructor #{member} after using the default."
569
+ end
570
+ else
571
+ constructors << JavaConstructor.new(member)
572
+ end
353
573
  else
354
574
  instance_methods[name] << JavaMethod.new(member)
355
575
  end
356
576
  end
357
-
577
+
358
578
  def declare_static_method(name, arguments, type, exceptions)
359
579
  member = DubyMember.new(self, name, arguments, type, true, exceptions)
360
580
  static_methods[name] << JavaStaticMethod.new(member)
361
581
  end
582
+
583
+ def interface?
584
+ false
585
+ end
586
+
587
+ def field_getter(name)
588
+ nil
589
+ end
590
+
591
+ def field_setter(name)
592
+ nil
593
+ end
362
594
  end
363
595
 
364
596
  class TypeDefMeta
@@ -369,13 +601,21 @@ module Duby::JVM::Types
369
601
  def java_method(*args)
370
602
  unmeta.java_static_method(*args)
371
603
  end
372
-
373
- def declared_instance_methods
374
- unmeta.declared_instance_methods
604
+
605
+ def declared_class_methods(name=nil)
606
+ unmeta.declared_class_methods(name)
375
607
  end
376
-
377
- def declared_class_methods
378
- unmeta.declared_class_methods
608
+
609
+ def declared_instance_methods(name=nil)
610
+ unmeta.declared_instance_methods(name)
611
+ end
612
+
613
+ def field_getter(name)
614
+ nil
615
+ end
616
+
617
+ def field_setter(name)
618
+ nil
379
619
  end
380
620
  end
381
621
  end