mirah 0.1.2-java → 0.1.3-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.
- checksums.yaml +4 -4
- data/History.txt +225 -0
- data/Rakefile +108 -315
- data/TODO.md +100 -0
- data/bin/bundler +16 -0
- data/bin/rake +16 -0
- data/dist/mirahc.jar +0 -0
- data/examples/appengine/Readme +0 -1
- data/examples/literals.mirah +17 -0
- data/examples/macros/string_each_char.mirah +1 -1
- data/lib/mirah.rb +11 -21
- data/lib/mirah/transform/transformer.rb +1 -2
- data/lib/mirah/util/class_loader.rb +1 -1
- data/lib/mirah/util/logging.rb +0 -63
- data/lib/mirah/util/process_errors.rb +1 -0
- data/lib/mirah/version.rb +1 -1
- data/{examples/simple_class.mirah~ → test/artifacts/jar_test.rb} +7 -11
- data/{lib/mirah/commands.rb → test/artifacts/jruby_test.rb} +8 -5
- data/test/core/typer_test.rb +29 -11
- data/test/core/util/argument_processor_test.rb +24 -23
- data/test/core/util/class_loader_test.rb +7 -4
- data/test/core/util/{compilation_state_test.rb → jvm_version_test.rb} +20 -16
- data/test/fixtures/org/foo/ImplicitClassRetAnno.java +4 -0
- data/test/fixtures/org/foo/IntAnno.java +9 -0
- data/test/jvm/annotations_test.rb +11 -11
- data/test/jvm/blocks_test.rb +16 -12
- data/test/jvm/constructors_test.rb +8 -8
- data/test/jvm/enumerable_test.rb +48 -24
- data/test/jvm/generics_test.rb +3 -7
- data/test/jvm/import_test.rb +14 -0
- data/test/jvm/interface_test.rb +9 -24
- data/test/jvm/jvm_commands_test.rb +22 -4
- data/test/jvm/jvm_compiler_test.rb +124 -79
- data/test/jvm/list_extensions_test.rb +1 -1
- data/test/jvm/macros_test.rb +67 -14
- data/test/jvm/main_method_test.rb +1 -1
- data/test/jvm/new_backend_test_helper.rb +100 -3
- data/{lib/mirah/jvm/types/bitescript_ext.rb → test/jvm/static_fields_test.rb} +22 -21
- data/test/mirrors/base_type_test.rb +4 -3
- data/test/mirrors/bytecode_mirror_test.rb +35 -15
- data/test/mirrors/generics_test.rb +14 -5
- data/test/mirrors/member_test.rb +2 -1
- data/test/mirrors/method_lookup_test.rb +18 -6
- data/test/mirrors/mirrors_test.rb +87 -20
- data/test/mirrors/simple_async_mirror_loader_test.rb +7 -3
- data/test/mirrors/simple_mirror_loader_test.rb +5 -5
- data/test/test_helper.rb +25 -1
- metadata +18 -78
- data/bin/mirahp +0 -27
- data/bin/mirahp.cmd +0 -16
- data/examples/Fib.class +0 -0
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-builtins.jar +0 -0
- data/javalib/mirah-compiler.jar +0 -0
- data/javalib/mirah-mirrors.jar +0 -0
- data/javalib/mirah-newast-transitional.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/javalib/mirah-util.jar +0 -0
- data/lib/mirah/ast.rb +0 -43
- data/lib/mirah/ast/scope.rb +0 -262
- data/lib/mirah/commands/base.rb +0 -59
- data/lib/mirah/commands/compile.rb +0 -39
- data/lib/mirah/commands/parse.rb +0 -36
- data/lib/mirah/commands/run.rb +0 -78
- data/lib/mirah/generator.rb +0 -150
- data/lib/mirah/jvm/compiler.rb +0 -50
- data/lib/mirah/jvm/compiler/base.rb +0 -421
- data/lib/mirah/jvm/compiler/jvm_bytecode.rb +0 -1194
- data/lib/mirah/jvm/method_lookup.rb +0 -307
- data/lib/mirah/jvm/types.rb +0 -45
- data/lib/mirah/jvm/types/array_type.rb +0 -60
- data/lib/mirah/jvm/types/ast_ext.rb +0 -31
- data/lib/mirah/jvm/types/basic_types.rb +0 -41
- data/lib/mirah/jvm/types/block_type.rb +0 -15
- data/lib/mirah/jvm/types/boolean.rb +0 -70
- data/lib/mirah/jvm/types/enumerable.rb +0 -80
- data/lib/mirah/jvm/types/extensions.rb +0 -110
- data/lib/mirah/jvm/types/factory.rb +0 -830
- data/lib/mirah/jvm/types/floats.rb +0 -99
- data/lib/mirah/jvm/types/generic_type.rb +0 -72
- data/lib/mirah/jvm/types/implicit_nil_type.rb +0 -29
- data/lib/mirah/jvm/types/integers.rb +0 -131
- data/lib/mirah/jvm/types/interface_definition.rb +0 -20
- data/lib/mirah/jvm/types/intrinsics.rb +0 -385
- data/lib/mirah/jvm/types/literals.rb +0 -89
- data/lib/mirah/jvm/types/meta_type.rb +0 -54
- data/lib/mirah/jvm/types/methods.rb +0 -946
- data/lib/mirah/jvm/types/null_type.rb +0 -39
- data/lib/mirah/jvm/types/number.rb +0 -184
- data/lib/mirah/jvm/types/primitive_type.rb +0 -76
- data/lib/mirah/jvm/types/source_mirror.rb +0 -274
- data/lib/mirah/jvm/types/type.rb +0 -311
- data/lib/mirah/jvm/types/type_definition.rb +0 -72
- data/lib/mirah/jvm/types/void_type.rb +0 -19
- data/lib/mirah/util/compilation_state.rb +0 -60
- data/test/core/commands_test.rb +0 -89
- data/test/core/generator_test.rb +0 -26
- data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
- data/test/jvm/bytecode_test_helper.rb +0 -193
- data/test/jvm/factory_test.rb +0 -28
- data/test/jvm/java_typer_test.rb +0 -283
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
module Mirah::JVM::Types
|
|
17
|
-
class FloatType < Number
|
|
18
|
-
def prefix
|
|
19
|
-
'f'
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def math_type
|
|
23
|
-
@type_system.type(nil, 'float')
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def suffix
|
|
27
|
-
'g'
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def init_value(builder)
|
|
31
|
-
builder.fconst_0
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def literal(builder, value)
|
|
35
|
-
case value
|
|
36
|
-
when 0.0
|
|
37
|
-
builder.fconst_0
|
|
38
|
-
when 1.0
|
|
39
|
-
builder.fconst_1
|
|
40
|
-
when 2.0
|
|
41
|
-
builder.fconst_2
|
|
42
|
-
else
|
|
43
|
-
builder.ldc_float(value)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def compile_widen(builder, type)
|
|
48
|
-
case type.name
|
|
49
|
-
when 'float'
|
|
50
|
-
# Do nothing
|
|
51
|
-
when 'double'
|
|
52
|
-
builder.f2d
|
|
53
|
-
when wrapper_name, 'java.lang.Object'
|
|
54
|
-
builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
|
|
55
|
-
else
|
|
56
|
-
raise ArgumentError, "Invalid widening conversion from float to #{type}"
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
class DoubleType < FloatType
|
|
62
|
-
def prefix
|
|
63
|
-
'd'
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def math_type
|
|
67
|
-
@type_system.type(nil, 'double')
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def wide?
|
|
71
|
-
true
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def init_value(builder)
|
|
75
|
-
builder.dconst_0
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def literal(builder, value)
|
|
79
|
-
case value
|
|
80
|
-
when 0.0
|
|
81
|
-
builder.dconst_0
|
|
82
|
-
when 1.0
|
|
83
|
-
builder.dconst_1
|
|
84
|
-
else
|
|
85
|
-
builder.ldc_double(value)
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def compile_widen(builder, type)
|
|
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
|
|
95
|
-
raise ArgumentError, "Invalid widening conversion from double to #{type}"
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
module Mirah
|
|
2
|
-
module JVM
|
|
3
|
-
module Types
|
|
4
|
-
class GenericType < Type
|
|
5
|
-
java_import 'java.util.HashMap'
|
|
6
|
-
java_import 'org.mirah.typer.GenericType'
|
|
7
|
-
include GenericType
|
|
8
|
-
|
|
9
|
-
attr_reader :ungeneric
|
|
10
|
-
|
|
11
|
-
def initialize(ungeneric)
|
|
12
|
-
super(ungeneric.type_system, ungeneric.name)
|
|
13
|
-
@ungeneric = ungeneric
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def basic_type
|
|
17
|
-
@ungeneric.basic_type
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def generic?
|
|
21
|
-
true
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def generic
|
|
25
|
-
self
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def ungeneric
|
|
29
|
-
@ungeneric
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def superclass
|
|
33
|
-
@ungeneric.superclass.generic if @ungeneric.superclass
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def declared_macros(name=nil)
|
|
37
|
-
@ungeneric.declared_macros(name)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def interfaces(include_parent=true)
|
|
41
|
-
ungeneric.interfaces
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def jvm_type
|
|
45
|
-
@ungeneric.jvm_type
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def inner_class?
|
|
49
|
-
basic_type.inner_class?
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def type_parameter_map
|
|
53
|
-
unless @type_parameter_map
|
|
54
|
-
@type_parameter_map = HashMap.new
|
|
55
|
-
end
|
|
56
|
-
@type_parameter_map
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def assignable_from?(other)
|
|
60
|
-
@ungeneric.assignable_from?(other)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def inspect(indent=0)
|
|
64
|
-
"#{' ' * indent}#<#{self.class.name.split(/::/)[-1]} #{name} #{type_parameter_map}>"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
class TypeDefGeneric < GenericType
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
module Mirah
|
|
2
|
-
module JVM
|
|
3
|
-
module Types
|
|
4
|
-
class ImplicitNilType < Type
|
|
5
|
-
def initialize(types)
|
|
6
|
-
super(types, types.get_mirror('java.lang.Object'))
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def to_s
|
|
10
|
-
"Type(implicit_nil)"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def widen(other)
|
|
14
|
-
other
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def compatible?(other)
|
|
18
|
-
true
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def assignable_from?(other)
|
|
22
|
-
true
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def matchesAnything; true; end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
require 'mirah/jvm/types/bitescript_ext'
|
|
17
|
-
|
|
18
|
-
module Mirah::JVM::Types
|
|
19
|
-
class IntegerType < Number
|
|
20
|
-
def literal(builder, value)
|
|
21
|
-
builder.push_int(value)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def init_value(builder)
|
|
25
|
-
builder.iconst_0
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def load(builder, index)
|
|
29
|
-
builder.iload(index)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def compile_widen(builder, type)
|
|
33
|
-
case type.name
|
|
34
|
-
when 'byte', 'short', 'int'
|
|
35
|
-
# do nothing
|
|
36
|
-
when 'long'
|
|
37
|
-
builder.i2l
|
|
38
|
-
when 'float'
|
|
39
|
-
builder.i2f
|
|
40
|
-
when 'double'
|
|
41
|
-
builder.i2d
|
|
42
|
-
when wrapper_name, 'java.lang.Object'
|
|
43
|
-
builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
|
|
44
|
-
else
|
|
45
|
-
raise ArgumentError, "Invalid widening conversion from #{name} to #{type}"
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def prefix
|
|
50
|
-
'i'
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def math_type
|
|
54
|
-
@type_system.type(nil, 'int')
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def jump_if(builder, op, label)
|
|
58
|
-
builder.send "if_icmp#{op}", label
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def add_intrinsics
|
|
62
|
-
super
|
|
63
|
-
math_operator('<<', 'shl')
|
|
64
|
-
math_operator('>>', 'shr')
|
|
65
|
-
math_operator('>>>', 'ushr')
|
|
66
|
-
math_operator('|', 'or')
|
|
67
|
-
math_operator('&', 'and')
|
|
68
|
-
math_operator('^', 'xor')
|
|
69
|
-
unary_operator('~', 'not')
|
|
70
|
-
end
|
|
71
|
-
end
|
|
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
|
-
|
|
84
|
-
class LongType < Number
|
|
85
|
-
def prefix
|
|
86
|
-
'l'
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def math_type
|
|
90
|
-
@type_system.type(nil, 'long')
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def literal(builder, value)
|
|
94
|
-
builder.ldc_long(value)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def init_value(builder)
|
|
98
|
-
builder.lconst_0
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def wide?
|
|
102
|
-
true
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def compile_widen(builder, type)
|
|
106
|
-
case type.name
|
|
107
|
-
when 'long'
|
|
108
|
-
# do nothing
|
|
109
|
-
when 'float'
|
|
110
|
-
builder.l2f
|
|
111
|
-
when 'double'
|
|
112
|
-
builder.l2d
|
|
113
|
-
when wrapper_name, 'java.lang.Object'
|
|
114
|
-
builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
|
|
115
|
-
else
|
|
116
|
-
raise ArgumentError, "Invalid widening conversion from Int to #{type}"
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def add_intrinsics
|
|
121
|
-
super
|
|
122
|
-
math_operator('<<', 'shl')
|
|
123
|
-
math_operator('>>', 'shr')
|
|
124
|
-
math_operator('>>>', 'ushr')
|
|
125
|
-
math_operator('|', 'or')
|
|
126
|
-
math_operator('&', 'and')
|
|
127
|
-
math_operator('^', 'xor')
|
|
128
|
-
unary_operator('~', 'not')
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module Mirah
|
|
2
|
-
module JVM
|
|
3
|
-
module Types
|
|
4
|
-
class InterfaceDefinition < TypeDefinition
|
|
5
|
-
def initialize(types, scope, name, node)
|
|
6
|
-
super(types, scope, name, node)
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def define(builder)
|
|
10
|
-
class_name = @name.tr('.', '/')
|
|
11
|
-
@type ||= builder.public_interface(class_name, *interfaces)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def interface?
|
|
15
|
-
true
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
require 'bitescript'
|
|
17
|
-
require 'mirah/jvm/types/bitescript_ext'
|
|
18
|
-
|
|
19
|
-
module Mirah::JVM::Types
|
|
20
|
-
class Type
|
|
21
|
-
java_import 'org.mirah.macros.anno.MacroDef'
|
|
22
|
-
|
|
23
|
-
def load(builder, index)
|
|
24
|
-
builder.send "#{prefix}load", index
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def store(builder, index)
|
|
28
|
-
builder.send "#{prefix}store", index
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def return(builder)
|
|
32
|
-
builder.send "#{prefix}return"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def init_value(builder)
|
|
36
|
-
builder.aconst_null
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def intrinsics
|
|
40
|
-
@intrinsics ||= begin
|
|
41
|
-
@intrinsics = Hash.new {|h, k| h[k] = {}}
|
|
42
|
-
add_intrinsics
|
|
43
|
-
@intrinsics
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def macros
|
|
48
|
-
@macros ||= Hash.new {|h, k| h[k] = {}}
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def add_method(name, args, method_or_type=nil, kind=nil, &block)
|
|
52
|
-
if block_given?
|
|
53
|
-
method_or_type = Intrinsic.new(self, name, args,
|
|
54
|
-
method_or_type, kind, &block)
|
|
55
|
-
end
|
|
56
|
-
intrinsics[name][args] = method_or_type
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def add_compiled_macro(klass)
|
|
60
|
-
name, arg_types, is_static = read_macrodef_annotation(klass)
|
|
61
|
-
if arg_types.nil?
|
|
62
|
-
return
|
|
63
|
-
elsif is_static && !self.meta?
|
|
64
|
-
self.meta.add_compiled_macro(klass)
|
|
65
|
-
return
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
log "Adding macro #{self.name}.#{name}(#{arg_types.map{|t| t.full_name}.join(', ')})"
|
|
69
|
-
# TODO separate static and instance macros
|
|
70
|
-
macro = Macro.new(self, name, arg_types) do |call, typer|
|
|
71
|
-
#TODO scope
|
|
72
|
-
# We probably need to set the scope on all the parameters, plus the
|
|
73
|
-
# arguments and body of any block params. Also make sure scope is copied
|
|
74
|
-
# when cloned.
|
|
75
|
-
scope = typer.scoper.get_scope(call)
|
|
76
|
-
# call.parameters.each do |arg|
|
|
77
|
-
# arg.scope = scope
|
|
78
|
-
# end
|
|
79
|
-
|
|
80
|
-
begin
|
|
81
|
-
expander = klass.constructors[0].newInstance(typer.macro_compiler, call)
|
|
82
|
-
ast = expander.expand
|
|
83
|
-
# rescue
|
|
84
|
-
# puts "Unable to expand macro #{name.inspect} from #{klass} with #{call}"
|
|
85
|
-
end
|
|
86
|
-
if ast
|
|
87
|
-
body = Mirah::AST::NodeList.new(ast.position.to_java(Mirah::AST::Position))
|
|
88
|
-
# TODO scope
|
|
89
|
-
# static_scope = typer.scoper.add_scope(body)
|
|
90
|
-
# static_scope.parent = typer.scoper.get_scope(call)
|
|
91
|
-
body.add(ast)
|
|
92
|
-
# if call.target
|
|
93
|
-
# static_scope.self_type = call.target.inferred_type!
|
|
94
|
-
# static_scope.self_node = call.target
|
|
95
|
-
# else
|
|
96
|
-
# static_scope.self_type = scope.self_type
|
|
97
|
-
# end
|
|
98
|
-
|
|
99
|
-
body
|
|
100
|
-
else
|
|
101
|
-
Mirah::AST::Noop.new
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
macros[name][arg_types] = macro
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def declared_macros(name=nil)
|
|
108
|
-
result = []
|
|
109
|
-
each_name = lambda do |name, hash|
|
|
110
|
-
hash.each do |args, macro|
|
|
111
|
-
result << macro
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
if name
|
|
115
|
-
each_name.call(name, self.macros[name])
|
|
116
|
-
else
|
|
117
|
-
self.macros.each &each_name
|
|
118
|
-
end
|
|
119
|
-
result
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def macro(name, types)
|
|
123
|
-
macro = macros[name][types]
|
|
124
|
-
return macro if macro
|
|
125
|
-
macro = superclass.macro(name, types) if (superclass && !superclass.isError)
|
|
126
|
-
return macro if macro
|
|
127
|
-
interfaces.each do |interface|
|
|
128
|
-
macro = interface.macro(name, types) unless interface.isError
|
|
129
|
-
return macro if macro
|
|
130
|
-
end
|
|
131
|
-
nil
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def declared_intrinsics(name=nil)
|
|
135
|
-
methods = []
|
|
136
|
-
all_intrinsics = if name.nil?
|
|
137
|
-
intrinsics
|
|
138
|
-
else
|
|
139
|
-
[[name, intrinsics[name]]]
|
|
140
|
-
end
|
|
141
|
-
all_intrinsics.each do |name, group|
|
|
142
|
-
group.each do |args, method|
|
|
143
|
-
methods << method
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
interfaces.each do |interface|
|
|
147
|
-
methods.concat(interface.declared_intrinsics(name)) unless interface.isError
|
|
148
|
-
end
|
|
149
|
-
methods
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def load_extensions(klass=nil)
|
|
153
|
-
mirror = nil
|
|
154
|
-
if klass
|
|
155
|
-
mirror = @type_system.mirror_class(klass)
|
|
156
|
-
elsif jvm_type
|
|
157
|
-
mirror = jvm_type
|
|
158
|
-
end
|
|
159
|
-
if mirror
|
|
160
|
-
extensions = mirror.getDeclaredAnnotation('org.mirah.macros.anno.Extensions')
|
|
161
|
-
return self if extensions.nil?
|
|
162
|
-
macros = extensions['macros']
|
|
163
|
-
return self if macros.nil?
|
|
164
|
-
macros.each do |macro_class|
|
|
165
|
-
klass = begin
|
|
166
|
-
JRuby.runtime.jruby_class_loader.loadClass(macro_class)
|
|
167
|
-
rescue java.lang.NoClassDefFoundError => ex
|
|
168
|
-
raise ex
|
|
169
|
-
end
|
|
170
|
-
add_compiled_macro(klass)
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
self
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def read_macrodef_annotation(klass)
|
|
177
|
-
macro = klass.getAnnotation(MacroDef.java_class)
|
|
178
|
-
if macro.nil?
|
|
179
|
-
error("Unable to load macro #{klass.name}: no MacroDef annotation")
|
|
180
|
-
return
|
|
181
|
-
end
|
|
182
|
-
macro_name = macro.name
|
|
183
|
-
# TODO optional, rest args
|
|
184
|
-
args = macro.arguments.required.map do |typename|
|
|
185
|
-
type = @type_system.get_type(typename)
|
|
186
|
-
raise "Unable to find class #{typename}" unless type
|
|
187
|
-
type
|
|
188
|
-
end
|
|
189
|
-
[macro_name, args, macro.is_static]
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def add_intrinsics
|
|
193
|
-
boolean = @type_system.type(nil, 'boolean')
|
|
194
|
-
object_type = @type_system.type(nil, 'java.lang.Object')
|
|
195
|
-
class_type = @type_system.type(nil, 'java.lang.Class')
|
|
196
|
-
|
|
197
|
-
add_method('nil?', [], boolean, 'IS_NULL') do |compiler, call, expression|
|
|
198
|
-
if expression
|
|
199
|
-
compiler.visit(call.target, true)
|
|
200
|
-
compiler.method.op_to_bool do |target|
|
|
201
|
-
compiler.method.ifnull(target)
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
add_method('==', [object_type], boolean, 'COMPARISON_OP') do |compiler, call, expression|
|
|
207
|
-
# Should this call Object.equals for consistency with Ruby?
|
|
208
|
-
if expression
|
|
209
|
-
compiler.visit(call.target, true)
|
|
210
|
-
compiler.visit(call.parameters(0), true)
|
|
211
|
-
compiler.method.op_to_bool do |target|
|
|
212
|
-
compiler.method.if_acmpeq(target)
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
add_method('!=', [object_type], boolean, 'COMPARISON_OP') do |compiler, call, expression|
|
|
218
|
-
# Should this call Object.equals for consistency with Ruby?
|
|
219
|
-
if expression
|
|
220
|
-
compiler.visit(call.target, true)
|
|
221
|
-
compiler.visit(call.parameters(0), true)
|
|
222
|
-
compiler.method.op_to_bool do |target|
|
|
223
|
-
compiler.method.if_acmpne(target)
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
add_method('kind_of?', [object_type.meta], boolean, "INSTANCEOF") do |compiler, call, expression|
|
|
229
|
-
compiler.visit(call.target, expression)
|
|
230
|
-
if expression
|
|
231
|
-
klass = compiler.inferred_type(call.parameters(0))
|
|
232
|
-
compiler.method.instanceof(klass.unmeta)
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
# add_macro('kind_of?', class_type) do |transformer, call|
|
|
237
|
-
# klass, object = call.parameters(0), call.target
|
|
238
|
-
# Mirah::AST::Call.new(call.parent, call.position, 'isInstance') do |call2|
|
|
239
|
-
# klass.parent = object.parent = call2
|
|
240
|
-
# [
|
|
241
|
-
# klass,
|
|
242
|
-
# [object]
|
|
243
|
-
# ]
|
|
244
|
-
# end
|
|
245
|
-
# end
|
|
246
|
-
#
|
|
247
|
-
end
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
class ArrayType
|
|
251
|
-
begin
|
|
252
|
-
java_import 'org.mirah.builtins.ArrayExtensions'
|
|
253
|
-
java_import 'org.mirah.builtins.EnumerableExtensions'
|
|
254
|
-
rescue NameError
|
|
255
|
-
ArrayExtensions = nil
|
|
256
|
-
EnumerableExtensions = nil
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def add_intrinsics
|
|
260
|
-
super
|
|
261
|
-
load_extensions(EnumerableExtensions.java_class) if EnumerableExtensions
|
|
262
|
-
load_extensions(ArrayExtensions.java_class) if ArrayExtensions
|
|
263
|
-
int_type = @type_system.type(nil, 'int')
|
|
264
|
-
add_method(
|
|
265
|
-
'[]', [int_type], component_type, "ARRAY_ACCESS") do |compiler, call, expression|
|
|
266
|
-
if expression
|
|
267
|
-
compiler.visit(call.target, true)
|
|
268
|
-
compiler.visit(call.parameters(0), true)
|
|
269
|
-
component_type.aload(compiler.method)
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
add_method('[]=',
|
|
274
|
-
[int_type, component_type],
|
|
275
|
-
component_type, "ARRAY_ASSIGN") do |compiler, call, expression|
|
|
276
|
-
compiler.visit(call.target, true)
|
|
277
|
-
convert_args(compiler, call.parameters, [@type_system.type(nil, 'int'), component_type])
|
|
278
|
-
component_type.astore(compiler.method)
|
|
279
|
-
if expression
|
|
280
|
-
compiler.visit(call.parameters(1), true)
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
add_method('length', [], int_type, "ARRAY_LENGTH") do |compiler, call, expression|
|
|
285
|
-
compiler.visit(call.target, true)
|
|
286
|
-
compiler.method.arraylength
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
class MetaType
|
|
292
|
-
def add_intrinsics
|
|
293
|
-
add_method('class', [], @type_system.type(nil, 'java.lang.Class'), "CLASS_LITERAL") do |compiler, call, expression|
|
|
294
|
-
if expression
|
|
295
|
-
compiler.method.ldc_class(unmeta)
|
|
296
|
-
end
|
|
297
|
-
end
|
|
298
|
-
add_method('[]', [], unmeta.array_type.meta) do |compiler, call, expression|
|
|
299
|
-
compiler.method.ldc_class(unmeta.array_type.meta)
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
class ArrayMetaType
|
|
305
|
-
def add_intrinsics
|
|
306
|
-
super
|
|
307
|
-
load_extensions(@type_system.type(nil, 'org.mirah.builtins.ArrayMetaExtensions'))
|
|
308
|
-
# add_macro('cast', @type_system.type(nil, 'java.lang.Object')) do |transformer, call|
|
|
309
|
-
# call.cast = true
|
|
310
|
-
# call.resolve_if(nil) { unmeta }
|
|
311
|
-
# call
|
|
312
|
-
# end
|
|
313
|
-
end
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
class StringType < Type
|
|
317
|
-
def add_intrinsics
|
|
318
|
-
super
|
|
319
|
-
string_type = @type_system.type(nil, 'java.lang.String')
|
|
320
|
-
bool_type = @type_system.type(nil, 'boolean')
|
|
321
|
-
int_type = @type_system.type(nil, 'int')
|
|
322
|
-
long_type = @type_system.type(nil, 'long')
|
|
323
|
-
char_type = @type_system.type(nil, 'char')
|
|
324
|
-
float_type = @type_system.type(nil, 'float')
|
|
325
|
-
double_type = @type_system.type(nil, 'double')
|
|
326
|
-
add_method('[]', [int_type], char_type) do |compiler, call, expression|
|
|
327
|
-
if expression
|
|
328
|
-
compiler.visit(call.target, true)
|
|
329
|
-
compiler.visit(call.parameters(0), true)
|
|
330
|
-
compiler.method.invokevirtual string_type, "charAt", [char_type, int_type]
|
|
331
|
-
end
|
|
332
|
-
end
|
|
333
|
-
add_method('[]', [int_type, int_type], string_type) do |compiler, call, expression|
|
|
334
|
-
if expression
|
|
335
|
-
compiler.visit(call.target, true)
|
|
336
|
-
compiler.visit(call.parameters(0), true)
|
|
337
|
-
compiler.method.dup
|
|
338
|
-
compiler.visit(call.parameters[1], true)
|
|
339
|
-
compiler.method.iadd
|
|
340
|
-
compiler.method.invokevirtual string_type, "substring", [string_type, int_type, int_type]
|
|
341
|
-
end
|
|
342
|
-
end
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
class IterableType < Type
|
|
347
|
-
def add_intrinsics
|
|
348
|
-
super
|
|
349
|
-
return
|
|
350
|
-
add_enumerable_macros
|
|
351
|
-
add_macro('each', @type_system.block_type) do |transformer, call|
|
|
352
|
-
Mirah::AST::Loop.new(call.parent,
|
|
353
|
-
call.position, true, false) do |forloop|
|
|
354
|
-
it = transformer.tmp
|
|
355
|
-
|
|
356
|
-
assignment = transformer.eval("#{it} = foo.iterator")
|
|
357
|
-
assignment.value.target = call.target
|
|
358
|
-
call.target.parent = assignment.value
|
|
359
|
-
forloop.init << assignment
|
|
360
|
-
|
|
361
|
-
var = call.block.args.args[0]
|
|
362
|
-
if var
|
|
363
|
-
forloop.pre << transformer.eval(
|
|
364
|
-
"#{var.name} = #{it}.next", '', forloop, it)
|
|
365
|
-
else
|
|
366
|
-
forloop.pre << transformer.eval("#{it}.next", '', forloop, it)
|
|
367
|
-
end
|
|
368
|
-
call.block.body.parent = forloop if call.block.body
|
|
369
|
-
[
|
|
370
|
-
Mirah::AST::Condition.new(forloop, call.position) do |c|
|
|
371
|
-
[transformer.eval("#{it}.hasNext", '', forloop, it)]
|
|
372
|
-
end,
|
|
373
|
-
call.block.body
|
|
374
|
-
]
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
end
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
class PrimitiveType
|
|
381
|
-
# Primitives define their own intrinsics instead of getting the Object ones.
|
|
382
|
-
def add_intrinsics
|
|
383
|
-
end
|
|
384
|
-
end
|
|
385
|
-
end
|