mirah 0.0.4-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 (141) hide show
  1. data/History.txt +15 -0
  2. data/README.txt +51 -0
  3. data/Rakefile +86 -0
  4. data/bin/duby +10 -0
  5. data/bin/dubyc +10 -0
  6. data/bin/dubyp +10 -0
  7. data/bin/jrubyp +36 -0
  8. data/bin/mirah +9 -0
  9. data/bin/mirah.cmd +1 -0
  10. data/bin/mirahc +9 -0
  11. data/bin/mirahc.cmd +1 -0
  12. data/bin/mirahp +9 -0
  13. data/bin/mirahp.cmd +1 -0
  14. data/examples/ant/example-build.xml +7 -0
  15. data/examples/appengine/Rakefile +19 -0
  16. data/examples/appengine/Readme +29 -0
  17. data/examples/appengine/src/org/mirah/MirahApp.mirah +57 -0
  18. data/examples/appengine/src/org/mirah/list.dhtml +15 -0
  19. data/examples/appengine/war/WEB-INF/lib/dubydatastore.jar +0 -0
  20. data/examples/bintrees.mirah +66 -0
  21. data/examples/construction.mirah +8 -0
  22. data/examples/dynamic.mirah +17 -0
  23. data/examples/edb.mirah +3 -0
  24. data/examples/fib.mirah +16 -0
  25. data/examples/fields.mirah +22 -0
  26. data/examples/fractal.mirah +55 -0
  27. data/examples/java_thing.mirah +13 -0
  28. data/examples/plugins/appengine/Rakefile +55 -0
  29. data/examples/plugins/appengine/lib/com/google/appengine/ext/duby/db/datastore.rb +375 -0
  30. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +336 -0
  31. data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +113 -0
  32. data/examples/simple_class.mirah +12 -0
  33. data/examples/sort_closure.mirah +7 -0
  34. data/examples/swing.mirah +20 -0
  35. data/examples/tak.mirah +15 -0
  36. data/examples/test.edb +9 -0
  37. data/examples/wiki/Rakefile +18 -0
  38. data/examples/wiki/src/org/mirah/wiki/MirahWiki.duby +324 -0
  39. data/examples/wiki/src/org/mirah/wiki/edit.eduby.html +42 -0
  40. data/examples/wiki/src/org/mirah/wiki/error.eduby.html +2 -0
  41. data/examples/wiki/src/org/mirah/wiki/layout.eduby.html +69 -0
  42. data/examples/wiki/src/org/mirah/wiki/parser.eduby.html +7 -0
  43. data/examples/wiki/src/org/mirah/wiki/view.eduby.html +15 -0
  44. data/examples/wiki/war/WEB-INF/classes/test/HeredocContext.class +0 -0
  45. data/examples/wiki/war/WEB-INF/classes/test/MirahParser.class +0 -0
  46. data/examples/wiki/war/WEB-INF/lib/appengine-api.jar +0 -0
  47. data/examples/wiki/war/WEB-INF/lib/dubydatastore.jar +0 -0
  48. data/examples/wiki/war/WEB-INF/lib/jmeta-runtime.jar +0 -0
  49. data/examples/wiki/war/WEB-INF/lib/pegdown-stubs.jar +0 -0
  50. data/examples/wiki/war/WEB-INF/pegdown.jar +0 -0
  51. data/examples/wiki/war/app.yaml +21 -0
  52. data/examples/wiki/war/public/favicon.ico +0 -0
  53. data/examples/wiki/war/public/images/appengine_duby.png +0 -0
  54. data/examples/wiki/war/public/images/back.gif +0 -0
  55. data/examples/wiki/war/public/images/dir.gif +0 -0
  56. data/examples/wiki/war/public/images/file.gif +0 -0
  57. data/examples/wiki/war/public/javascripts/prettify.js +61 -0
  58. data/examples/wiki/war/public/robots.txt +0 -0
  59. data/examples/wiki/war/public/stylesheets/main.css +156 -0
  60. data/examples/wiki/war/public/stylesheets/prettify.css +1 -0
  61. data/examples/wiki/war/public/stylesheets/sh_style.css +66 -0
  62. data/examples/wiki/war/public/stylesheets/source.css +21 -0
  63. data/examples/wiki/war/public/wmd/images/bg-fill.png +0 -0
  64. data/examples/wiki/war/public/wmd/images/bg.png +0 -0
  65. data/examples/wiki/war/public/wmd/images/blockquote.png +0 -0
  66. data/examples/wiki/war/public/wmd/images/bold.png +0 -0
  67. data/examples/wiki/war/public/wmd/images/code.png +0 -0
  68. data/examples/wiki/war/public/wmd/images/h1.png +0 -0
  69. data/examples/wiki/war/public/wmd/images/hr.png +0 -0
  70. data/examples/wiki/war/public/wmd/images/img.png +0 -0
  71. data/examples/wiki/war/public/wmd/images/italic.png +0 -0
  72. data/examples/wiki/war/public/wmd/images/link.png +0 -0
  73. data/examples/wiki/war/public/wmd/images/ol.png +0 -0
  74. data/examples/wiki/war/public/wmd/images/redo.png +0 -0
  75. data/examples/wiki/war/public/wmd/images/separator.png +0 -0
  76. data/examples/wiki/war/public/wmd/images/ul.png +0 -0
  77. data/examples/wiki/war/public/wmd/images/undo.png +0 -0
  78. data/examples/wiki/war/public/wmd/images/wmd-on.png +0 -0
  79. data/examples/wiki/war/public/wmd/images/wmd.png +0 -0
  80. data/examples/wiki/war/public/wmd/showdown.js +421 -0
  81. data/examples/wiki/war/public/wmd/wmd-base.js +1799 -0
  82. data/examples/wiki/war/public/wmd/wmd-plus.js +311 -0
  83. data/examples/wiki/war/public/wmd/wmd.js +73 -0
  84. data/javalib/JRubyParser.jar +0 -0
  85. data/javalib/dynalang-invoke-0.1.jar +0 -0
  86. data/javalib/mirah-bootstrap.jar +0 -0
  87. data/javalib/mirah-parser.jar +0 -0
  88. data/lib/duby.rb +2 -0
  89. data/lib/mirah.rb +338 -0
  90. data/lib/mirah/appengine_tasks.rb +146 -0
  91. data/lib/mirah/ast.rb +615 -0
  92. data/lib/mirah/ast/call.rb +307 -0
  93. data/lib/mirah/ast/class.rb +311 -0
  94. data/lib/mirah/ast/flow.rb +364 -0
  95. data/lib/mirah/ast/intrinsics.rb +470 -0
  96. data/lib/mirah/ast/literal.rb +154 -0
  97. data/lib/mirah/ast/local.rb +89 -0
  98. data/lib/mirah/ast/method.rb +360 -0
  99. data/lib/mirah/ast/scope.rb +208 -0
  100. data/lib/mirah/ast/structure.rb +226 -0
  101. data/lib/mirah/ast/type.rb +130 -0
  102. data/lib/mirah/compiler.rb +341 -0
  103. data/lib/mirah/env.rb +33 -0
  104. data/lib/mirah/jvm/base.rb +258 -0
  105. data/lib/mirah/jvm/compiler.rb +885 -0
  106. data/lib/mirah/jvm/method_lookup.rb +203 -0
  107. data/lib/mirah/jvm/source_compiler.rb +737 -0
  108. data/lib/mirah/jvm/source_generator/builder.rb +444 -0
  109. data/lib/mirah/jvm/source_generator/loops.rb +110 -0
  110. data/lib/mirah/jvm/source_generator/precompile.rb +188 -0
  111. data/lib/mirah/jvm/source_generator/typer.rb +11 -0
  112. data/lib/mirah/jvm/typer.rb +151 -0
  113. data/lib/mirah/jvm/types.rb +416 -0
  114. data/lib/mirah/jvm/types/basic_types.rb +33 -0
  115. data/lib/mirah/jvm/types/boolean.rb +17 -0
  116. data/lib/mirah/jvm/types/enumerable.rb +65 -0
  117. data/lib/mirah/jvm/types/extensions.rb +86 -0
  118. data/lib/mirah/jvm/types/factory.rb +186 -0
  119. data/lib/mirah/jvm/types/floats.rb +86 -0
  120. data/lib/mirah/jvm/types/integers.rb +171 -0
  121. data/lib/mirah/jvm/types/intrinsics.rb +376 -0
  122. data/lib/mirah/jvm/types/literals.rb +74 -0
  123. data/lib/mirah/jvm/types/methods.rb +614 -0
  124. data/lib/mirah/jvm/types/number.rb +143 -0
  125. data/lib/mirah/nbcompiler.rb +29 -0
  126. data/lib/mirah/plugin/edb.rb +29 -0
  127. data/lib/mirah/plugin/gwt.rb +173 -0
  128. data/lib/mirah/plugin/java.rb +55 -0
  129. data/lib/mirah/transform.rb +266 -0
  130. data/lib/mirah/transform2.rb +728 -0
  131. data/lib/mirah/typer.rb +407 -0
  132. data/lib/mirah_task.rb +107 -0
  133. data/test/test_ast.rb +359 -0
  134. data/test/test_compilation.rb +112 -0
  135. data/test/test_env.rb +42 -0
  136. data/test/test_gwt.rb +58 -0
  137. data/test/test_java_typer.rb +183 -0
  138. data/test/test_javac_compiler.rb +63 -0
  139. data/test/test_jvm_compiler.rb +2607 -0
  140. data/test/test_typer.rb +221 -0
  141. metadata +235 -0
