mirah 0.0.12-java → 0.1.0-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.
- data/History.txt +372 -0
- data/README.txt +4 -5
- data/Rakefile +178 -55
- data/examples/appengine/Readme +3 -3
- data/examples/appengine/src/org/mirah/MirahApp.mirah +1 -1
- data/examples/appengine/src/org/mirah/list.dhtml +1 -1
- data/examples/bintrees.mirah +1 -1
- data/examples/edb.mirah +1 -1
- data/examples/fib.mirah +1 -1
- data/examples/interfaces.mirah +1 -1
- data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +4 -5
- data/examples/maven/README.txt +1 -1
- data/examples/maven/src/main/mirah/hello_mirah.mirah +1 -1
- data/examples/plugins/appengine/Rakefile +1 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +1 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +1 -1
- data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +1 -1
- data/examples/rosettacode/100-doors.mirah +6 -6
- data/examples/rosettacode/README.txt +3 -3
- data/examples/rosettacode/boolean-values.mirah +1 -1
- data/examples/rosettacode/comments.mirah +1 -1
- data/examples/rosettacode/count-occurrences-of-a-substring.mirah +1 -1
- data/examples/rosettacode/factorial.mirah +1 -1
- data/examples/rosettacode/fibonacci.mirah +1 -1
- data/examples/rosettacode/fizz-buzz.mirah +2 -2
- data/examples/rosettacode/flatten-a-list.mirah +4 -4
- data/examples/rosettacode/guess-the-number.mirah +2 -2
- data/examples/rosettacode/hamming-numbers.mirah +4 -4
- data/examples/rosettacode/is-string-numeric.mirah +22 -22
- data/examples/rosettacode/palindrome.mirah +2 -2
- data/examples/rosettacode/random-numbers.mirah +1 -1
- data/examples/rosettacode/repeat-a-string.mirah +1 -1
- data/examples/rosettacode/reverse-a-string.mirah +1 -1
- data/examples/rosettacode/rot-13.mirah +5 -5
- data/examples/rosettacode/secure-temporary-file.mirah +2 -2
- data/examples/rosettacode/sleep.mirah +1 -1
- data/examples/rosettacode/string-length.mirah +5 -5
- data/examples/swing.mirah +1 -1
- data/examples/test.edb +1 -1
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-builtins.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/javalib/mirah-util.jar +0 -0
- data/lib/duby.rb +1 -1
- data/lib/mirah.rb +50 -28
- data/lib/mirah/ast.rb +15 -605
- data/lib/mirah/ast/scope.rb +98 -69
- data/lib/mirah/commands.rb +1 -1
- data/lib/mirah/commands/base.rb +7 -7
- data/lib/mirah/commands/compile.rb +3 -3
- data/lib/mirah/commands/parse.rb +7 -5
- data/lib/mirah/commands/run.rb +12 -19
- data/lib/mirah/compiler.rb +15 -23
- data/lib/mirah/errors.rb +16 -1
- data/lib/mirah/generator.rb +79 -39
- data/lib/mirah/jvm/compiler.rb +1 -19
- data/lib/mirah/jvm/compiler/base.rb +233 -90
- data/lib/mirah/jvm/compiler/jvm_bytecode.rb +675 -363
- data/lib/mirah/jvm/method_lookup.rb +134 -65
- data/lib/mirah/jvm/typer.rb +10 -5
- data/lib/mirah/jvm/types.rb +10 -2
- data/lib/mirah/jvm/types/array_type.rb +10 -12
- data/lib/mirah/{compiler/type.rb → jvm/types/ast_ext.rb} +12 -8
- data/lib/mirah/jvm/types/basic_types.rb +26 -33
- data/lib/mirah/jvm/types/bitescript_ext.rb +1 -1
- data/lib/mirah/jvm/types/block_type.rb +15 -0
- data/lib/mirah/jvm/types/boolean.rb +8 -4
- data/lib/mirah/jvm/types/dynamic_type.rb +12 -13
- data/lib/mirah/jvm/types/enumerable.rb +7 -7
- data/lib/mirah/jvm/types/extensions.rb +11 -6
- data/lib/mirah/jvm/types/factory.rb +624 -94
- data/lib/mirah/jvm/types/floats.rb +21 -15
- data/lib/mirah/jvm/types/generic_type.rb +72 -0
- data/lib/mirah/jvm/types/implicit_nil_type.rb +29 -0
- data/lib/mirah/jvm/types/integers.rb +26 -71
- data/lib/mirah/jvm/types/interface_definition.rb +3 -3
- data/lib/mirah/jvm/types/intrinsics.rb +203 -168
- data/lib/mirah/jvm/types/literals.rb +6 -6
- data/lib/mirah/jvm/types/meta_type.rb +13 -4
- data/lib/mirah/jvm/types/methods.rb +281 -93
- data/lib/mirah/jvm/types/null_type.rb +17 -5
- data/lib/mirah/jvm/types/number.rb +10 -7
- data/lib/mirah/jvm/types/primitive_type.rb +17 -6
- data/lib/mirah/jvm/types/source_mirror.rb +12 -7
- data/lib/mirah/jvm/types/type.rb +107 -23
- data/lib/mirah/jvm/types/type_definition.rb +25 -10
- data/lib/mirah/jvm/types/unreachable_type.rb +1 -1
- data/lib/mirah/jvm/types/void_type.rb +3 -3
- data/lib/mirah/parser.rb +154 -16
- data/lib/mirah/plugin/edb.rb +1 -1
- data/lib/mirah/transform.rb +1 -2
- data/lib/mirah/transform/ast_ext.rb +24 -43
- data/lib/mirah/transform/transformer.rb +29 -224
- data/lib/mirah/typer.rb +2 -16
- data/lib/mirah/util/argument_processor.rb +25 -10
- data/lib/mirah/util/class_loader.rb +1 -1
- data/lib/mirah/util/compilation_state.rb +16 -17
- data/lib/mirah/util/delegate.rb +2 -2
- data/lib/mirah/util/logging.rb +110 -0
- data/lib/mirah/util/process_errors.rb +69 -11
- data/lib/mirah/version.rb +1 -1
- data/test/core/commands_test.rb +6 -24
- data/test/core/env_test.rb +5 -5
- data/{lib/mirah/jvm/source_generator/typer.rb → test/core/generator_test.rb} +9 -9
- data/test/core/typer_test.rb +196 -158
- data/test/core/util/argument_processor_test.rb +10 -10
- data/test/core/util/class_loader_test.rb +6 -5
- data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
- data/test/jvm/annotations_test.rb +5 -5
- data/test/jvm/blocks_test.rb +140 -88
- data/test/jvm/bytecode_test_helper.rb +112 -94
- data/test/jvm/cast_test.rb +162 -0
- data/test/jvm/constructors_test.rb +18 -8
- data/test/jvm/enumerable_test.rb +77 -44
- data/test/jvm/example_test.rb +53 -0
- data/test/jvm/factory_test.rb +7 -1
- data/test/jvm/generics_test.rb +57 -0
- data/test/jvm/hash_test.rb +106 -0
- data/test/jvm/import_test.rb +81 -0
- data/test/jvm/interface_test.rb +73 -0
- data/test/jvm/java_typer_test.rb +92 -66
- data/{lib/mirah/typer/base.rb → test/jvm/jvm_commands_test.rb} +6 -10
- data/test/jvm/jvm_compiler_test.rb +170 -604
- data/test/jvm/list_extensions_test.rb +23 -0
- data/test/jvm/macros_test.rb +197 -32
- data/test/jvm/main_method_test.rb +4 -4
- data/test/jvm/numeric_extensions_test.rb +13 -0
- data/test/jvm/rescue_test.rb +73 -16
- data/test/jvm/varargs_test.rb +65 -0
- data/test/test_helper.rb +1 -2
- metadata +234 -251
- data/examples/SortClosure$__xform_tmp_1.class +0 -0
- data/examples/SortClosure$__xform_tmp_2.class +0 -0
- data/examples/SortClosure.class +0 -0
- data/examples/macros/StringEachChar$Extension1.class +0 -0
- data/lib/mirah/ast/call.rb +0 -345
- data/lib/mirah/ast/class.rb +0 -359
- data/lib/mirah/ast/flow.rb +0 -381
- data/lib/mirah/ast/intrinsics.rb +0 -563
- data/lib/mirah/ast/literal.rb +0 -178
- data/lib/mirah/ast/local.rb +0 -112
- data/lib/mirah/ast/method.rb +0 -408
- data/lib/mirah/ast/structure.rb +0 -387
- data/lib/mirah/ast/type.rb +0 -146
- data/lib/mirah/commands/base.rb~ +0 -57
- data/lib/mirah/compiler/call.rb +0 -45
- data/lib/mirah/compiler/class.rb +0 -81
- data/lib/mirah/compiler/flow.rb +0 -109
- data/lib/mirah/compiler/literal.rb +0 -130
- data/lib/mirah/compiler/local.rb +0 -59
- data/lib/mirah/compiler/method.rb +0 -44
- data/lib/mirah/compiler/structure.rb +0 -65
- data/lib/mirah/jvm/compiler/java_source.rb +0 -787
- data/lib/mirah/jvm/method_lookup.rb~ +0 -247
- data/lib/mirah/jvm/source_generator/builder.rb +0 -468
- data/lib/mirah/jvm/source_generator/loops.rb +0 -131
- data/lib/mirah/jvm/source_generator/precompile.rb +0 -210
- data/lib/mirah/plugin/gwt.rb +0 -189
- data/lib/mirah/plugin/java.rb +0 -70
- data/lib/mirah/transform/error.rb +0 -13
- data/lib/mirah/transform/helper.rb +0 -765
- data/lib/mirah/typer/simple.rb +0 -384
- data/lib/mirah/version.rb~ +0 -18
- data/test/core/ast_test.rb +0 -382
- data/test/core/compilation_test.rb +0 -130
- data/test/core/macros_test.rb +0 -61
- data/test/jvm/javac_test_helper.rb +0 -89
- data/test/jvm/jvm_compiler_test.rb~ +0 -2181
- data/test/plugins/gwt_test.rb +0 -69
|
@@ -24,7 +24,7 @@ module Mirah::JVM::Types
|
|
|
24
24
|
super(default_type)
|
|
25
25
|
@narrowed = default_type != narrowed_type && narrowed_type
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
def hash
|
|
29
29
|
__getobj__.hash
|
|
30
30
|
end
|
|
@@ -38,12 +38,12 @@ module Mirah::JVM::Types
|
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
class FixnumLiteral < NarrowingType
|
|
43
43
|
def self.range(type)
|
|
44
44
|
type::MIN_VALUE .. type::MAX_VALUE
|
|
45
45
|
end
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
BYTE_RANGE = range(java.lang.Byte)
|
|
48
48
|
SHORT_RANGE = range(java.lang.Short)
|
|
49
49
|
INT_RANGE = range(java.lang.Integer)
|
|
@@ -56,7 +56,7 @@ module Mirah::JVM::Types
|
|
|
56
56
|
else
|
|
57
57
|
Long
|
|
58
58
|
end
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
# TODO chars?
|
|
61
61
|
# There's not really any way to tell if we should narrow to a char
|
|
62
62
|
# or a byte/short. I suppose we could try both, but that seems ugly.
|
|
@@ -71,7 +71,7 @@ module Mirah::JVM::Types
|
|
|
71
71
|
else
|
|
72
72
|
Long
|
|
73
73
|
end
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
super(default_type, narrowed_type)
|
|
76
76
|
end
|
|
77
77
|
end
|
|
@@ -86,4 +86,4 @@ module Mirah::JVM::Types
|
|
|
86
86
|
super(Double, Double)
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
|
-
end
|
|
89
|
+
end
|
|
@@ -5,7 +5,7 @@ module Mirah
|
|
|
5
5
|
attr_reader :unmeta
|
|
6
6
|
|
|
7
7
|
def initialize(unmeta)
|
|
8
|
-
|
|
8
|
+
super(unmeta.type_system, unmeta.name)
|
|
9
9
|
@unmeta = unmeta
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -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
|
|
@@ -22,10 +27,14 @@ module Mirah
|
|
|
22
27
|
end
|
|
23
28
|
|
|
24
29
|
def superclass
|
|
25
|
-
|
|
30
|
+
if @unmeta.superclass
|
|
31
|
+
@unmeta.superclass.meta
|
|
32
|
+
else
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
26
35
|
end
|
|
27
36
|
|
|
28
|
-
def interfaces
|
|
37
|
+
def interfaces(include_parent=true)
|
|
29
38
|
[]
|
|
30
39
|
end
|
|
31
40
|
|
|
@@ -42,4 +51,4 @@ module Mirah
|
|
|
42
51
|
end
|
|
43
52
|
end
|
|
44
53
|
end
|
|
45
|
-
end
|
|
54
|
+
end
|
|
@@ -31,14 +31,36 @@ module Mirah::JVM::Types
|
|
|
31
31
|
module ArgumentConversion
|
|
32
32
|
def convert_args(compiler, values, types=nil)
|
|
33
33
|
# TODO boxing/unboxing
|
|
34
|
-
# TODO varargs
|
|
35
34
|
types ||= argument_types
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
needs_to_build_varargs_array = false
|
|
36
|
+
|
|
37
|
+
if respond_to?(:varargs?) && varargs?
|
|
38
|
+
non_varargs_types = types[0..-2]
|
|
39
|
+
non_varargs_values = values.first non_varargs_types.size
|
|
40
|
+
|
|
41
|
+
varargs_values = values.to_a.last(values.size - non_varargs_values.size)
|
|
42
|
+
varargs_type = types.last
|
|
43
|
+
|
|
44
|
+
unless varargs_values.length == 1 &&
|
|
45
|
+
varargs_type.compatible?(compiler.inferred_type(varargs_values.first))
|
|
46
|
+
needs_to_build_varargs_array = true
|
|
47
|
+
values = non_varargs_values
|
|
40
48
|
end
|
|
41
49
|
end
|
|
50
|
+
|
|
51
|
+
values_and_types = values.zip(types)
|
|
52
|
+
|
|
53
|
+
values_and_types.each do |value, type|
|
|
54
|
+
compiler.visit(value, true)
|
|
55
|
+
in_type = compiler.inferred_type(value)
|
|
56
|
+
if in_type.primitive? && type != in_type
|
|
57
|
+
in_type.compile_widen(compiler.method, type)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if needs_to_build_varargs_array
|
|
62
|
+
compiler.visitVarargsArray(varargs_type, varargs_values)
|
|
63
|
+
end
|
|
42
64
|
end
|
|
43
65
|
end
|
|
44
66
|
|
|
@@ -57,8 +79,8 @@ module Mirah::JVM::Types
|
|
|
57
79
|
@block = block
|
|
58
80
|
end
|
|
59
81
|
|
|
60
|
-
def call(builder, ast, expression)
|
|
61
|
-
@block.call(builder, ast, expression)
|
|
82
|
+
def call(builder, ast, expression, *args)
|
|
83
|
+
@block.call(builder, ast, expression, *args)
|
|
62
84
|
end
|
|
63
85
|
|
|
64
86
|
def declaring_class
|
|
@@ -80,14 +102,41 @@ module Mirah::JVM::Types
|
|
|
80
102
|
def exceptions
|
|
81
103
|
[]
|
|
82
104
|
end
|
|
105
|
+
|
|
106
|
+
def varargs?
|
|
107
|
+
false
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
class Macro
|
|
112
|
+
java_import 'org.mirah.typer.InlineCode'
|
|
113
|
+
java_import 'org.mirah.typer.NodeBuilder'
|
|
114
|
+
attr_reader :name, :argument_types, :return_type
|
|
115
|
+
|
|
116
|
+
def initialize(klass, name, args, &block)
|
|
117
|
+
raise ArgumentError, "Block required" unless block_given?
|
|
118
|
+
@class = klass
|
|
119
|
+
@name = name
|
|
120
|
+
@argument_types = args
|
|
121
|
+
raise ArgumentError unless args.all?
|
|
122
|
+
@return_type = InlineCode.new(block.to_java(NodeBuilder))
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def declaring_class
|
|
126
|
+
@class
|
|
127
|
+
end
|
|
83
128
|
end
|
|
84
129
|
|
|
85
130
|
class JavaCallable
|
|
86
131
|
include ArgumentConversion
|
|
132
|
+
java_import 'org.mirah.typer.ResolvedType'
|
|
133
|
+
java_import 'org.mirah.typer.TypeSystem'
|
|
87
134
|
|
|
88
135
|
attr_accessor :member
|
|
89
136
|
|
|
90
|
-
def initialize(member)
|
|
137
|
+
def initialize(types, member)
|
|
138
|
+
raise ArgumentError unless types.kind_of?(TypeSystem)
|
|
139
|
+
@types = types
|
|
91
140
|
@member = member
|
|
92
141
|
end
|
|
93
142
|
|
|
@@ -107,10 +156,10 @@ module Mirah::JVM::Types
|
|
|
107
156
|
class JavaConstructor < JavaCallable
|
|
108
157
|
def argument_types
|
|
109
158
|
@argument_types ||= @member.argument_types.map do |arg|
|
|
110
|
-
if arg.kind_of?(
|
|
159
|
+
if arg.kind_of?(Type) || arg.nil?
|
|
111
160
|
arg
|
|
112
161
|
else
|
|
113
|
-
|
|
162
|
+
@types.type(nil, arg)
|
|
114
163
|
end
|
|
115
164
|
end
|
|
116
165
|
end
|
|
@@ -121,23 +170,30 @@ module Mirah::JVM::Types
|
|
|
121
170
|
|
|
122
171
|
def exceptions
|
|
123
172
|
@member.exception_types.map do |exception|
|
|
124
|
-
if exception.kind_of?(
|
|
173
|
+
if exception.kind_of?(ResolvedType)
|
|
125
174
|
exception
|
|
126
175
|
else
|
|
127
|
-
|
|
176
|
+
@types.type(nil, exception.class_name)
|
|
128
177
|
end
|
|
129
178
|
end
|
|
130
179
|
end
|
|
131
180
|
|
|
132
181
|
def declaring_class
|
|
133
|
-
|
|
182
|
+
@types.type(nil, @member.declaring_class)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def type_parameters
|
|
186
|
+
@declaring_class and @declaring_class.jvm_type.type_parameters
|
|
134
187
|
end
|
|
135
188
|
|
|
136
|
-
def call(compiler, ast, expression)
|
|
137
|
-
target = ast.target
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
189
|
+
def call(compiler, ast, expression, parameters=nil, delegate=false)
|
|
190
|
+
target = compiler.inferred_type(ast.target)
|
|
191
|
+
unless delegate
|
|
192
|
+
compiler.method.new target
|
|
193
|
+
compiler.method.dup if expression
|
|
194
|
+
end
|
|
195
|
+
parameters ||= ast.parameters
|
|
196
|
+
convert_args(compiler, parameters)
|
|
141
197
|
compiler.method.invokespecial(
|
|
142
198
|
target,
|
|
143
199
|
"<init>",
|
|
@@ -147,15 +203,20 @@ module Mirah::JVM::Types
|
|
|
147
203
|
def constructor?
|
|
148
204
|
true
|
|
149
205
|
end
|
|
206
|
+
|
|
207
|
+
def varargs?
|
|
208
|
+
@member.varargs?
|
|
209
|
+
end
|
|
210
|
+
|
|
150
211
|
end
|
|
151
212
|
|
|
152
213
|
class JavaMethod < JavaConstructor
|
|
153
214
|
def return_type
|
|
154
215
|
@return_type ||= begin
|
|
155
216
|
if void?
|
|
156
|
-
|
|
217
|
+
@types.type(nil, 'void')
|
|
157
218
|
else
|
|
158
|
-
|
|
219
|
+
@types.type(nil, @member.return_type)
|
|
159
220
|
end
|
|
160
221
|
end
|
|
161
222
|
end
|
|
@@ -168,6 +229,10 @@ module Mirah::JVM::Types
|
|
|
168
229
|
@member.abstract?
|
|
169
230
|
end
|
|
170
231
|
|
|
232
|
+
def type_parameters
|
|
233
|
+
@member.type_parameters
|
|
234
|
+
end
|
|
235
|
+
|
|
171
236
|
def void?
|
|
172
237
|
return_type = @member.return_type
|
|
173
238
|
return true if return_type.nil?
|
|
@@ -181,9 +246,9 @@ module Mirah::JVM::Types
|
|
|
181
246
|
false
|
|
182
247
|
end
|
|
183
248
|
|
|
184
|
-
def call(compiler, ast, expression)
|
|
185
|
-
target = ast.target
|
|
186
|
-
ast.target
|
|
249
|
+
def call(compiler, ast, expression, parameters=nil)
|
|
250
|
+
target = compiler.inferred_type(ast.target)
|
|
251
|
+
compiler.visit(ast.target, true)
|
|
187
252
|
|
|
188
253
|
# if expression, void methods return the called object,
|
|
189
254
|
# for consistency and chaining
|
|
@@ -193,7 +258,8 @@ module Mirah::JVM::Types
|
|
|
193
258
|
compiler.method.dup
|
|
194
259
|
end
|
|
195
260
|
|
|
196
|
-
|
|
261
|
+
parameters ||= ast.parameters
|
|
262
|
+
convert_args(compiler, parameters)
|
|
197
263
|
if target.interface?
|
|
198
264
|
compiler.method.invokeinterface(
|
|
199
265
|
target,
|
|
@@ -206,14 +272,22 @@ module Mirah::JVM::Types
|
|
|
206
272
|
[@member.return_type, *@member.argument_types])
|
|
207
273
|
end
|
|
208
274
|
|
|
275
|
+
if expression && !void?
|
|
276
|
+
# Insert a cast if the inferred type and actual type differ. This is part of generics support.
|
|
277
|
+
inferred_return_type = compiler.inferred_type(ast)
|
|
278
|
+
if !inferred_return_type.assignableFrom(return_type)
|
|
279
|
+
compiler.method.checkcast(inferred_return_type)
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
209
283
|
unless expression || void?
|
|
210
284
|
return_type.pop(compiler.method)
|
|
211
285
|
end
|
|
212
286
|
end
|
|
213
287
|
|
|
214
|
-
def call_special(compiler,
|
|
215
|
-
|
|
216
|
-
|
|
288
|
+
def call_special(compiler, target, target_type, parameters, expression)
|
|
289
|
+
target_type ||= compiler.inferred_type(target)
|
|
290
|
+
compiler.visit(target, true)
|
|
217
291
|
|
|
218
292
|
# if expression, void methods return the called object,
|
|
219
293
|
# for consistency and chaining
|
|
@@ -223,12 +297,12 @@ module Mirah::JVM::Types
|
|
|
223
297
|
compiler.method.dup
|
|
224
298
|
end
|
|
225
299
|
|
|
226
|
-
convert_args(compiler,
|
|
227
|
-
if
|
|
300
|
+
convert_args(compiler, parameters)
|
|
301
|
+
if target_type.interface?
|
|
228
302
|
raise "interfaces should not receive call_special"
|
|
229
303
|
else
|
|
230
304
|
compiler.method.invokespecial(
|
|
231
|
-
|
|
305
|
+
target_type,
|
|
232
306
|
name,
|
|
233
307
|
[@member.return_type, *@member.argument_types])
|
|
234
308
|
end
|
|
@@ -240,9 +314,10 @@ module Mirah::JVM::Types
|
|
|
240
314
|
end
|
|
241
315
|
|
|
242
316
|
class JavaStaticMethod < JavaMethod
|
|
243
|
-
def call(compiler, ast, expression)
|
|
317
|
+
def call(compiler, ast, expression, parameters=nil)
|
|
244
318
|
target = declaring_class
|
|
245
|
-
|
|
319
|
+
parameters ||= ast.parameters
|
|
320
|
+
convert_args(compiler, parameters)
|
|
246
321
|
compiler.method.invokestatic(
|
|
247
322
|
target,
|
|
248
323
|
name,
|
|
@@ -256,13 +331,14 @@ module Mirah::JVM::Types
|
|
|
256
331
|
end
|
|
257
332
|
|
|
258
333
|
class JavaDynamicMethod < JavaMethod
|
|
259
|
-
def initialize(name, *
|
|
334
|
+
def initialize(type_system, name, *argument_types)
|
|
335
|
+
super(type_system, nil)
|
|
260
336
|
@name = name
|
|
261
|
-
@
|
|
337
|
+
@argument_types = argument_types
|
|
262
338
|
end
|
|
263
339
|
|
|
264
340
|
def return_type
|
|
265
|
-
|
|
341
|
+
@types.type(nil, 'dynamic')
|
|
266
342
|
end
|
|
267
343
|
|
|
268
344
|
def declaring_class
|
|
@@ -270,17 +346,21 @@ module Mirah::JVM::Types
|
|
|
270
346
|
end
|
|
271
347
|
|
|
272
348
|
def argument_types
|
|
273
|
-
@
|
|
349
|
+
@argument_types
|
|
274
350
|
end
|
|
275
351
|
|
|
276
|
-
def call(compiler, ast, expression)
|
|
277
|
-
|
|
278
|
-
|
|
352
|
+
def call(compiler, ast, expression, parameters=nil)
|
|
353
|
+
unless compiler.respond_to?(:supports_invokedynamic?) && compiler.supports_invokedynamic?
|
|
354
|
+
raise Mirah::MirahError, "Target JVM version: #{compiler.target_jvm_version} doesn't support invoke dynamic"
|
|
355
|
+
end
|
|
356
|
+
target = compiler.inferred_type(ast.target)
|
|
357
|
+
compiler.visit(ast.target, true)
|
|
279
358
|
|
|
280
|
-
ast.parameters
|
|
281
|
-
|
|
359
|
+
parameters ||= ast.parameters
|
|
360
|
+
parameters.each do |param|
|
|
361
|
+
compiler.visit(param, true)
|
|
282
362
|
end
|
|
283
|
-
handle = compiler.method.
|
|
363
|
+
handle = compiler.method.h_invokestatic(
|
|
284
364
|
org.dynalang.dynalink.DefaultBootstrapper,
|
|
285
365
|
"bootstrap",
|
|
286
366
|
java.lang.invoke.CallSite,
|
|
@@ -289,7 +369,7 @@ module Mirah::JVM::Types
|
|
|
289
369
|
java.lang.invoke.MethodType)
|
|
290
370
|
compiler.method.invokedynamic(
|
|
291
371
|
"dyn:callPropWithThis:#{name}",
|
|
292
|
-
[return_type, target, *@
|
|
372
|
+
[return_type, target, *@argument_types],
|
|
293
373
|
handle)
|
|
294
374
|
|
|
295
375
|
unless expression
|
|
@@ -304,7 +384,7 @@ module Mirah::JVM::Types
|
|
|
304
384
|
end
|
|
305
385
|
|
|
306
386
|
def return_type
|
|
307
|
-
|
|
387
|
+
@types.type(nil, @member.type)
|
|
308
388
|
end
|
|
309
389
|
|
|
310
390
|
def public?
|
|
@@ -321,8 +401,8 @@ module Mirah::JVM::Types
|
|
|
321
401
|
[]
|
|
322
402
|
end
|
|
323
403
|
|
|
324
|
-
def call(compiler, ast, expression)
|
|
325
|
-
target = ast.target
|
|
404
|
+
def call(compiler, ast, expression, parameters=nil)
|
|
405
|
+
target = compiler.inferred_type(ast.target)
|
|
326
406
|
|
|
327
407
|
# TODO: assert that no args are being passed, though that should have failed lookup
|
|
328
408
|
|
|
@@ -330,7 +410,7 @@ module Mirah::JVM::Types
|
|
|
330
410
|
if @member.static?
|
|
331
411
|
compiler.method.getstatic(target, name, @member.type)
|
|
332
412
|
else
|
|
333
|
-
ast.target
|
|
413
|
+
compiler.visit(ast.target, true)
|
|
334
414
|
compiler.method.getfield(target, name, @member.type)
|
|
335
415
|
end
|
|
336
416
|
end
|
|
@@ -339,25 +419,26 @@ module Mirah::JVM::Types
|
|
|
339
419
|
|
|
340
420
|
class JavaFieldSetter < JavaFieldAccessor
|
|
341
421
|
def return_type
|
|
342
|
-
|
|
422
|
+
@types.type(nil, @member.type)
|
|
343
423
|
end
|
|
344
424
|
|
|
345
425
|
def argument_types
|
|
346
|
-
[
|
|
426
|
+
[@types.type(nil, @member.type)]
|
|
347
427
|
end
|
|
348
428
|
|
|
349
|
-
def call(compiler, ast, expression)
|
|
350
|
-
target = ast.target
|
|
429
|
+
def call(compiler, ast, expression, parameters=nil)
|
|
430
|
+
target = compiler.inferred_type(ast.target)
|
|
351
431
|
|
|
352
432
|
# TODO: assert that no args are being passed, though that should have failed lookup
|
|
353
433
|
|
|
434
|
+
parameters ||= ast.parameters
|
|
354
435
|
if @member.static?
|
|
355
|
-
convert_args(compiler,
|
|
436
|
+
convert_args(compiler, parameters)
|
|
356
437
|
compiler.method.dup if expression
|
|
357
438
|
compiler.method.putstatic(target, name, @member.type)
|
|
358
439
|
else
|
|
359
|
-
ast.target
|
|
360
|
-
convert_args(compiler,
|
|
440
|
+
compiler.visit(ast.target, true)
|
|
441
|
+
convert_args(compiler, parameters)
|
|
361
442
|
compiler.method.dup_x2 if expression
|
|
362
443
|
compiler.method.putfield(target, name, @member.type)
|
|
363
444
|
end
|
|
@@ -369,7 +450,7 @@ module Mirah::JVM::Types
|
|
|
369
450
|
attr_reader :exception_types
|
|
370
451
|
|
|
371
452
|
def initialize(klass, name, args, return_type, static, exceptions)
|
|
372
|
-
if return_type ==
|
|
453
|
+
if return_type.name == 'void' || return_type.name == ':unreachable'
|
|
373
454
|
return_type = nil
|
|
374
455
|
end
|
|
375
456
|
@declaring_class = klass
|
|
@@ -387,11 +468,111 @@ module Mirah::JVM::Types
|
|
|
387
468
|
def abstract?
|
|
388
469
|
@declaring_class.interface?
|
|
389
470
|
end
|
|
471
|
+
|
|
472
|
+
def varargs?
|
|
473
|
+
false
|
|
474
|
+
end
|
|
390
475
|
end
|
|
391
476
|
|
|
392
477
|
class Type
|
|
478
|
+
def method_listeners
|
|
479
|
+
if meta?
|
|
480
|
+
unmeta.method_listeners
|
|
481
|
+
else
|
|
482
|
+
@method_listeners ||= {}
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
def method_updated(name)
|
|
487
|
+
listeners = method_listeners[name]
|
|
488
|
+
listeners.values.each do |l|
|
|
489
|
+
if l.kind_of?(Proc)
|
|
490
|
+
l.call(name)
|
|
491
|
+
else
|
|
492
|
+
l.method_updated(name)
|
|
493
|
+
end
|
|
494
|
+
end if listeners
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
def add_method_listener(name, listener=nil, &block)
|
|
498
|
+
listeners = method_listeners[name] ||= {}
|
|
499
|
+
if listener
|
|
500
|
+
unless listener.respond_to?(:method_updated) || listener.kind_of?(Proc)
|
|
501
|
+
raise "Invalid listener"
|
|
502
|
+
end
|
|
503
|
+
listeners[listener] = listener
|
|
504
|
+
else
|
|
505
|
+
listeners[block] = block
|
|
506
|
+
end
|
|
507
|
+
if !self.meta? && jvm_type && superclass && !superclass.isError
|
|
508
|
+
superclass.add_method_listener(name, self)
|
|
509
|
+
end
|
|
510
|
+
interfaces.each {|i| i.add_method_listener(name, self) unless i.isError}
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
# TODO take a scope and check visibility
|
|
514
|
+
def find_callable_macros(name)
|
|
515
|
+
interfaces = []
|
|
516
|
+
macros = find_callable_macros2(name, interfaces)
|
|
517
|
+
seen = {}
|
|
518
|
+
until interfaces.empty?
|
|
519
|
+
interface = interfaces.pop
|
|
520
|
+
next if seen[interface] || interface.isError
|
|
521
|
+
seen[interface] = true
|
|
522
|
+
interfaces.concat(interface.interfaces)
|
|
523
|
+
macros.concat(interface.declared_macros(name))
|
|
524
|
+
end
|
|
525
|
+
macros
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
def find_callable_macros2(name, interfaces)
|
|
529
|
+
macros = []
|
|
530
|
+
interfaces.concat(self.interfaces)
|
|
531
|
+
macros.concat(declared_macros(name))
|
|
532
|
+
if superclass && !superclass.error?
|
|
533
|
+
macros.concat(superclass.find_callable_macros2(name, interfaces))
|
|
534
|
+
end
|
|
535
|
+
macros
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
# TODO take a scope and check visibility
|
|
539
|
+
def find_callable_methods(name, include_interfaces=false, &proc)
|
|
540
|
+
if block_given?
|
|
541
|
+
add_method_listener(name) {proc.call(find_callable_methods(name))}
|
|
542
|
+
proc.call(find_callable_methods(name))
|
|
543
|
+
return
|
|
544
|
+
end
|
|
545
|
+
interfaces = if self.interface? || include_interfaces # TODO || self.abstract?
|
|
546
|
+
[]
|
|
547
|
+
else
|
|
548
|
+
nil
|
|
549
|
+
end
|
|
550
|
+
methods = find_callable_methods2(name, interfaces)
|
|
551
|
+
if interfaces
|
|
552
|
+
seen = {}
|
|
553
|
+
until interfaces.empty?
|
|
554
|
+
interface = interfaces.pop
|
|
555
|
+
next if seen[interface]
|
|
556
|
+
seen[interface] = true
|
|
557
|
+
interfaces.concat(interface.interfaces)
|
|
558
|
+
methods.concat(interface.declared_instance_methods(name))
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
methods
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
def find_callable_methods2(name, interfaces)
|
|
565
|
+
methods = []
|
|
566
|
+
interfaces.concat(self.interfaces) if interfaces
|
|
567
|
+
methods.concat(declared_instance_methods(name))
|
|
568
|
+
if superclass && !superclass.error?
|
|
569
|
+
methods.concat(superclass.find_callable_methods2(name, interfaces))
|
|
570
|
+
end
|
|
571
|
+
methods
|
|
572
|
+
end
|
|
573
|
+
|
|
393
574
|
def get_method(name, args)
|
|
394
|
-
method = find_method(self, name, args, meta?)
|
|
575
|
+
method = find_method(self, name, args, nil, meta?)
|
|
395
576
|
unless method
|
|
396
577
|
# Allow constant narrowing for assignment methods
|
|
397
578
|
if name =~ /=$/ && args[-1].respond_to?(:narrow!)
|
|
@@ -407,9 +588,9 @@ module Mirah::JVM::Types
|
|
|
407
588
|
begin
|
|
408
589
|
descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
|
|
409
590
|
constructor = jvm_type.getConstructor(*descriptors)
|
|
410
|
-
return JavaConstructor.new(constructor) if constructor
|
|
591
|
+
return JavaConstructor.new(@type_system, constructor) if constructor
|
|
411
592
|
rescue => ex
|
|
412
|
-
log(ex.message)
|
|
593
|
+
log("#{ex.message}\n#{ex.backtrace.join("\n")}")
|
|
413
594
|
end
|
|
414
595
|
raise NameError, "No constructor #{name}(#{types.join ', '})"
|
|
415
596
|
end
|
|
@@ -419,7 +600,7 @@ module Mirah::JVM::Types
|
|
|
419
600
|
return intrinsic if intrinsic
|
|
420
601
|
jvm_types = types.map {|type| type.jvm_type}
|
|
421
602
|
|
|
422
|
-
return JavaDynamicMethod.new(name, *jvm_types) if dynamic?
|
|
603
|
+
return JavaDynamicMethod.new(@type_system, name, *jvm_types) if dynamic?
|
|
423
604
|
|
|
424
605
|
begin
|
|
425
606
|
descriptors = types.map {|type| BiteScript::Signature.class_id(type)}
|
|
@@ -429,7 +610,7 @@ module Mirah::JVM::Types
|
|
|
429
610
|
method = superclass.java_method(name, *types) rescue nil
|
|
430
611
|
end
|
|
431
612
|
|
|
432
|
-
if method.nil? && jvm_type.abstract?
|
|
613
|
+
if method.nil? && jvm_type && jvm_type.abstract?
|
|
433
614
|
interfaces.each do |interface|
|
|
434
615
|
method = interface.java_method(name, *types) rescue nil
|
|
435
616
|
break if method
|
|
@@ -438,11 +619,11 @@ module Mirah::JVM::Types
|
|
|
438
619
|
|
|
439
620
|
return method if method.kind_of?(JavaCallable)
|
|
440
621
|
if method && method.static? == meta?
|
|
441
|
-
return JavaStaticMethod.new(method) if method.static?
|
|
442
|
-
return JavaMethod.new(method)
|
|
622
|
+
return JavaStaticMethod.new(@type_system, method) if method.static?
|
|
623
|
+
return JavaMethod.new(@type_system, method)
|
|
443
624
|
end
|
|
444
625
|
rescue => ex
|
|
445
|
-
log(ex.message)
|
|
626
|
+
log("#{ex.message}\n#{ex.backtrace.join("\n")}")
|
|
446
627
|
end
|
|
447
628
|
raise NameError, "No method #{self.name}.#{name}(#{types.join ', '})"
|
|
448
629
|
end
|
|
@@ -451,7 +632,7 @@ module Mirah::JVM::Types
|
|
|
451
632
|
methods = []
|
|
452
633
|
if jvm_type && !array?
|
|
453
634
|
jvm_type.getDeclaredMethods(name).each do |method|
|
|
454
|
-
methods << JavaMethod.new(method) unless method.static?
|
|
635
|
+
methods << JavaMethod.new(@type_system, method) unless method.static?
|
|
455
636
|
end
|
|
456
637
|
end
|
|
457
638
|
methods.concat((meta? ? unmeta : self).declared_intrinsics(name))
|
|
@@ -461,7 +642,7 @@ module Mirah::JVM::Types
|
|
|
461
642
|
methods = []
|
|
462
643
|
if jvm_type && !unmeta.array?
|
|
463
644
|
jvm_type.getDeclaredMethods(name).each do |method|
|
|
464
|
-
methods << JavaStaticMethod.new(method) if method.static?
|
|
645
|
+
methods << JavaStaticMethod.new(@type_system, method) if method.static?
|
|
465
646
|
end
|
|
466
647
|
end
|
|
467
648
|
methods.concat(meta.declared_intrinsics(name))
|
|
@@ -469,14 +650,14 @@ module Mirah::JVM::Types
|
|
|
469
650
|
|
|
470
651
|
def declared_constructors
|
|
471
652
|
jvm_type.getConstructors.map do |method|
|
|
472
|
-
JavaConstructor.new(method)
|
|
653
|
+
JavaConstructor.new(@type_system, method)
|
|
473
654
|
end
|
|
474
655
|
end
|
|
475
656
|
|
|
476
657
|
def field_getter(name)
|
|
477
658
|
if jvm_type
|
|
478
659
|
field = jvm_type.getField(name)
|
|
479
|
-
JavaFieldGetter.new(field) if field
|
|
660
|
+
JavaFieldGetter.new(@type_system, field) if field
|
|
480
661
|
else
|
|
481
662
|
nil
|
|
482
663
|
end
|
|
@@ -485,7 +666,7 @@ module Mirah::JVM::Types
|
|
|
485
666
|
def field_setter(name)
|
|
486
667
|
if jvm_type
|
|
487
668
|
field = jvm_type.getField(name)
|
|
488
|
-
JavaFieldSetter.new(field) if field
|
|
669
|
+
JavaFieldSetter.new(@type_system, field) if field
|
|
489
670
|
else
|
|
490
671
|
nil
|
|
491
672
|
end
|
|
@@ -493,13 +674,14 @@ module Mirah::JVM::Types
|
|
|
493
674
|
|
|
494
675
|
def inner_class_getter(name)
|
|
495
676
|
full_name = "#{self.name}$#{name}"
|
|
496
|
-
inner_class =
|
|
677
|
+
inner_class = @type_system.type(nil, full_name) rescue nil
|
|
497
678
|
return unless inner_class
|
|
679
|
+
|
|
498
680
|
inner_class.inner_class = true
|
|
499
|
-
|
|
500
|
-
Mirah::AST::Constant.new(call.
|
|
681
|
+
macro = Macro.new(self, name, []) do |call, typer|
|
|
682
|
+
Mirah::AST::Constant.new(call.position, Mirah::AST::SimpleString.new(call.position, full_name))
|
|
501
683
|
end
|
|
502
|
-
intrinsics[name][[]]
|
|
684
|
+
intrinsics[name][[]] = macro
|
|
503
685
|
end
|
|
504
686
|
end
|
|
505
687
|
|
|
@@ -547,17 +729,12 @@ module Mirah::JVM::Types
|
|
|
547
729
|
end
|
|
548
730
|
|
|
549
731
|
def constructors
|
|
550
|
-
@constructors
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
def default_constructor
|
|
554
|
-
if constructors.empty?
|
|
732
|
+
if @constructors.nil?
|
|
733
|
+
@constructors = []
|
|
555
734
|
declare_method('initialize', [], self, [])
|
|
556
|
-
@
|
|
557
|
-
constructors[0]
|
|
558
|
-
else
|
|
559
|
-
constructor
|
|
735
|
+
@have_default_constructor = true
|
|
560
736
|
end
|
|
737
|
+
@constructors
|
|
561
738
|
end
|
|
562
739
|
|
|
563
740
|
def instance_methods
|
|
@@ -570,25 +747,36 @@ module Mirah::JVM::Types
|
|
|
570
747
|
|
|
571
748
|
def declare_method(name, arguments, type, exceptions)
|
|
572
749
|
raise "Bad args" unless arguments.all?
|
|
750
|
+
if type.isError
|
|
751
|
+
instance_methods.delete(name)
|
|
752
|
+
method_updated(name)
|
|
753
|
+
return
|
|
754
|
+
end
|
|
573
755
|
member = MirahMember.new(self, name, arguments, type, false, exceptions)
|
|
574
756
|
if name == 'initialize'
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
constructors << JavaConstructor.new(member)
|
|
757
|
+
# The ordering is important here:
|
|
758
|
+
# The first call to constructors initializes @have_default_constructor.
|
|
759
|
+
if constructors.size == 1 && @have_default_constructor
|
|
760
|
+
constructors.clear
|
|
761
|
+
@have_default_constructor = false
|
|
762
|
+
elsif constructors.size > 1 && @have_default_constructor
|
|
763
|
+
raise "Invalid state: default constructor but #{constructors.size} constructors"
|
|
583
764
|
end
|
|
765
|
+
constructors << JavaConstructor.new(@type_system, member)
|
|
584
766
|
else
|
|
585
|
-
instance_methods[name] << JavaMethod.new(member)
|
|
767
|
+
instance_methods[name] << JavaMethod.new(@type_system, member)
|
|
586
768
|
end
|
|
769
|
+
method_updated(name)
|
|
587
770
|
end
|
|
588
771
|
|
|
589
772
|
def declare_static_method(name, arguments, type, exceptions)
|
|
590
|
-
|
|
591
|
-
|
|
773
|
+
if type.isError
|
|
774
|
+
static_methods.delete(name)
|
|
775
|
+
else
|
|
776
|
+
member = MirahMember.new(self, name, arguments, type, true, exceptions)
|
|
777
|
+
static_methods[name] << JavaStaticMethod.new(@type_system, member)
|
|
778
|
+
end
|
|
779
|
+
method_updated(name)
|
|
592
780
|
end
|
|
593
781
|
|
|
594
782
|
def interface?
|
|
@@ -629,4 +817,4 @@ module Mirah::JVM::Types
|
|
|
629
817
|
nil
|
|
630
818
|
end
|
|
631
819
|
end
|
|
632
|
-
end
|
|
820
|
+
end
|