mirah 0.1.0.pre-java → 0.1.1-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 (92) hide show
  1. data/History.txt +736 -0
  2. data/README.md +71 -0
  3. data/Rakefile +227 -73
  4. data/examples/Fib.class +0 -0
  5. data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +2 -3
  6. data/examples/simple_class.mirah +3 -3
  7. data/examples/{dynamic.mirah → simple_class.mirah~} +7 -12
  8. data/javalib/mirah-bootstrap.jar +0 -0
  9. data/javalib/mirah-builtins.jar +0 -0
  10. data/javalib/mirah-compiler.jar +0 -0
  11. data/javalib/mirah-parser.jar +0 -0
  12. data/javalib/mirah-util.jar +0 -0
  13. data/lib/mirah.rb +8 -1
  14. data/lib/mirah/ast.rb +1 -1
  15. data/lib/mirah/ast/scope.rb +16 -0
  16. data/lib/mirah/commands/base.rb +1 -3
  17. data/lib/mirah/compiler.rb +17 -3
  18. data/lib/mirah/errors.rb +10 -10
  19. data/lib/mirah/generator.rb +21 -9
  20. data/lib/mirah/jvm/compiler.rb +17 -0
  21. data/lib/mirah/jvm/compiler/base.rb +24 -5
  22. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +83 -20
  23. data/lib/mirah/jvm/method_lookup.rb +43 -22
  24. data/lib/mirah/jvm/types.rb +1 -2
  25. data/lib/mirah/jvm/types/array_type.rb +1 -6
  26. data/lib/mirah/jvm/types/ast_ext.rb +31 -0
  27. data/lib/mirah/jvm/types/basic_types.rb +1 -2
  28. data/lib/mirah/jvm/types/boolean.rb +11 -10
  29. data/lib/mirah/jvm/types/extensions.rb +14 -5
  30. data/lib/mirah/jvm/types/factory.rb +128 -43
  31. data/lib/mirah/jvm/types/floats.rb +8 -10
  32. data/lib/mirah/jvm/types/integers.rb +16 -9
  33. data/lib/mirah/jvm/types/intrinsics.rb +17 -69
  34. data/lib/mirah/jvm/types/meta_type.rb +5 -0
  35. data/lib/mirah/jvm/types/methods.rb +317 -151
  36. data/lib/mirah/jvm/types/methods.rb~ +973 -0
  37. data/lib/mirah/jvm/types/number.rb +29 -6
  38. data/lib/mirah/jvm/types/primitive_type.rb +35 -7
  39. data/lib/mirah/jvm/types/source_mirror.rb +11 -6
  40. data/lib/mirah/jvm/types/type.rb +52 -0
  41. data/lib/mirah/jvm/types/type_definition.rb +8 -2
  42. data/lib/mirah/transform/ast_ext.rb +9 -31
  43. data/lib/mirah/transform/transformer.rb +1 -1
  44. data/lib/mirah/typer.rb +2 -1
  45. data/lib/mirah/util/argument_processor.rb +10 -14
  46. data/lib/mirah/util/argument_processor.rb~ +146 -0
  47. data/lib/mirah/util/compilation_state.rb +15 -9
  48. data/lib/mirah/util/process_errors.rb +8 -2
  49. data/lib/mirah/version.rb +2 -2
  50. data/lib/mirah_task.rb +0 -7
  51. data/test/core/typer_test.rb +21 -13
  52. data/test/core/util/argument_processor_test.rb +19 -19
  53. data/test/core/util/class_loader_test.rb +19 -4
  54. data/test/core/util/compilation_state_test.rb +38 -0
  55. data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
  56. data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
  57. data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
  58. data/test/jvm/blocks_test.rb +50 -29
  59. data/test/jvm/bytecode_test_helper.rb +71 -57
  60. data/test/jvm/cast_test.rb +162 -0
  61. data/test/jvm/constructors_test.rb +48 -0
  62. data/test/jvm/enumerable_test.rb +136 -7
  63. data/test/jvm/example_test.rb +39 -0
  64. data/test/jvm/factory_test.rb +6 -0
  65. data/test/jvm/generics_test.rb +0 -5
  66. data/test/jvm/import_test.rb +81 -0
  67. data/test/jvm/interface_test.rb +113 -0
  68. data/test/jvm/java_typer_test.rb +57 -11
  69. data/test/jvm/jvm_commands_test.rb +24 -0
  70. data/test/jvm/jvm_compiler_test.rb +186 -370
  71. data/test/jvm/macros_test.rb +67 -6
  72. data/test/jvm/main_method_test.rb +1 -1
  73. data/test/jvm/mirror_compilation_test_helper.rb +24 -0
  74. data/test/jvm/new_backend_test_helper.rb +25 -0
  75. data/test/jvm/rescue_test.rb +153 -18
  76. data/test/jvm/string_test.rb +41 -0
  77. data/test/jvm/varargs_test.rb +65 -0
  78. data/test/mirrors/base_type_test.rb +96 -0
  79. data/test/mirrors/bytecode_mirror_test.rb +86 -0
  80. data/test/mirrors/generics_test.rb +776 -0
  81. data/test/mirrors/member_test.rb +69 -0
  82. data/test/mirrors/method_lookup_test.rb +574 -0
  83. data/test/mirrors/mirrors_test.rb +562 -0
  84. data/test/mirrors/simple_async_mirror_loader_test.rb +110 -0
  85. data/test/mirrors/simple_mirror_loader_test.rb +104 -0
  86. data/test/test_helper.rb +2 -1
  87. metadata +244 -217
  88. data/README.txt +0 -59
  89. data/javalib/dynalink-0.2.jar +0 -0
  90. data/lib/mirah/jvm/typer.rb +0 -177
  91. data/lib/mirah/jvm/types/dynamic_type.rb +0 -45
  92. data/lib/mirah/jvm/types/unreachable_type.rb +0 -27
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
1
+ # Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
2
2
  # All contributing project authors may be found in the NOTICE file.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,10 +23,6 @@ module Mirah::JVM::Types