@@ -0,0 +1,74 @@
1
+ require 'delegate'
2
+
3
+ module Duby::JVM::Types
4
+
5
+ # Represents a literal number that can be represented
6
+ # in multiple types
7
+ class NarrowingType < DelegateClass(PrimitiveType)
8
+ def initialize(default_type, narrowed_type)
9
+ super(default_type)
10
+ @narrowed = default_type != narrowed_type && narrowed_type
11
+ end
12
+
13
+ def hash
14
+ __getobj__.hash
15
+ end
16
+
17
+ # Changes this type to the smallest type that will hold
18
+ # its literal value.
19
+ def narrow!
20
+ if @narrowed
21
+ __setobj__(@narrowed)
22
+ true
23
+ end
24
+ end
25
+ end
26
+
27
+ class FixnumLiteral < NarrowingType
28
+ def self.range(type)
29
+ type::MIN_VALUE .. type::MAX_VALUE
30
+ end
31
+
32
+ BYTE_RANGE = range(java.lang.Byte)
33
+ SHORT_RANGE = range(java.lang.Short)
34
+ INT_RANGE = range(java.lang.Integer)
35
+ LONG_RANGE = range(java.lang.Long)
36
+
37
+ def initialize(literal)
38
+ default_type = case literal
39
+ when INT_RANGE
40
+ Int
41
+ else
42
+ Long
43
+ end
44
+
45
+ # TODO chars?
46
+ # There's not really any way to tell if we should narrow to a char
47
+ # or a byte/short. I suppose we could try both, but that seems ugly.
48
+ # Maybe it's the right thing to do though?
49
+ narrowed_type = case literal
50
+ when BYTE_RANGE
51
+ Byte
52
+ when SHORT_RANGE
53
+ Short
54
+ when INT_RANGE
55
+ Int
56
+ else
57
+ Long
58
+ end
59
+
60
+ super(default_type, narrowed_type)
61
+ end
62
+ end
63
+
64
+ class FloatLiteral < NarrowingType
65
+ FLOAT_RANGE = java.lang.Float::MIN_VALUE .. java.lang.Float::MAX_VALUE
66
+ NaN = java.lang.Float::NaN
67
+ POSITIVE_INFINITY = java.lang.Float::POSITIVE_INFINITY
68
+ NEGATIVE_INFINITY = java.lang.Float::NEGATIVE_INFINITY
69
+
70
+ def initialize(literal)
71
+ super(Double, Double)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,614 @@
1
+ require 'mirah/jvm/types'
2
+
3
+ class Java::JavaMethod
4
+ def static?
5
+ java.lang.reflect.Modifier.static?(modifiers)
6
+ end
7
+
8
+ def abstract?
9
+ java.lang.reflect.Modifier.abstract?(modifiers)
10
+ end
11
+ end
12
+
13
+ module Duby::JVM::Types
14
+ AST ||= Duby::AST
15
+
16
+ module ArgumentConversion
17
+ def convert_args(compiler, values, types=nil)
18
+ # TODO boxing/unboxing
19
+ # TODO varargs
20
+ types ||= argument_types
21
+ values.zip(types).each do |value, type|
22
+ compiler.compile(value, true)
23
+ if type.primitive? && type != value.inferred_type
24
+ value.inferred_type.widen(compiler.method, type)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ Type.send :include, ArgumentConversion
31
+
32
+ class Intrinsic
33
+ include ArgumentConversion
34
+ attr_reader :name, :argument_types, :return_type
35
+
36
+ def initialize(klass, name, args, type, &block)
37
+ raise ArgumentError, "Block required" unless block_given?
38
+ @class = klass
39
+ @name = name
40
+ @argument_types = args
41
+ @return_type = type
42
+ @block = block
43
+ end
44
+
45
+ def call(builder, ast, expression)
46
+ @block.call(builder, ast, expression)
47
+ end
48
+
49
+ def declaring_class
50
+ @class
51
+ end
52
+
53
+ def constructor?
54
+ false
55
+ end
56
+
57
+ def field?
58
+ false
59
+ end
60
+
61
+ def abstract?
62
+ false
63
+ end
64
+
65
+ def exceptions
66
+ []
67
+ end
68
+ end
69
+
70
+ class JavaCallable
71
+ include ArgumentConversion
72
+
73
+ attr_accessor :member
74
+
75
+ def initialize(member)
76
+ @member = member
77
+ end
78
+
79
+ def name
80
+ @name ||= @member.name
81
+ end
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
93
+ def argument_types
94
+ @argument_types ||= @member.argument_types.map do |arg|
95
+ if arg.kind_of?(AST::TypeReference) || arg.nil?
96
+ arg
97
+ else
98
+ AST.type(nil, arg)
99
+ end
100
+ end
101
+ end
102
+
103
+ def return_type
104
+ declaring_class
105
+ end
106
+
107
+ def exceptions
108
+ @member.exception_types.map do |exception|
109
+ if exception.kind_of?(Duby::JVM::Types::Type)
110
+ exception
111
+ else
112
+ Duby::AST.type(nil, exception.class_name)
113
+ end
114
+ end
115
+ end
116
+
117
+ def declaring_class
118
+ AST.type(nil, @member.declaring_class)
119
+ end
120
+
121
+ def call(compiler, ast, expression)
122
+ target = ast.target.inferred_type
123
+ compiler.method.new target
124
+ compiler.method.dup if expression
125
+ convert_args(compiler, ast.parameters)
126
+ compiler.method.invokespecial(
127
+ target,
128
+ "<init>",
129
+ [nil, *@member.argument_types])
130
+ end
131
+
132
+ def constructor?
133
+ true
134
+ end
135
+ end
136
+
137
+ class JavaMethod < JavaConstructor
138
+ def return_type
139
+ @return_type ||= begin
140
+ if void?
141
+ Void
142
+ else
143
+ AST.type(nil, @member.return_type)
144
+ end
145
+ end
146
+ end
147
+
148
+ def static?
149
+ @member.static?
150
+ end
151
+
152
+ def abstract?
153
+ @member.abstract?
154
+ end
155
+
156
+ def void?
157
+ return_type = @member.return_type
158
+ return true if return_type.nil?
159
+ if return_type.respond_to?(:descriptor) && return_type.descriptor == 'V'
160
+ return true
161
+ end
162
+ false
163
+ end
164
+
165
+ def constructor?
166
+ false
167
+ end
168
+
169
+ def call(compiler, ast, expression)
170
+ target = ast.target.inferred_type
171
+ ast.target.compile(compiler, true)
172
+
173
+ # if expression, void methods return the called object,
174
+ # for consistency and chaining
175
+ # TODO: inference phase needs to track that signature is
176
+ # void but actual type is callee
177
+ if expression && void?
178
+ compiler.method.dup
179
+ end
180
+
181
+ convert_args(compiler, ast.parameters)
182
+ if target.interface?
183
+ compiler.method.invokeinterface(
184
+ target,
185
+ name,
186
+ [@member.return_type, *@member.argument_types])
187
+ else
188
+ compiler.method.invokevirtual(
189
+ target,
190
+ name,
191
+ [@member.return_type, *@member.argument_types])
192
+ end
193
+
194
+ unless expression || void?
195
+ if return_type.wide?
196
+ compiler.method.pop2
197
+ else
198
+ compiler.method.pop
199
+ end
200
+ end
201
+ end
202
+
203
+ def call_special(compiler, ast, expression)
204
+ target = ast.target.inferred_type
205
+ ast.target.compile(compiler, true)
206
+
207
+ # if expression, void methods return the called object,
208
+ # for consistency and chaining
209
+ # TODO: inference phase needs to track that signature is
210
+ # void but actual type is callee
211
+ if expression && void?
212
+ compiler.method.dup
213
+ end
214
+
215
+ convert_args(compiler, ast.parameters)
216
+ if target.interface?
217
+ raise "interfaces should not receive call_special"
218
+ else
219
+ compiler.method.invokespecial(
220
+ target,
221
+ name,
222
+ [@member.return_type, *@member.argument_types])
223
+ end
224
+
225
+ unless expression || void?
226
+ compiler.method.pop
227
+ end
228
+ end
229
+ end
230
+
231
+ class JavaStaticMethod < JavaMethod
232
+ def call(compiler, ast, expression)
233
+ target = declaring_class
234
+ convert_args(compiler, ast.parameters)
235
+ compiler.method.invokestatic(
236
+ target,
237
+ name,
238
+ [@member.return_type, *@member.argument_types])
239
+ # if expression, void static methods return null, for consistency
240
+ # TODO: inference phase needs to track that signature is void
241
+ # but actual type is null object
242
+ compiler.method.aconst_null if expression && void?
243
+ compiler.method.pop unless expression || void?
244
+ end
245
+ end
246
+
247
+ class JavaDynamicMethod < JavaMethod
248
+ def initialize(name, *types)
249
+ @name = name
250
+ @types = types
251
+ end
252
+
253
+ def return_type
254
+ AST.type(nil, 'dynamic')
255
+ end
256
+
257
+ def declaring_class
258
+ java.lang.Object
259
+ end
260
+
261
+ def argument_types
262
+ @types
263
+ end
264
+
265
+ def call(compiler, ast, expression)
266
+ target = ast.target.inferred_type
267
+ ast.target.compile(compiler, true)
268
+
269
+ ast.parameters.each do |param|
270
+ param.compile(compiler, true)
271
+ end
272
+ compiler.method.invokedynamic(
273
+ target,
274
+ "dyn:callPropWithThis:#{name}",
275
+ [return_type, target, *@types])
276
+
277
+ unless expression
278
+ compiler.method.pop
279
+ end
280
+
281
+ compiler.bootstrap_dynamic
282
+ end
283
+ end
284
+
285
+ class JavaFieldAccessor < JavaMethod
286
+ def field?
287
+ true
288
+ end
289
+
290
+ def return_type
291
+ AST.type(nil, @member.type)
292
+ end
293
+
294
+ def public?
295
+ @member.public?
296
+ end
297
+
298
+ def final?
299
+ @member.final?
300
+ end
301
+ end
302
+
303
+ class JavaFieldGetter < JavaFieldAccessor
304
+ def argument_types
305
+ []
306
+ end
307
+
308
+ def call(compiler, ast, expression)
309
+ target = ast.target.inferred_type
310
+
311
+ # TODO: assert that no args are being passed, though that should have failed lookup
312
+
313
+ if expression
314
+ if @member.static?
315
+ compiler.method.getstatic(target, name, @member.type)
316
+ else
317
+ ast.target.compile(compiler, true)
318
+ compiler.method.getfield(target, name, @member.type)
319
+ end
320
+ end
321
+ end
322
+ end
323
+
324
+ class JavaFieldSetter < JavaFieldAccessor
325
+ def return_type
326
+ AST.type(nil, @member.type)
327
+ end
328
+
329
+ def argument_types
330
+ [AST.type(nil, @member.type)]
331
+ end
332
+
333
+ def call(compiler, ast, expression)
334
+ target = ast.target.inferred_type
335
+
336
+ # TODO: assert that no args are being passed, though that should have failed lookup
337
+
338
+ if @member.static?
339
+ convert_args(compiler, ast.parameters)
340
+ compiler.method.dup if expression
341
+ compiler.method.putstatic(target, name, @member.type)
342
+ else
343
+ ast.target.compile(compiler, true)
344
+ convert_args(compiler, ast.parameters)
345
+ compiler.method.dup_x2 if expression
346
+ compiler.method.putfield(target, name, @member.type)
347
+ end
348
+ end
349
+ end
350
+
351
+ class DubyMember
352
+ attr_reader :name, :argument_types, :declaring_class, :return_type
353
+ attr_reader :exception_types
354
+
355
+ def initialize(klass, name, args, return_type, static, exceptions)
356
+ if return_type == Void
357
+ return_type = nil
358
+ end
359
+ @declaring_class = klass
360
+ @name = name
361
+ @argument_types = args
362
+ @return_type = return_type
363
+ @static = static
364
+ @exception_types = exceptions || []
365
+ end
366
+
367
+ def static?
368
+ @static
369
+ end
370
+
371
+ def abstract?
372
+ @declaring_class.interface?
373
+ end
374
+ end
375
+
376
+ class Type
377
+ def get_method(name, args)
378
+ method = find_method(self, name, args, meta?)
379
+ unless method
380
+ # Allow constant narrowing for assignment methods
381
+ if name =~ /=$/ && args[-1].respond_to?(:narrow!)
382
+ if args[-1].narrow!
383
+ method = find_method(self, name, args, meta?)
384
+ end
385
+ end
386
+ end
387
+ method
388
+ end
389
+
390
+ def constructor(*types)
391
+ begin
392
+ descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
393
+ constructor = jvm_type.getConstructor(*descriptors)
394
+ return JavaConstructor.new(constructor) if constructor
395
+ rescue => ex
396
+ log(ex.message)
397
+ end
398
+ raise NameError, "No constructor #{name}(#{types.join ', '})"
399
+ end
400
+
401
+ def java_method(name, *types)
402
+ intrinsic = intrinsics[name][types]
403
+ return intrinsic if intrinsic
404
+ jvm_types = types.map {|type| type.jvm_type}
405
+
406
+ return JavaDynamicMethod.new(name, *jvm_types) if dynamic?
407
+
408
+ begin
409
+ descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
410
+ method = jvm_type.getDeclaredMethod(name, *descriptors)
411
+
412
+ if method.nil? && superclass
413
+ method = superclass.java_method(name, *types) rescue nil
414
+ end
415
+
416
+ if method.nil? && jvm_type.abstract?
417
+ interfaces.each do |interface|
418
+ method = interface.java_method(name, *types) rescue nil
419
+ break if method
420
+ end
421
+ end
422
+
423
+ return method if method.kind_of?(JavaCallable)
424
+ if method && method.static? == meta?
425
+ return JavaStaticMethod.new(method) if method.static?
426
+ return JavaMethod.new(method)
427
+ end
428
+ rescue => ex
429
+ log(ex.message)
430
+ end
431
+ raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
432
+ end
433
+
434
+ def declared_instance_methods(name=nil)
435
+ methods = []
436
+ if jvm_type && !array?
437
+ jvm_type.getDeclaredMethods(name).each do |method|
438
+ methods << JavaMethod.new(method) unless method.static?
439
+ end
440
+ end
441
+ methods.concat((meta? ? unmeta : self).declared_intrinsics(name))
442
+ end
443
+
444
+ def declared_class_methods(name=nil)
445
+ methods = []
446
+ if jvm_type && !unmeta.array?
447
+ jvm_type.getDeclaredMethods(name).each do |method|
448
+ methods << JavaStaticMethod.new(method) if method.static?
449
+ end
450
+ end
451
+ methods.concat(meta.declared_intrinsics(name))
452
+ end
453
+
454
+ def declared_constructors
455
+ jvm_type.getConstructors.map do |method|
456
+ JavaConstructor.new(method)
457
+ end
458
+ end
459
+
460
+ def field_getter(name)
461
+ if jvm_type
462
+ field = jvm_type.getField(name)
463
+ JavaFieldGetter.new(field) if field
464
+ else
465
+ nil
466
+ end
467
+ end
468
+
469
+ def field_setter(name)
470
+ if jvm_type
471
+ field = jvm_type.getField(name)
472
+ JavaFieldSetter.new(field) if field
473
+ else
474
+ nil
475
+ end
476
+ end
477
+
478
+ def inner_class_getter(name)
479
+ full_name = "#{self.name}$#{name}"
480
+ inner_class = Duby::AST.type(nil, full_name) rescue nil
481
+ return unless inner_class
482
+ inner_class.inner_class = true
483
+ add_macro(name) do |transformer, call|
484
+ Duby::AST::Constant.new(call.parent, call.position, full_name)
485
+ end
486
+ intrinsics[name][[]]
487
+ end
488
+ end
489
+
490
+ class TypeDefinition
491
+ def java_method(name, *types)
492
+ method = instance_methods[name].find {|m| m.argument_types == types}
493
+ return method if method
494
+ intrinsic = intrinsics[name][types]
495
+ return intrinsic if intrinsic
496
+ raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
497
+ end
498
+
499
+ def java_static_method(name, *types)
500
+ method = static_methods[name].find {|m| m.argument_types == types}
501
+ return method if method
502
+ intrinsic = meta.intrinsics[name][types]
503
+ return intrinsic if intrinsic
504
+ raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
505
+ end
506
+
507
+ def constructor(*types)
508
+ constructor = constructors.find {|c| c.argument_types == types}
509
+ return constructor if constructor
510
+ raise NameError, "No constructor #{name}(#{types.join ', '})"
511
+ end
512
+
513
+ def declared_instance_methods(name=nil)
514
+ declared_intrinsics(name) + if name.nil?
515
+ instance_methods.values.flatten
516
+ else
517
+ instance_methods[name]
518
+ end
519
+ end
520
+
521
+ def declared_class_methods(name=nil)
522
+ meta.declared_intrinsics(name) + if name.nil?
523
+ static_methods.values.flatten
524
+ else
525
+ static_methods[name]
526
+ end
527
+ end
528
+
529
+ def declared_constructors
530
+ constructors
531
+ end
532
+
533
+ def constructors
534
+ @constructors ||= []
535
+ end
536
+
537
+ def default_constructor
538
+ if constructors.empty?
539
+ declare_method('initialize', [], self, [])
540
+ @default_constructor_added = true
541
+ constructors[0]
542
+ else
543
+ constructor
544
+ end
545
+ end
546
+
547
+ def instance_methods
548
+ @instance_methods ||= Hash.new {|h, k| h[k] = []}
549
+ end
550
+
551
+ def static_methods
552
+ @static_methods ||= Hash.new {|h, k| h[k] = []}
553
+ end
554
+
555
+ def declare_method(name, arguments, type, exceptions)
556
+ raise "Bad args" unless arguments.all?
557
+ member = DubyMember.new(self, name, arguments, type, false, exceptions)
558
+ if name == 'initialize'
559
+ if @default_constructor_added
560
+ unless arguments.empty?
561
+ raise "Can't add constructor #{member} after using the default."
562
+ end
563
+ else
564
+ constructors << JavaConstructor.new(member)
565
+ end
566
+ else
567
+ instance_methods[name] << JavaMethod.new(member)
568
+ end
569
+ end
570
+
571
+ def declare_static_method(name, arguments, type, exceptions)
572
+ member = DubyMember.new(self, name, arguments, type, true, exceptions)
573
+ static_methods[name] << JavaStaticMethod.new(member)
574
+ end
575
+
576
+ def interface?
577
+ false
578
+ end
579
+
580
+ def field_getter(name)
581
+ nil
582
+ end
583
+
584
+ def field_setter(name)
585
+ nil
586
+ end
587
+ end
588
+
589
+ class TypeDefMeta
590
+ def constructor(*args)
591
+ unmeta.constructor(*args)
592
+ end
593
+
594
+ def java_method(*args)
595
+ unmeta.java_static_method(*args)
596
+ end
597
+
598
+ def declared_class_methods(name=nil)
599
+ unmeta.declared_class_methods(name)
600
+ end
601
+
602
+ def declared_instance_methods(name=nil)
603
+ unmeta.declared_instance_methods(name)
604
+ end
605
+
606
+ def field_getter(name)
607
+ nil
608
+ end
609
+
610
+ def field_setter(name)
611
+ nil
612
+ end
613
+ end
614
+ end