duby 0.0.2-java → 0.0.3-java

Sign up to get free protection for your applications and to get access to all the features.
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