23
23
  @type_system.type(nil, 'float')
24
24
  end
25
25
 
26
- def box_type
27
- @type_system.type(nil, 'java.lang.Float')
28
- end
29
-
30
26
  def suffix
31
27
  'g'
32
28
  end
@@ -54,6 +50,8 @@ module Mirah::JVM::Types
54
50
  # Do nothing
55
51
  when 'double'
56
52
  builder.f2d
53
+ when wrapper_name, 'java.lang.Object'
54
+ builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
57
55
  else
58
56
  raise ArgumentError, "Invalid widening conversion from float to #{type}"
59
57
  end
@@ -69,10 +67,6 @@ module Mirah::JVM::Types
69
67
  @type_system.type(nil, 'double')
70
68
  end
71
69
 
72
- def box_type
73
- @type_system.type(nil, 'java.lang.Double')
74
- end
75
-
76
70
  def wide?
77
71
  true
78
72
  end
@@ -93,7 +87,11 @@ module Mirah::JVM::Types
93
87
  end
94
88
 
95
89
  def compile_widen(builder, type)
96
- if type.name != 'double'
90
+ case type.name
91
+ when 'double'
92
+ when wrapper_name, 'java.lang.Object'
93
+ builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
94
+ else
97
95
  raise ArgumentError, "Invalid widening conversion from double to #{type}"
98
96
  end
99
97
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
1
+ # Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
2
2
  # All contributing project authors may be found in the NOTICE file.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,6 +39,8 @@ module Mirah::JVM::Types
39
39
  builder.i2f
40
40
  when 'double'
41
41
  builder.i2d
42
+ when wrapper_name, 'java.lang.Object'
43
+ builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
42
44
  else
43
45
  raise ArgumentError, "Invalid widening conversion from #{name} to #{type}"
44
46
  end
@@ -52,10 +54,6 @@ module Mirah::JVM::Types
52
54
  @type_system.type(nil, 'int')
53
55
  end
54
56
 
55
- def box_type
56
- @type_system.type(nil, 'java.lang.Integer')
57
- end
58
-
59
57
  def jump_if(builder, op, label)
60
58
  builder.send "if_icmp#{op}", label
61
59
  end
@@ -72,6 +70,17 @@ module Mirah::JVM::Types
72
70
  end
73
71
  end
74
72
 
73
+ class CharacterType < IntegerType
74
+ def compile_widen(builder, type)
75
+ case type.name
76
+ when 'char'
77
+ # do nothing
78
+ else
79
+ super
80
+ end
81
+ end
82
+ end
83
+
75
84
  class LongType < Number
76
85
  def prefix
77
86
  'l'
@@ -81,10 +90,6 @@ module Mirah::JVM::Types
81
90
  @type_system.type(nil, 'long')
82
91
  end
83
92
 
84
- def box_type
85
- @type_system.type(nil, 'java.lang.Long')
86
- end
87
-
88
93
  def literal(builder, value)
89
94
  builder.ldc_long(value)
90
95
  end
@@ -105,6 +110,8 @@ module Mirah::JVM::Types
105
110
  builder.l2f
106
111
  when 'double'
107
112
  builder.l2d
113
+ when wrapper_name, 'java.lang.Object'
114
+ builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
108
115
  else
109
116
  raise ArgumentError, "Invalid widening conversion from Int to #{type}"
110
117
  end
@@ -48,10 +48,10 @@ module Mirah::JVM::Types
48
48
  @macros ||= Hash.new {|h, k| h[k] = {}}
49
49
  end
50
50
 
51
- def add_method(name, args, method_or_type=nil, &block)
51
+ def add_method(name, args, method_or_type=nil, kind=nil, &block)
52
52
  if block_given?
53
53
  method_or_type = Intrinsic.new(self, name, args,
54
- method_or_type, &block)
54
+ method_or_type, kind, &block)
55
55
  end
56
56
  intrinsics[name][args] = method_or_type
57
57
  end
@@ -76,6 +76,7 @@ module Mirah::JVM::Types
76
76
  # call.parameters.each do |arg|
77
77
  # arg.scope = scope
78
78
  # end
79
+
79
80
  begin
80
81
  expander = klass.constructors[0].newInstance(typer.macro_compiler, call)
81
82
  ast = expander.expand
@@ -83,7 +84,7 @@ module Mirah::JVM::Types
83
84
  # puts "Unable to expand macro #{name.inspect} from #{klass} with #{call}"
84
85
  end
85
86
  if ast
86
- body = Mirah::AST::NodeList.new(ast.position)
87
+ body = Mirah::AST::NodeList.new(ast.position.to_java(Mirah::AST::Position))
87
88
  # TODO scope
88
89
  # static_scope = typer.scoper.add_scope(body)
89
90
  # static_scope.parent = typer.scoper.get_scope(call)
@@ -151,7 +152,7 @@ module Mirah::JVM::Types
151
152
  def load_extensions(klass=nil)
