mirah 0.0.4-java

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