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,39 +0,0 @@
|
|
|
1
|
-
module Mirah
|
|
2
|
-
module JVM
|
|
3
|
-
module Types
|
|
4
|
-
class NullType < Type
|
|
5
|
-
def initialize(types)
|
|
6
|
-
super(types, types.get_mirror('java.lang.Object'))
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def to_s
|
|
10
|
-
"Type(null)"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def null?
|
|
14
|
-
true
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def compatible?(other)
|
|
18
|
-
assignable_from(other)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def assignable_from?(other)
|
|
22
|
-
if other.respond_to?(:primitive?)
|
|
23
|
-
!other.primitive?
|
|
24
|
-
else
|
|
25
|
-
other.matchesAnything
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def widen(other)
|
|
30
|
-
if other.matchesAnything
|
|
31
|
-
self
|
|
32
|
-
else
|
|
33
|
-
other
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,184 +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 ComparisonIntrinsic < Intrinsic
|
|
18
|
-
attr_reader :name, :op
|
|
19
|
-
def initialize(type, name, op, args)
|
|
20
|
-
super(type, name, args, type.type_system.type(nil, 'boolean')) do; end
|
|
21
|
-
@type = type
|
|
22
|
-
@op = op
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def call(compiler, call, expression)
|
|
26
|
-
if expression
|
|
27
|
-
@type.compile_boolean_operator(compiler, op, false, call, nil)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def jump_if(compiler, call, label)
|
|
32
|
-
@type.compile_boolean_operator(compiler, @op, false, call, label)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def jump_if_not(compiler, call, label)
|
|
36
|
-
@type.compile_boolean_operator(compiler, @op, true, call, label)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def accept(visitor, expression)
|
|
40
|
-
visitor.visitComparison(self, expression)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def kind
|
|
44
|
-
Java::OrgMirahJvmTypes::MemberKind::COMPARISON_OP
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
class MathIntrinsic < Intrinsic
|
|
49
|
-
def accept(visitor, expression)
|
|
50
|
-
visitor.visitMath(self, expression)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def kind
|
|
54
|
-
Java::OrgMirahJvmTypes::MemberKind::MATH_OP
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
class Number < PrimitiveType
|
|
59
|
-
TYPE_ORDERING = ['byte', 'short', 'int', 'long', 'float', 'double']
|
|
60
|
-
|
|
61
|
-
# The type returned by arithmetic operations with this type.
|
|
62
|
-
def math_type
|
|
63
|
-
self
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def suffix
|
|
67
|
-
''
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Adds an intrinsic that delegates to an intrinsic in another primitive
|
|
71
|
-
# type. That type must support promoting the "this" argument.
|
|
72
|
-
def delegate_intrinsic(name, type, return_type)
|
|
73
|
-
args = [type]
|
|
74
|
-
delegate = type.intrinsics[name][args]
|
|
75
|
-
if delegate.kind_of?(ComparisonIntrinsic)
|
|
76
|
-
add_method(name, args, ComparisonIntrinsic.new(type, name, delegate.op, args))
|
|
77
|
-
elsif delegate.kind_of?(MathIntrinsic)
|
|
78
|
-
method = MathIntrinsic.new(self, name, args, return_type) do |compiler, call, expression|
|
|
79
|
-
if expression
|
|
80
|
-
delegate.call(compiler, call, expression)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
add_method(name, args, method)
|
|
84
|
-
else
|
|
85
|
-
add_method(name, args, return_type) do |compiler, call, expression|
|
|
86
|
-
if expression
|
|
87
|
-
delegate.call(compiler, call, expression)
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def add_delegates(name, return_type = nil)
|
|
94
|
-
index = TYPE_ORDERING.index(math_type.name)
|
|
95
|
-
larger_types = TYPE_ORDERING[index + 1, TYPE_ORDERING.size]
|
|
96
|
-
larger_types.each do |type|
|
|
97
|
-
type = @type_system.type(nil, type)
|
|
98
|
-
delegate_intrinsic(name, type, return_type || type)
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# if_cmpxx for non-ints
|
|
103
|
-
def jump_if(builder, op, label)
|
|
104
|
-
builder.send "#{prefix}cmp#{suffix}"
|
|
105
|
-
builder.send "if#{op}", label
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def boolean_operator(name, op)
|
|
109
|
-
args = [math_type]
|
|
110
|
-
add_method(name, args, ComparisonIntrinsic.new(self, name, op, args))
|
|
111
|
-
add_delegates(name, @type_system.type(nil, 'boolean'))
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def invert_op(op)
|
|
115
|
-
inverted = {
|
|
116
|
-
:lt => :ge,
|
|
117
|
-
:le => :gt,
|
|
118
|
-
:eq => :ne,
|
|
119
|
-
:ne => :eq,
|
|
120
|
-
:gt => :le,
|
|
121
|
-
:ge => :lt
|
|
122
|
-
}[op]
|
|
123
|
-
raise "Can't invert #{op}." unless inverted
|
|
124
|
-
inverted
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def compile_boolean_operator(compiler, op, negated, call, label)
|
|
128
|
-
# Promote the target or the argument if necessary
|
|
129
|
-
convert_args(compiler,
|
|
130
|
-
[call.target, *call.parameters],
|
|
131
|
-
[math_type, math_type])
|
|
132
|
-
if negated
|
|
133
|
-
op = invert_op(op)
|
|
134
|
-
end
|
|
135
|
-
if label
|
|
136
|
-
jump_if(compiler.method, op, label)
|
|
137
|
-
else
|
|
138
|
-
compiler.method.op_to_bool do |label|
|
|
139
|
-
jump_if(compiler.method, op, label)
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def math_operator(name, op)
|
|
145
|
-
args = [math_type]
|
|
146
|
-
method = MathIntrinsic.new(self, name, args, math_type) do |compiler, call, expression|
|
|
147
|
-
if expression
|
|
148
|
-
# Promote the target or the argument if necessary
|
|
149
|
-
convert_args(compiler,
|
|
150
|
-
[call.target, *call.parameters],
|
|
151
|
-
[math_type, math_type])
|
|
152
|
-
compiler.method.send "#{prefix}#{op}"
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
add_method(name, args, method)
|
|
156
|
-
add_delegates(name)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def unary_operator(name, op)
|
|
160
|
-
add_method(name, [], math_type) do |compiler, call, expression|
|
|
161
|
-
if expression
|
|
162
|
-
call.target.compile(compiler, true)
|
|
163
|
-
compiler.method.send("#{prefix}#{op}") if op
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def add_intrinsics
|
|
169
|
-
boolean_operator('<', :lt)
|
|
170
|
-
boolean_operator('<=', :le)
|
|
171
|
-
boolean_operator('==', :eq)
|
|
172
|
-
boolean_operator('!=', :ne)
|
|
173
|
-
boolean_operator('>=', :ge)
|
|
174
|
-
boolean_operator('>', :gt)
|
|
175
|
-
math_operator('+', :add)
|
|
176
|
-
math_operator('-', :sub)
|
|
177
|
-
math_operator('*', :mul)
|
|
178
|
-
math_operator('/', :div)
|
|
179
|
-
math_operator('%', :rem)
|
|
180
|
-
unary_operator('-@', :neg)
|
|
181
|
-
unary_operator('+@', nil)
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
@@ -1,76 +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
|
|
17
|
-
module JVM
|
|
18
|
-
module Types
|
|
19
|
-
class PrimitiveType < Type
|
|
20
|
-
WIDENING_CONVERSIONS = {
|
|
21
|
-
'byte' => ['byte', 'short', 'int', 'long', 'float', 'double', 'java.lang.Byte', 'java.lang.Object'],
|
|
22
|
-
'short' => ['short', 'int', 'long', 'float', 'double', 'java.lang.Short', 'java.lang.Object'],
|
|
23
|
-
'char' => ['char', 'int', 'long', 'float', 'double', 'java.lang.Character', 'java.lang.Object'],
|
|
24
|
-
'int' => ['int', 'long', 'float', 'double','java.lang.Integer', 'java.lang.Object'],
|
|
25
|
-
'long' => ['long', 'float', 'double', 'java.lang.Long', 'java.lang.Object'],
|
|
26
|
-
'float' => ['float', 'double', 'java.lang.Float', 'java.lang.Object'],
|
|
27
|
-
'double' => ['double', 'java.lang.Double', 'java.lang.Object']
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
def initialize(types, type, wrapper)
|
|
31
|
-
@wrapper = wrapper
|
|
32
|
-
super(types, type)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def primitive?
|
|
36
|
-
true
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def primitive_type
|
|
40
|
-
@wrapper::TYPE
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def newarray(method)
|
|
44
|
-
method.send "new#{name}array"
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def interfaces(include_parent=true)
|
|
48
|
-
[]
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def convertible_to?(type)
|
|
52
|
-
return true if type == self
|
|
53
|
-
return false if type.array?
|
|
54
|
-
widening_conversions = WIDENING_CONVERSIONS[self.name]
|
|
55
|
-
widening_conversions && widening_conversions.include?(type.name)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def superclass
|
|
59
|
-
nil
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def wrapper_name
|
|
63
|
-
@wrapper.java_class.name
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def box_type
|
|
67
|
-
@type_system.type(nil, wrapper_name)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def box(builder)
|
|
71
|
-
builder.invokestatic box_type, "valueOf", [box_type, self]
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
@@ -1,274 +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 'jruby'
|
|
17
|
-
require 'set'
|
|
18
|
-
require 'bitescript'
|
|
19
|
-
module Mirah::JVM::Types
|
|
20
|
-
class JavaSourceMirror
|
|
21
|
-
begin
|
|
22
|
-
java_import 'javax.tools.ToolProvider'
|
|
23
|
-
java_import 'java.util.Arrays'
|
|
24
|
-
java_import 'javax.tools.SimpleJavaFileObject'
|
|
25
|
-
java_import 'javax.tools.JavaFileObject'
|
|
26
|
-
java_import 'java.net.URI'
|
|
27
|
-
java_import 'javax.lang.model.element.Element'
|
|
28
|
-
java_import 'javax.lang.model.type.TypeKind'
|
|
29
|
-
java_import 'javax.lang.model.type.TypeMirror'
|
|
30
|
-
java_import 'javax.lang.model.util.ElementScanner6'
|
|
31
|
-
java_import 'javax.lang.model.element.AnnotationValueVisitor'
|
|
32
|
-
java_import 'com.sun.tools.javac.model.JavacElements'
|
|
33
|
-
rescue
|
|
34
|
-
# must be after Java 7-15
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
if defined?(JavacElements)
|
|
38
|
-
class FakeJavaFile < SimpleJavaFileObject
|
|
39
|
-
def initialize(package, name, kind='class')
|
|
40
|
-
package ||= ''
|
|
41
|
-
super(URI.create(FakeJavaFile.build_uri(package, name)), JavaFileObject::Kind::SOURCE)
|
|
42
|
-
@code = ''
|
|
43
|
-
if package != ""
|
|
44
|
-
@code << "package #{package};\n"
|
|
45
|
-
end
|
|
46
|
-
@code << "@org.mirah.infer.FakeClass\n"
|
|
47
|
-
@code << "public #{kind} #{name} { }"
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def self.build_uri(package, name)
|
|
51
|
-
name = name.tr('.', '$')
|
|
52
|
-
package = package.tr('.', '/')
|
|
53
|
-
package << '/' unless "" == package
|
|
54
|
-
"string:///#{package}#{name}#{JavaFileObject::Kind::SOURCE.extension}"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def getCharContent(ignoreEncodingErrors)
|
|
58
|
-
java.lang.String.new(@code)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
class JavaSourceParser < ElementScanner6
|
|
63
|
-
include AnnotationValueVisitor
|
|
64
|
-
|
|
65
|
-
# TODO support generics
|
|
66
|
-
def initialize(file, type_factory)
|
|
67
|
-
super()
|
|
68
|
-
@file = file
|
|
69
|
-
@type_factory = type_factory
|
|
70
|
-
@mirrors = []
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def parse
|
|
74
|
-
tools = ToolProvider.system_java_compiler
|
|
75
|
-
units = [get_java_file(tools)] + get_fake_files
|
|
76
|
-
@javac = tools.get_task(nil, nil, nil, classpath, nil, units)
|
|
77
|
-
@element_utils = JavacElements.instance(@javac.context)
|
|
78
|
-
elements = @javac.enter
|
|
79
|
-
elements.each {|elem| scan(elem)}
|
|
80
|
-
@mirrors
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def classpath
|
|
84
|
-
options = [
|
|
85
|
-
'-classpath', @type_factory.classpath
|
|
86
|
-
]
|
|
87
|
-
if @type_factory.bootclasspath
|
|
88
|
-
options << '-bootclasspath' << @type_factory.bootclasspath
|
|
89
|
-
end
|
|
90
|
-
options
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def get_java_file(tools)
|
|
94
|
-
fm = tools.get_standard_file_manager(nil, nil, nil)
|
|
95
|
-
fm.get_java_file_objects(@file).to_a[0]
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def get_fake_files
|
|
99
|
-
mirah_typedefs = Set.new(@type_factory.known_types.values.reject {|t| !t.kind_of?(TypeDefinition)})
|
|
100
|
-
files = [FakeJavaFile.new('org.mirah.infer', 'FakeClass', '@interface')]
|
|
101
|
-
mirah_typedefs.each do |typedef|
|
|
102
|
-
typedef.name =~ /^(?:(.+)\.)?([^.]+)$/
|
|
103
|
-
package, name = $1, $2
|
|
104
|
-
kind = if typedef.interface?
|
|
105
|
-
'interface'
|
|
106
|
-
else
|
|
107
|
-
'class'
|
|
108
|
-
end
|
|
109
|
-
files << FakeJavaFile.new(package, name, kind)
|
|
110
|
-
end
|
|
111
|
-
files
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def visitType(elem, arg)
|
|
115
|
-
return anno_visitType(elem, arg) if elem.kind_of?(TypeMirror)
|
|
116
|
-
if elem.annotation_mirrors.any? {|a| a.toString == '@org.mirah.infer.FakeClass'}
|
|
117
|
-
return
|
|
118
|
-
end
|
|
119
|
-
superclass = internal_type_name(elem.superclass) || 'java/lang/Object'
|
|
120
|
-
interfaces = elem.interfaces.map {|i| internal_type_name(i)}
|
|
121
|
-
flags = flags_from_modifiers(elem)
|
|
122
|
-
builder = BiteScript::ASM::ClassMirror::Builder.new
|
|
123
|
-
builder.visit(0, flags, internal_name(elem), nil, superclass, interfaces)
|
|
124
|
-
with(builder) do
|
|
125
|
-
elem.annotation_mirrors.each {|anno| visitAnnotation(anno)}
|
|
126
|
-
super(elem, arg)
|
|
127
|
-
end
|
|
128
|
-
@mirrors << builder.mirror
|
|
129
|
-
builder.mirror
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def visitVariable(field, arg)
|
|
133
|
-
flags = flags_from_modifiers(field)
|
|
134
|
-
type = type_desc(field.as_type)
|
|
135
|
-
fbuilder = @current.visitField(
|
|
136
|
-
flags, field.simple_name, type, nil, field.constant_value)
|
|
137
|
-
with fbuilder do
|
|
138
|
-
field.annotation_mirrors.each {|anno| visitAnnotation(anno)}
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def visitExecutable(method, arg)
|
|
143
|
-
# TODO varags
|
|
144
|
-
flags = flags_from_modifiers(method)
|
|
145
|
-
exceptions = method.thrown_types.map {|t| internal_type_name(t)}
|
|
146
|
-
desc = type_desc(method.as_type)
|
|
147
|
-
mbuilder = @current.visitMethod(flags, method.simple_name, desc, nil, exceptions)
|
|
148
|
-
with mbuilder do
|
|
149
|
-
method.annotation_mirrors.each {|anno| visitAnnotation(anno)}
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def visitAnnotation(elem, arg=nil)
|
|
154
|
-
desc = type_desc(elem.annotation_type)
|
|
155
|
-
if arg.nil?
|
|
156
|
-
anno = @current.visitAnnotation(desc, 0)
|
|
157
|
-
else
|
|
158
|
-
builder, name = arg
|
|
159
|
-
anno = builder.visitAnnotation(name, desc)
|
|
160
|
-
end
|
|
161
|
-
elem.element_values.each do |method, value|
|
|
162
|
-
name = method.simple_name
|
|
163
|
-
visit(value, [anno, name])
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
# AnnotationValueVisitor
|
|
168
|
-
def visitArray(values, arg)
|
|
169
|
-
anno, name = arg
|
|
170
|
-
array = anno.visitArray(name)
|
|
171
|
-
values.each do |value|
|
|
172
|
-
visit(value, [array, name])
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def visitBoolean(val, arg)
|
|
177
|
-
anno, name = arg
|
|
178
|
-
anno.visit(name, val)
|
|
179
|
-
end
|
|
180
|
-
alias visitByte visitBoolean
|
|
181
|
-
alias visitChar visitBoolean
|
|
182
|
-
alias visitDouble visitBoolean
|
|
183
|
-
alias visitFloat visitBoolean
|
|
184
|
-
alias visitInt visitBoolean
|
|
185
|
-
alias visitLong visitBoolean
|
|
186
|
-
alias visitShort visitBoolean
|
|
187
|
-
alias visitString visitBoolean
|
|
188
|
-
alias visitUnknown visitBoolean
|
|
189
|
-
|
|
190
|
-
def visitEnumConstant(c, arg)
|
|
191
|
-
anno, name = arg
|
|
192
|
-
anno.visitEnum(name, type_desc(c.as_type), c.simple_name)
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def anno_visitType(t, arg)
|
|
196
|
-
anno, name = arg
|
|
197
|
-
anno.visit(name, BiteScript::ASM::Type.getType(type_desc(t)))
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def with(elem)
|
|
201
|
-
saved, @current = @current, elem
|
|
202
|
-
begin
|
|
203
|
-
yield
|
|
204
|
-
ensure
|
|
205
|
-
@current = saved
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def flags_from_modifiers(elem)
|
|
210
|
-
flags = 0
|
|
211
|
-
elem.modifiers.each do |modifier|
|
|
212
|
-
flags |= BiteScript::ASM::Opcodes.const_get("ACC_#{modifier.name}")
|
|
213
|
-
end
|
|
214
|
-
flags
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def internal_name(element)
|
|
218
|
-
@element_utils.get_binary_name(element).to_s.tr('.', '/')
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def internal_type_name(type)
|
|
222
|
-
return nil if type.kind == TypeKind::NONE
|
|
223
|
-
return @element_utils.get_binary_name(type.as_element).to_s.tr('.', '/')
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
def type_desc(type)
|
|
227
|
-
case type.kind.name
|
|
228
|
-
when 'ARRAY'
|
|
229
|
-
"[#{type_desc(type.component_type)}"
|
|
230
|
-
when 'BOOLEAN'
|
|
231
|
-
'Z'
|
|
232
|
-
when 'BYTE'
|
|
233
|
-
'B'
|
|
234
|
-
when 'CHAR'
|
|
235
|
-
'C'
|
|
236
|
-
when 'DECLARED'
|
|
237
|
-
name = internal_type_name(type)
|
|
238
|
-
"L#{name};"
|
|
239
|
-
when 'DOUBLE'
|
|
240
|
-
'D'
|
|
241
|
-
when 'FLOAT'
|
|
242
|
-
'F'
|
|
243
|
-
when 'INT'
|
|
244
|
-
'I'
|
|
245
|
-
when 'LONG'
|
|
246
|
-
'J'
|
|
247
|
-
when 'SHORT'
|
|
248
|
-
'S'
|
|
249
|
-
when 'VOID'
|
|
250
|
-
'V'
|
|
251
|
-
when 'EXECUTABLE'
|
|
252
|
-
desc = '('
|
|
253
|
-
type.parameter_types.each do |param|
|
|
254
|
-
desc << type_desc(param)
|
|
255
|
-
end
|
|
256
|
-
desc << ')'
|
|
257
|
-
desc << type_desc(type.return_type)
|
|
258
|
-
else
|
|
259
|
-
raise ArgumentError, "Unsupported type #{type.kind.name}"
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
def self.load(file, factory)
|
|
266
|
-
if defined? JavacElements
|
|
267
|
-
parser = JavaSourceParser.new(file, factory)
|
|
268
|
-
parser.parse
|
|
269
|
-
end
|
|
270
|
-
rescue TypeError
|
|
271
|
-
# 1.6.8 on Java 7, don't use source mirror
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
end
|