152
153
  mirror = nil
153
154
  if klass
154
- mirror = @type_system.get_mirror(klass.name)
155
+ mirror = @type_system.mirror_class(klass)
155
156
  elsif jvm_type
156
157
  mirror = jvm_type
157
158
  end
@@ -162,10 +163,10 @@ module Mirah::JVM::Types
162
163
  return self if macros.nil?
163
164
  macros.each do |macro_class|
164
165
  klass = begin
165
- JRuby.runtime.jruby_class_loader.loadClass(macro_class)
166
- rescue java.lang.NoClassDefFoundError => ex
167
- raise ex
168
- end
166
+ JRuby.runtime.jruby_class_loader.loadClass(macro_class)
167
+ rescue java.lang.NoClassDefFoundError => ex
168
+ raise ex
169
+ end
169
170
  add_compiled_macro(klass)
170
171
  end
171
172
  end
@@ -193,7 +194,7 @@ module Mirah::JVM::Types
193
194
  object_type = @type_system.type(nil, 'java.lang.Object')
194
195
  class_type = @type_system.type(nil, 'java.lang.Class')
195
196
 
196
- add_method('nil?', [], boolean) do |compiler, call, expression|
197
+ add_method('nil?', [], boolean, 'IS_NULL') do |compiler, call, expression|
197
198
  if expression
198
199
  compiler.visit(call.target, true)
199
200
  compiler.method.op_to_bool do |target|
@@ -202,7 +203,7 @@ module Mirah::JVM::Types
202
203
  end
203
204
  end
204
205
 
205
- add_method('==', [object_type], boolean) do |compiler, call, expression|
206
+ add_method('==', [object_type], boolean, 'COMPARISON_OP') do |compiler, call, expression|
206
207
  # Should this call Object.equals for consistency with Ruby?
207
208
  if expression
208
209
  compiler.visit(call.target, true)
@@ -213,7 +214,7 @@ module Mirah::JVM::Types
213
214
  end
214
215
  end
215
216
 
216
- add_method('!=', [object_type], boolean) do |compiler, call, expression|
217
+ add_method('!=', [object_type], boolean, 'COMPARISON_OP') do |compiler, call, expression|
217
218
  # Should this call Object.equals for consistency with Ruby?
218
219
  if expression
219
220
  compiler.visit(call.target, true)
@@ -224,7 +225,7 @@ module Mirah::JVM::Types
224
225
  end
225
226
  end
226
227
 
227
- add_method('kind_of?', [object_type.meta], boolean) do |compiler, call, expression|
228
+ add_method('kind_of?', [object_type.meta], boolean, "INSTANCEOF") do |compiler, call, expression|
228
229
  compiler.visit(call.target, expression)
229
230
  if expression
230
231
  klass = compiler.inferred_type(call.parameters(0))
@@ -261,7 +262,7 @@ module Mirah::JVM::Types
261
262
  load_extensions(ArrayExtensions.java_class) if ArrayExtensions
262
263
  int_type = @type_system.type(nil, 'int')
263
264
  add_method(
264
- '[]', [int_type], component_type) do |compiler, call, expression|
265
+ '[]', [int_type], component_type, "ARRAY_ACCESS") do |compiler, call, expression|
265
266
  if expression
266
267
  compiler.visit(call.target, true)
267
268
  compiler.visit(call.parameters(0), true)
@@ -271,7 +272,7 @@ module Mirah::JVM::Types
271
272
 
272
273
  add_method('[]=',
273
274
  [int_type, component_type],
274
- component_type) do |compiler, call, expression|
275
+ component_type, "ARRAY_ASSIGN") do |compiler, call, expression|
275
276
  compiler.visit(call.target, true)
276
277
  convert_args(compiler, call.parameters, [@type_system.type(nil, 'int'), component_type])
277
278
  component_type.astore(compiler.method)
@@ -280,7 +281,7 @@ module Mirah::JVM::Types
280
281
  end
281
282
  end
282
283
 
283
- add_method('length', [], int_type) do |compiler, call, expression|
284
+ add_method('length', [], int_type, "ARRAY_LENGTH") do |compiler, call, expression|
284
285
  compiler.visit(call.target, true)
285
286
  compiler.method.arraylength
286
287
  end
@@ -289,7 +290,7 @@ module Mirah::JVM::Types
289
290
 
290
291
  class MetaType
291
292
  def add_intrinsics
292
- add_method('class', [], @type_system.type(nil, 'java.lang.Class')) do |compiler, call, expression|
293
+ add_method('class', [], @type_system.type(nil, 'java.lang.Class'), "CLASS_LITERAL") do |compiler, call, expression|
293
294
  if expression
294
295
  compiler.method.ldc_class(unmeta)
295
296
  end
@@ -322,59 +323,6 @@ module Mirah::JVM::Types
322
323
  char_type = @type_system.type(nil, 'char')
323
324
  float_type = @type_system.type(nil, 'float')
324
325
  double_type = @type_system.type(nil, 'double')
325
- add_method('+', [string_type], string_type) do |compiler, call, expression|
326
- if expression
327
- java_method('concat', string_type).call(compiler, call, expression)
328
- end
329
- end
330
- add_method('+', [bool_type], string_type) do |compiler, call, expression|
331
- if expression
332
- compiler.visit(call.target, true)
333
- compiler.visit(call.parameters(0), true)
334
- compiler.method.invokestatic string_type, "valueOf", [string_type, bool_type]
335
- compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
336
- end
337
- end
338
- add_method('+', [char_type], string_type) do |compiler, call, expression|
339
- if expression
340
- compiler.visit(call.target, true)
341
- compiler.visit(call.parameters(0), true)
342
- compiler.method.invokestatic string_type, "valueOf", [string_type, char_type]
343
- compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
344
- end
345
- end
346
- add_method('+', [int_type], string_type) do |compiler, call, expression|
347
- if expression
348
- compiler.visit(call.target, true)
349
- compiler.visit(call.parameters(0), true)
350
- compiler.method.invokestatic string_type, "valueOf", [string_type, int_type]
351
- compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
352
- end
353
- end
354
- add_method('+', [long_type], string_type) do |compiler, call, expression|
355
- if expression
356
- compiler.visit(call.target, true)
357
- compiler.visit(call.parameters(0), true)
358
- compiler.method.invokestatic string_type, "valueOf", [string_type, long_type]
359
- compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
360
- end
361
- end
362
- add_method('+', [float_type], string_type) do |compiler, call, expression|
363
- if expression
364
- compiler.visit(call.target, true)
365
- compiler.visit(call.parameters(0), true)
366
- compiler.method.invokestatic string_type, "valueOf", [string_type, float_type]
367
- compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
368
- end
369
- end
370
- add_method('+', [double_type], string_type) do |compiler, call, expression|
371
- if expression
372
- compiler.visit(call.target, true)
373
- compiler.visit(call.parameters(0), true)
374
- compiler.method.invokestatic string_type, "valueOf", [string_type, double_type]
375
- compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
376
- end
377
- end
378
326
  add_method('[]', [int_type], char_type) do |compiler, call, expression|
379
327
  if expression
380
328
  compiler.visit(call.target, true)
@@ -13,6 +13,11 @@ module Mirah
13
13
  @unmeta.basic_type
14
14
  end
15
15
 
16
+ def name
17
+ return @unmeta.name if @unmeta
18
+ super
19
+ end
20
+
16
21
  def meta?
17
22
  true
18
23
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
1
+ # Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
2
2
  # All contributing project authors may be found in the NOTICE file.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,20 +25,48 @@ class Java::JavaMethod
25
25
  end
26
26
  end
27
27
 
28
+ class BiteScript::ASM::FieldMirror
29
+ def returnType
30
+ self.type
31
+ end
32
+ end
33
+
28
34
  module Mirah::JVM::Types
29
35
  AST ||= Mirah::AST
30
36
 
31
37
  module ArgumentConversion
32
38
  def convert_args(compiler, values, types=nil)
33
39
  # TODO boxing/unboxing
34
- # TODO varargs
35
40
  types ||= argument_types
36
- values.zip(types).each do |value, type|
41
+ needs_to_build_varargs_array = false
42
+
43
+ if respond_to?(:varargs?) && varargs?
44
+ non_varargs_types = types[0..-2]
45
+ non_varargs_values = values.first non_varargs_types.size
46
+
47
+ varargs_values = values.to_a.last(values.size - non_varargs_values.size)
48
+ varargs_type = types.last
49
+
50
+ unless varargs_values.length == 1 &&
51
+ varargs_type.compatible?(compiler.inferred_type(varargs_values.first))
52
+ needs_to_build_varargs_array = true
53
+ values = non_varargs_values
54
+ end
55
+ end
56
+
57
+ values_and_types = values.zip(types)
58
+
59
+ values_and_types.each do |value, type|
37
60
  compiler.visit(value, true)
38
- if type.primitive? && type != compiler.inferred_type(value)
39
- compiler.inferred_type(value).compile_widen(compiler.method, type)
61
+ in_type = compiler.inferred_type(value)
62
+ if in_type.primitive? && type != in_type
63
+ in_type.compile_widen(compiler.method, type)
40
64
  end
41
65
  end
66
+
67
+ if needs_to_build_varargs_array
68
+ compiler.visitVarargsArray(varargs_type, varargs_values)
69
+ end
42
70
  end
43
71
  end
44
72
 
@@ -48,13 +76,23 @@ module Mirah::JVM::Types
48
76
  include ArgumentConversion
49
77
  attr_reader :name, :argument_types, :return_type
50
78
 
51
- def initialize(klass, name, args, type, &block)
79
+ def initialize(klass, name, args, type, kind=nil, &block)
52
80
  raise ArgumentError, "Block required" unless block_given?
53
81
  @class = klass
54
82
  @name = name
55
83
  @argument_types = args
56
84
  @return_type = type
57
85
  @block = block
86
+ @kind = kind
87
+ end
88
+
89
+ def kind
90
+ Java::OrgMirahJvmTypes::MemberKind.const_get(@kind)
91
+ end
92
+
93
+ def accept(visitor, expression)
94
+ name = "visit_#{@kind.downcase}".sub(/_op$/,"")
95
+ visitor.send(name, self, expression)
58
96
  end
59
97
 
60
98
  def call(builder, ast, expression, *args)
@@ -80,10 +118,19 @@ module Mirah::JVM::Types
80
118
  def exceptions
81
119
  []
82
120
  end
121
+
122
+ def varargs?
123
+ false
124
+ end
125
+
126
+ def isVararg
127
+ varargs?
128
+ end
83
129
  end
84
130
 
85
131
  class Macro
86
132
  java_import 'org.mirah.typer.InlineCode'
133
+ java_import 'org.mirah.typer.NodeBuilder'
87
134
  attr_reader :name, :argument_types, :return_type
88
135
 
89
136
  def initialize(klass, name, args, &block)
@@ -92,7 +139,7 @@ module Mirah::JVM::Types
92
139
  @name = name
93
140
  @argument_types = args
94
141
  raise ArgumentError unless args.all?
95
- @return_type = InlineCode.new(&block)
142
+ @return_type = InlineCode.new(block.to_java(NodeBuilder))
96
143
  end
97
144
 
98
145
  def declaring_class
@@ -102,13 +149,11 @@ module Mirah::JVM::Types
102
149
 
103
150
  class JavaCallable
104
151
  include ArgumentConversion
105
- java_import 'org.mirah.typer.ResolvedType'
106
- java_import 'org.mirah.typer.TypeSystem'
107
152
 
108
153
  attr_accessor :member
109
154
 
110
155
  def initialize(types, member)
111
- raise ArgumentError unless types.kind_of?(TypeSystem)
156
+ raise ArgumentError unless types.kind_of?(Mirah::Typer::TypeSystem)
112
157
  @types = types
113
158
  @member = member
114
159
  end
@@ -124,6 +169,10 @@ module Mirah::JVM::Types
124
169
  def parameter_types
125
170
  @member.parameter_types
126
171
  end
172
+
173
+ def synthetic?
174
+ @member.synthetic?
175
+ end
127
176
  end
128
177
 
129
178
  class JavaConstructor < JavaCallable
@@ -143,7 +192,7 @@ module Mirah::JVM::Types
143
192
 
144
193
  def exceptions
145
194
  @member.exception_types.map do |exception|
146
- if exception.kind_of?(ResolvedType)
195
+ if exception.kind_of?(Mirah::Typer::ResolvedType)
147
196
  exception
148
197
  else
149
198
  @types.type(nil, exception.class_name)
@@ -176,6 +225,22 @@ module Mirah::JVM::Types
176
225
  def constructor?
177
226
  true
178
227
  end
228
+
229
+ def varargs?
230
+ @member.varargs?
231
+ end
232
+
233
+ def isVararg
234
+ varargs?
235
+ end
236
+
237
+ def accept(visitor, expression)
238
+ visitor.visitConstructor(self, expression)
239
+ end
240
+
241
+ def kind
242
+ Java::OrgMirahJvmTypes::MemberKind::CONSTRUCTOR
243
+ end
179
244
  end
180
245
 
181
246
  class JavaMethod < JavaConstructor
@@ -214,6 +279,22 @@ module Mirah::JVM::Types
214
279
  false
215
280
  end
216
281
 
282
+ def accept(visitor, expression)
283
+ if self.static?
284
+ visitor.visitStaticMethodCall(self, expression)
285
+ else
286
+ visitor.visitMethodCall(self, expression)
287
+ end
288
+ end
289
+
290
+ def kind
291
+ if self.static?
292
+ Java::OrgMirahJvmTypes::MemberKind::STATIC_METHOD
293
+ else
294
+ Java::OrgMirahJvmTypes::MemberKind::METHOD
295
+ end
296
+ end
297
+
217
298
  def call(compiler, ast, expression, parameters=nil)
218
299
  target = compiler.inferred_type(ast.target)
219
300
  compiler.visit(ast.target, true)
@@ -296,50 +377,13 @@ module Mirah::JVM::Types
296
377
  compiler.method.aconst_null if expression && void?
297
378
  return_type.pop(compiler.method) unless expression || void?
298
379
  end
299
- end
300
-
301
- class JavaDynamicMethod < JavaMethod
302
- def initialize(type_system, name, *argument_types)
303
- super(type_system, nil)
304
- @name = name
305
- @argument_types = argument_types
306
- end
307
-
308
- def return_type
309
- @types.type(nil, 'dynamic')
310
- end
311
-
312
- def declaring_class
313
- java.lang.Object
314
- end
315
380
 
316
- def argument_types
317
- @argument_types
381
+ def accept(visitor, expression)
382
+ visitor.visitStaticMethodCall(self, expression)
318
383
  end
319
-
320
- def call(compiler, ast, expression, parameters=nil)
321
- target = compiler.inferred_type(ast.target)
322
- compiler.visit(ast.target, true)
323
-
324
- parameters ||= ast.parameters
325
- parameters.each do |param|
326
- compiler.visit(param, true)
327
- end
328
- handle = compiler.method.mh_invokestatic(
329
- org.dynalang.dynalink.DefaultBootstrapper,
330
- "bootstrap",
331
- java.lang.invoke.CallSite,
332
- java.lang.invoke.MethodHandles::Lookup,
333
- java.lang.String,
334
- java.lang.invoke.MethodType)
335
- compiler.method.invokedynamic(
336
- "dyn:callPropWithThis:#{name}",
337
- [return_type, target, *@argument_types],
338
- handle)
339
-
340
- unless expression
341
- return_type.pop(compiler.method)
342
- end
384
+
385
+ def kind
386
+ Java::OrgMirahJvmTypes::MemberKind::STATIC_METHOD
343
387
  end
344
388
  end
345
389
 
@@ -380,6 +424,22 @@ module Mirah::JVM::Types
380
424
  end
381
425
  end
382
426
  end
427
+
428
+ def accept(visitor, expression)
429
+ if self.static?
430
+ visitor.visitStaticFieldAccess(self, expression)
431
+ else
432
+ visitor.visitFieldAccess(self, expression)
433
+ end
434
+ end
435
+
436
+ def kind
437
+ if self.static?
438
+ Java::OrgMirahJvmTypes::MemberKind::STATIC_FIELD_ACCESS
439
+ else
440
+ Java::OrgMirahJvmTypes::MemberKind::FIELD_ACCESS
441
+ end
442
+ end
383
443
  end
384
444
 
385
445
  class JavaFieldSetter < JavaFieldAccessor
@@ -408,6 +468,22 @@ module Mirah::JVM::Types
408
468
  compiler.method.putfield(target, name, @member.type)
409
469
  end
410
470
  end
471
+
472
+ def accept(visitor, expression)
473
+ if self.static?
474
+ visitor.visitStaticFieldAssign(self, expression)
475
+ else
476
+ visitor.visitFieldAssign(self, expression)
477
+ end
478
+ end
479
+
480
+ def kind
481
+ if self.static?
482
+ Java::OrgMirahJvmTypes::MemberKind::STATIC_FIELD_ASSIGN
483
+ else
484
+ Java::OrgMirahJvmTypes::MemberKind::FIELD_ASSIGN
485
+ end
486
+ end
411
487
  end
412
488
 
413
489
  class MirahMember
@@ -433,9 +509,19 @@ module Mirah::JVM::Types
433
509
  def abstract?
434
510
  @declaring_class.interface?
435
511
  end
512
+
513
+ def varargs?
514
+ false
515
+ end
516
+
517
+ def isVararg
518
+ varargs?
519
+ end
436
520
  end
437
521
 
438
522
  class Type
523
+ java_import "org.mirah.jvm.types.JVMMethod" rescue nil
524
+
439
525
  def method_listeners
440
526
  if meta?
441
527
  unmeta.method_listeners
@@ -465,7 +551,7 @@ module Mirah::JVM::Types
465
551
  else
466
552
  listeners[block] = block
467
553
  end
468
- if !self.meta? && jvm_type && superclass && !superclass.isError
554
+ if !self.meta? && jvm_type && super_class_valid?
469
555
  superclass.add_method_listener(name, self)
470
556
  end
471
557
  interfaces.each {|i| i.add_method_listener(name, self) unless i.isError}
@@ -473,27 +559,17 @@ module Mirah::JVM::Types
473
559
 
474
560
  # TODO take a scope and check visibility
475
561
  def find_callable_macros(name)
476
- interfaces = []
477
- macros = find_callable_macros2(name, interfaces)
478
- seen = {}
479
- until interfaces.empty?
480
- interface = interfaces.pop
481
- next if seen[interface] || interface.isError
482
- seen[interface] = true
483
- interfaces.concat(interface.interfaces)
484
- macros.concat(interface.declared_macros(name))
485
- end
562
+ macros = find_callable_macros2 name
563
+ macros.concat collect_up_interface_tree {|interface| interface.declared_macros(name) }
486
564
  macros
487
565
  end
488
566
 
489
- def find_callable_macros2(name, interfaces)
490
- macros = []
491
- interfaces.concat(self.interfaces)
492
- macros.concat(declared_macros(name))
493
- if superclass && !superclass.error?
494
- macros.concat(superclass.find_callable_macros2(name, interfaces))
495
- end
496
- macros
567
+ def find_callable_macros2(name)
568
+ collect_up_inheritance_tree {|type| type.declared_macros name }
569
+ end
570
+
571
+ def find_callable_static_methods(name)
572
+ collect_up_inheritance_tree { |type| type.declared_class_methods(name) }
497
573
  end
498
574
 
499
575
  # TODO take a scope and check visibility
@@ -503,33 +579,17 @@ module Mirah::JVM::Types
503
579
  proc.call(find_callable_methods(name))
504
580
  return
505
581
  end
506
- interfaces = if self.interface? || include_interfaces # TODO || self.abstract?
507
- []
508
- else
509
- nil
510
- end
511
- methods = find_callable_methods2(name, interfaces)
512
- if interfaces
513
- seen = {}
514
- until interfaces.empty?
515
- interface = interfaces.pop
516
- next if seen[interface]
517
- seen[interface] = true
518
- interfaces.concat(interface.interfaces)
519
- methods.concat(interface.declared_instance_methods(name))
520
- end
582
+
583
+ methods = find_callable_methods2 name
584
+
585
+ if self.interface? || include_interfaces # TODO || self.abstract?
586
+ methods.concat collect_up_interface_tree { |interface| interface.declared_instance_methods(name) }
521
587
  end
522
588
  methods
523
589
  end
524
590
 
525
- def find_callable_methods2(name, interfaces)
526
- methods = []
527
- interfaces.concat(self.interfaces) if interfaces
528
- methods.concat(declared_instance_methods(name))
529
- if superclass && !superclass.error?
530
- methods.concat(superclass.find_callable_methods2(name, interfaces))
531
- end
532
- methods
591
+ def find_callable_methods2(name)
592
+ collect_up_inheritance_tree { |type| type.declared_instance_methods(name) }
533
593
  end
534
594
 
535
595
  def get_method(name, args)
@@ -547,8 +607,7 @@ module Mirah::JVM::Types
547
607
 
548
608
  def constructor(*types)
549
609
  begin
550
- descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
551
- constructor = jvm_type.getConstructor(*descriptors)
610
+ constructor = jvm_type.getConstructor(*bitescript_signatures(types))
552
611
  return JavaConstructor.new(@type_system, constructor) if constructor
553
612
  rescue => ex
554
613
  log("#{ex.message}\n#{ex.backtrace.join("\n")}")
@@ -559,13 +618,9 @@ module Mirah::JVM::Types
559
618
  def java_method(name, *types)
560
619
  intrinsic = intrinsics[name][types]
561
620
  return intrinsic if intrinsic
562
- jvm_types = types.map {|type| type.jvm_type}
563
-
564
- return JavaDynamicMethod.new(@type_system, name, *jvm_types) if dynamic?
565
621
 
566
622
  begin
567
- descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
568
- method = jvm_type.getDeclaredMethod(name, *descriptors) if jvm_type
623
+ method = jvm_type.getDeclaredMethod(name, *bitescript_signatures(types)) if jvm_type
569
624
 
570
625
  if method.nil? && superclass
571
626
  method = superclass.java_method(name, *types) rescue nil
@@ -580,8 +635,7 @@ module Mirah::JVM::Types
580
635
 
581
636
  return method if method.kind_of?(JavaCallable)
582
637
  if method && method.static? == meta?
583
- return JavaStaticMethod.new(@type_system, method) if method.static?
584
- return JavaMethod.new(@type_system, method)
638
+ return wrap_jvm_method method
585
639
  end
586
640
  rescue => ex
587
641
  log("#{ex.message}\n#{ex.backtrace.join("\n")}")
@@ -590,23 +644,13 @@ module Mirah::JVM::Types
590
644
  end
591
645
 
592
646
  def declared_instance_methods(name=nil)
593
- methods = []
594
- if jvm_type && !array?
595
- jvm_type.getDeclaredMethods(name).each do |method|
596
- methods << JavaMethod.new(@type_system, method) unless method.static?
597
- end
598
- end
599
- methods.concat((meta? ? unmeta : self).declared_intrinsics(name))
647
+ all_declared_jvm_methods(name).reject{ |method| method.static? && !method.synthetic? } +
648
+ (meta? ? unmeta : self).declared_intrinsics(name)
600
649
  end
601
650
 
602
651
  def declared_class_methods(name=nil)
603
- methods = []
604
- if jvm_type && !unmeta.array?
605
- jvm_type.getDeclaredMethods(name).each do |method|
606
- methods << JavaStaticMethod.new(@type_system, method) if method.static?
607
- end
608
- end
609
- methods.concat(meta.declared_intrinsics(name))
652
+ all_declared_jvm_methods(name).select{ |method| method.static? && !method.synthetic? } +
653
+ meta.declared_intrinsics(name)
610
654
  end
611
655
 
612
656
  def declared_constructors
@@ -616,38 +660,130 @@ module Mirah::JVM::Types
616
660
  end
617
661
 
618
662
  def field_getter(name)
619
- if jvm_type
620
- field = jvm_type.getField(name)
621
- JavaFieldGetter.new(@type_system, field) if field
622
- else
623
- nil
624
- end
663
+ field = jvm_field(name)
664
+ return nil unless field
665
+
666
+ JavaFieldGetter.new(@type_system, field)
625
667
  end
626
668
 
627
669
  def field_setter(name)
628
- if jvm_type
629
- field = jvm_type.getField(name)
630
- JavaFieldSetter.new(@type_system, field) if field
631
- else
632
- nil
633
- end
670
+ field = jvm_field(name)
671
+ return nil unless field
672
+
673
+ JavaFieldSetter.new(@type_system, field)
634
674
  end
635
675
 
636
676
  def inner_class_getter(name)
637
677
  full_name = "#{self.name}$#{name}"
638
- inner_class = nil # @type_system.type(nil, full_name) rescue nil
678
+ inner_class = @type_system.type(nil, full_name) rescue nil
639
679
  return unless inner_class
680
+
640
681
  inner_class.inner_class = true
641
- add_macro(name) do |transformer, call|
642
- Mirah::AST::Constant.new(call.parent, call.position, full_name)
682
+ macro = Macro.new(self, name, []) do |call, typer|
683
+ Mirah::AST::Constant.new(call.position, Mirah::AST::SimpleString.new(call.position, full_name))
643
684
  end
644
- intrinsics[name][[]]
685
+ intrinsics[name][[]] = macro
686
+ end
687
+
688
+ def getDeclaredFields
689
+ @member.getDeclaredFields.to_java(JVMMethod)
690
+ end
691
+
692
+ def getDeclaredField(name)
693
+ @member.getDeclaredField(name)
694
+ end
695
+
696
+ def hasStaticField(name)
697
+ f = getDeclaredField(name)
698
+ f && f.static?
699
+ end
700
+
701
+ protected
702
+
703
+ def find_interfaces
704
+ collect_up_inheritance_tree {|type| type.interfaces }
705
+ end
706
+
707
+ def collect_up_interface_tree &block
708
+ interfaces = find_interfaces
709
+ things = []
710
+ seen = {}
711
+ until interfaces.empty?
712
+ interface = interfaces.pop
713
+ next if seen[interface]
714
+ next if interface.isError
715
+ seen[interface] = true
716
+ interfaces.concat(interface.interfaces)
717
+ new_things = block.call interface
718
+ things.concat new_things if new_things
719
+ end
720
+ things
721
+ end
722
+
723
+ def collect_up_inheritance_tree(&block)
724
+ things = []
725
+ new_things = block.call(self)
726
+ things.concat new_things if new_things
727
+ if super_class_valid?
728
+ things.concat superclass.collect_up_inheritance_tree(&block)
729
+ end
730
+ things
731
+ end
732
+
733
+ private
734
+
735
+ def super_class_valid?
736
+ superclass && !superclass.error?
737
+ end
738
+
739
+ def all_declared_jvm_methods(name=nil)
740
+ return [] if !jvm_type || (meta? ? unmeta : self).array?
741
+
742
+ jvm_type.getDeclaredMethods(name).map { |method| wrap_jvm_method method }
743
+ end
744
+
745
+ def wrap_jvm_method method
746
+ if (method.static? && !method.synthetic?)
747
+ JavaStaticMethod.new(@type_system, method)
748
+ else
749
+ JavaMethod.new(@type_system, method)
750
+ end
751
+ end
752
+
753
+ def jvm_field(name)
754
+ return nil unless jvm_type
755
+ field = jvm_type.getField(name)
756
+ field ||= begin
757
+ ifaces = jvm_type.interfaces.map { |i| wrap_with_mirror i }
758
+ ifaces.map{|i| i.getField(name) }.compact.first
759
+ end
760
+ field ||= begin
761
+ mirror = wrap_with_mirror jvm_type.superclass
762
+ potential, mirror = [mirror.getField(name), wrap_with_mirror(mirror.superclass)] until potential || mirror.nil?
763
+ potential
764
+ end
765
+ field
766
+ end
767
+
768
+ def wrap_with_mirror type
769
+ return unless type
770
+ if type.respond_to?(:getField)
771
+ type
772
+ else
773
+ BiteScript::ASM::ClassMirror.for_name type.class_name
774
+ end
775
+ end
776
+
777
+ def bitescript_signatures types
778
+ types.map {|type| BiteScript::Signature.class_id(type)}
645
779
  end
646
780
  end
647
781
 
648
782
  class TypeDefinition
783
+ java_import "org.mirah.jvm.types.JVMMethod" rescue nil
784
+
649
785
  def java_method(name, *types)
650
- method = instance_methods[name].find {|m| m.argument_types == types}
786
+ method = first_matching instance_methods[name], types
651
787
  return method if method
652
788
  intrinsic = intrinsics[name][types]
653
789
  return intrinsic if intrinsic
@@ -655,7 +791,7 @@ module Mirah::JVM::Types
655
791
  end
656
792
 
657
793
  def java_static_method(name, *types)
658
- method = static_methods[name].find {|m| m.argument_types == types}
794
+ method = first_matching static_methods[name], types
659
795
  return method if method
660
796
  intrinsic = meta.intrinsics[name][types]
661
797
  return intrinsic if intrinsic
@@ -663,29 +799,17 @@ module Mirah::JVM::Types
663
799
  end
664
800
 
665
801
  def constructor(*types)
666
- constructor = constructors.find {|c| c.argument_types == types}
802
+ constructor = first_matching constructors, types
667
803
  return constructor if constructor
668
804
  raise NameError, "No constructor #{name}(#{types.join ', '})"
669
805
  end
670
806
 
671
807
  def declared_instance_methods(name=nil)
672
- declared_intrinsics(name) + if name.nil?
673
- instance_methods.values.flatten
674
- else
675
- instance_methods[name]
676
- end
808
+ declared_methods self, instance_methods, name
677
809
  end
678
810
 
679
811
  def declared_class_methods(name=nil)
680
- meta.declared_intrinsics(name) + if name.nil?
681
- static_methods.values.flatten
682
- else
683
- static_methods[name]
684
- end
685
- end
686
-
687
- def declared_constructors
688
- constructors
812
+ declared_methods meta, static_methods, name
689
813
  end
690
814
 
691
815
  def constructors
@@ -696,6 +820,7 @@ module Mirah::JVM::Types
696
820
  end
697
821
  @constructors
698
822
  end
823
+ alias :declared_constructors :constructors
699
824
 
700
825
  def instance_methods
701
826
  @instance_methods ||= Hash.new {|h, k| h[k] = []}
@@ -704,6 +829,31 @@ module Mirah::JVM::Types
704
829
  def static_methods
705
830
  @static_methods ||= Hash.new {|h, k| h[k] = []}
706
831
  end
832
+
833
+ def getDeclaredFields
834
+ @fields.values.to_java(JVMMethod)
835
+ end
836
+
837
+ def getDeclaredField(name)
838
+ @fields[name]
839
+ end
840
+
841
+ def hasStaticField(name)
842
+ f = getDeclaredField(name)
843
+ f && f.static?
844
+ end
845
+
846
+ def declared_fields
847
+ @fields ||= {}
848
+ end
849
+
850
+ def declare_field(name, type, static)
851
+ if type.isError
852
+ declared_fields.delete(name)
853
+ return
854
+ end
855
+ declared_fields[name] ||= MirahMember.new(self, name, [], type, static, [])
856
+ end
707
857
 
708
858
  def declare_method(name, arguments, type, exceptions)
709
859
  raise "Bad args" unless arguments.all?
@@ -750,6 +900,22 @@ module Mirah::JVM::Types
750
900
  def field_setter(name)
751
901
  nil
752
902
  end
903
+
904
+ private
905
+
906
+ def declared_methods target, method_hash, name
907
+ # should the declared intrinsics be first here? nh
908
+ target.declared_intrinsics(name) +
909
+ if name.nil?
910
+ method_hash.values.flatten
911
+ else
912
+ method_hash[name]
913
+ end
914
+ end
915
+
916
+ def first_matching method_list, types
917
+ method_list.find {|m| m.argument_types == types}
918
+ end
753
919
  end
754
920
 
755
921
  class TypeDefMeta