unageanu-javaclass 0.0.1
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/ChangeLog +0 -0
- data/README +4 -0
- data/lib/javaclass/accessflag.rb +279 -0
- data/lib/javaclass/attribute.rb +1061 -0
- data/lib/javaclass/base.rb +369 -0
- data/lib/javaclass/class.rb +282 -0
- data/lib/javaclass/constant.rb +522 -0
- data/lib/javaclass/member.rb +194 -0
- data/lib/javaclass/reader.rb +449 -0
- data/lib/javaclass.rb +8 -0
- data/sample/class_list.rb +22 -0
- data/sample/create_assert.rb +69 -0
- data/sample/java_class/HelloWorld.class +0 -0
- data/sample/java_class/com/example/Constants.class +0 -0
- data/sample/java_class/com/example/Deprecated.class +0 -0
- data/sample/java_class/com/example/InnerClass$1.class +0 -0
- data/sample/java_class/com/example/InnerClass$BasicInnerClass.class +0 -0
- data/sample/java_class/com/example/InnerClass$StaticInnerClass$InnerInnerClass.class +0 -0
- data/sample/java_class/com/example/InnerClass$StaticInnerClass$StaticInnerInnerClass.class +0 -0
- data/sample/java_class/com/example/InnerClass$StaticInnerClass.class +0 -0
- data/sample/java_class/com/example/InnerClass.class +0 -0
- data/sample/java_class/com/example/InnerClassImpl$1.class +0 -0
- data/sample/java_class/com/example/InnerClassImpl$1MethodInnerClass.class +0 -0
- data/sample/java_class/com/example/InnerClassImpl$2.class +0 -0
- data/sample/java_class/com/example/InnerClassImpl$BasicInnerClass2.class +0 -0
- data/sample/java_class/com/example/InnerClassImpl$StaticInnerClass2.class +0 -0
- data/sample/java_class/com/example/InnerClassImpl.class +0 -0
- data/sample/java_class/com/example/Kitten.class +0 -0
- data/sample/java_class/com/example/ThrowsException.class +0 -0
- data/sample/java_class/com/example/annotation/Annotated.class +0 -0
- data/sample/java_class/com/example/annotation/AnnotatedMethod$A.class +0 -0
- data/sample/java_class/com/example/annotation/AnnotatedMethod$B.class +0 -0
- data/sample/java_class/com/example/annotation/AnnotatedMethod$C.class +0 -0
- data/sample/java_class/com/example/annotation/AnnotatedMethod.class +0 -0
- data/sample/java_class/com/example/annotation/ClassAnnotationA.class +0 -0
- data/sample/java_class/com/example/annotation/HasDefaultValue.class +0 -0
- data/sample/java_class/com/example/annotation/RuntimeAnnotationA.class +0 -0
- data/sample/java_class/com/example/annotation/RuntimeAnnotationB.class +0 -0
- data/sample/java_class/com/example/annotation/RuntimeAnnotationC.class +0 -0
- data/sample/java_class/com/example/annotation/SourceAnnotationA.class +0 -0
- data/sample/java_class/com/example/types/TypeVariables.class +0 -0
- data/sample/java_src/HelloWorld.java +6 -0
- data/sample/java_src/com/example/Constants.java +45 -0
- data/sample/java_src/com/example/Deprecated.java +16 -0
- data/sample/java_src/com/example/InnerClass.java +23 -0
- data/sample/java_src/com/example/InnerClassImpl.java +31 -0
- data/sample/java_src/com/example/Kitten.java +78 -0
- data/sample/java_src/com/example/ThrowsException.java +12 -0
- data/sample/java_src/com/example/annotation/Annotated.java +47 -0
- data/sample/java_src/com/example/annotation/AnnotatedMethod.java +18 -0
- data/sample/java_src/com/example/annotation/ClassAnnotationA.java +10 -0
- data/sample/java_src/com/example/annotation/HasDefaultValue.java +10 -0
- data/sample/java_src/com/example/annotation/RuntimeAnnotationA.java +15 -0
- data/sample/java_src/com/example/annotation/RuntimeAnnotationB.java +10 -0
- data/sample/java_src/com/example/annotation/RuntimeAnnotationC.java +8 -0
- data/sample/java_src/com/example/annotation/SourceAnnotationA.java +10 -0
- data/sample/java_src/com/example/types/TypeVariables.java +19 -0
- data/sample/sample.rb +27 -0
- data/test/all-tests.rb +32 -0
- data/test/java_class/com/example/TestClass1$1.class +0 -0
- data/test/java_class/com/example/TestClass1$Hoo.class +0 -0
- data/test/java_class/com/example/TestClass1$Var.class +0 -0
- data/test/java_class/com/example/TestClass1.class +0 -0
- data/test/java_src/com/example/TestClass1.java +28 -0
- data/test/test_access_flag.rb +205 -0
- data/test/test_attribute.rb +955 -0
- data/test/test_class.rb +90 -0
- data/test/test_constant.rb +830 -0
- data/test/test_member.rb +282 -0
- data/test/test_util.rb +20 -0
- metadata +157 -0
@@ -0,0 +1,522 @@
|
|
1
|
+
require "javaclass/base"
|
2
|
+
|
3
|
+
module JavaClass
|
4
|
+
|
5
|
+
#
|
6
|
+
#=== Constantの基底クラス
|
7
|
+
#
|
8
|
+
class Constant
|
9
|
+
include JavaClass::Base
|
10
|
+
|
11
|
+
CONSTANT_Class = 7
|
12
|
+
CONSTANT_Fieldref = 9
|
13
|
+
CONSTANT_Methodref = 10
|
14
|
+
CONSTANT_InterfaceMethodref = 11
|
15
|
+
CONSTANT_String = 8
|
16
|
+
CONSTANT_Integer = 3
|
17
|
+
CONSTANT_Float = 4
|
18
|
+
CONSTANT_Long = 5
|
19
|
+
CONSTANT_Double = 6
|
20
|
+
CONSTANT_NameAndType = 12
|
21
|
+
CONSTANT_Utf8 = 1
|
22
|
+
|
23
|
+
#
|
24
|
+
#===コンストラクタ
|
25
|
+
#
|
26
|
+
#*java_class::constantの所有者であるJavaクラス
|
27
|
+
#*tag::constantの種類を示すタグ
|
28
|
+
#
|
29
|
+
def initialize( java_class, tag=nil )
|
30
|
+
@java_class = java_class
|
31
|
+
@tag = tag
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_bytes()
|
35
|
+
to_byte( @tag, 1)
|
36
|
+
end
|
37
|
+
|
38
|
+
attr :tag, true
|
39
|
+
attr :java_class, true
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
#=== ClassConstant
|
45
|
+
#
|
46
|
+
class ClassConstant < Constant
|
47
|
+
#
|
48
|
+
#===コンストラクタ
|
49
|
+
#
|
50
|
+
#*java_class::constantの所有者であるJavaクラス
|
51
|
+
#*tag::constantの種類を示すタグ
|
52
|
+
#*name_index::名前を示すconstant_poolのインデックス
|
53
|
+
#
|
54
|
+
def initialize( java_class, tag=nil, name_index=nil )
|
55
|
+
super( java_class, tag )
|
56
|
+
@name_index = name_index
|
57
|
+
end
|
58
|
+
#
|
59
|
+
#===クラス名を取得する。
|
60
|
+
#
|
61
|
+
#<b>戻り値</b>::クラス名
|
62
|
+
#
|
63
|
+
def name
|
64
|
+
value = @java_class.get_constant_value(@name_index)
|
65
|
+
return value.gsub(/\//, ".")
|
66
|
+
end
|
67
|
+
def to_bytes()
|
68
|
+
super + to_byte( @name_index, 2)
|
69
|
+
end
|
70
|
+
attr :name_index, true
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
#=== フィールド、メソッドのConstantの共通基底クラス
|
75
|
+
#
|
76
|
+
class MemberRefConstant < Constant
|
77
|
+
#
|
78
|
+
#===コンストラクタ
|
79
|
+
#
|
80
|
+
#*java_class::constantの所有者であるJavaクラス
|
81
|
+
#*tag::constantの種類を示すタグ
|
82
|
+
#*class_name_index::フィールドorメソッドを持つクラス名を示すconstant_poolのインデックス
|
83
|
+
#*name_and_type_index::フィールドorメソッドの名前とディスクリプタを示すconstant_poolのインデックス
|
84
|
+
#
|
85
|
+
def initialize( java_class, tag=nil, class_name_index=nil, name_and_type_index=nil )
|
86
|
+
super(java_class, tag)
|
87
|
+
@class_name_index = class_name_index
|
88
|
+
@name_and_type_index = name_and_type_index
|
89
|
+
end
|
90
|
+
#
|
91
|
+
#===フィールドorメソッドを持つクラスのconstantを取得する
|
92
|
+
#
|
93
|
+
#<b>戻り値</b>::フィールドorメソッドを持つクラスのconstant
|
94
|
+
#
|
95
|
+
def class_name
|
96
|
+
@java_class.get_constant(@class_name_index)
|
97
|
+
end
|
98
|
+
#
|
99
|
+
#===フィールドorメソッドの名前とディスクリプタを示すconstantを取得する
|
100
|
+
#
|
101
|
+
#<b>戻り値</b>::フィールドorメソッドの名前とディスクリプタを示すconstantを取得する
|
102
|
+
#
|
103
|
+
def name_and_type
|
104
|
+
@java_class.get_constant(@name_and_type_index)
|
105
|
+
end
|
106
|
+
def to_bytes()
|
107
|
+
bytes = super
|
108
|
+
bytes += to_byte( @class_name_index, 2 )
|
109
|
+
bytes += to_byte( @name_and_type_index, 2 )
|
110
|
+
end
|
111
|
+
attr :class_name_index, true
|
112
|
+
attr :name_and_type_index, true
|
113
|
+
end
|
114
|
+
#
|
115
|
+
#=== フィールドのConstant
|
116
|
+
#
|
117
|
+
class FieldRefConstant < MemberRefConstant
|
118
|
+
#
|
119
|
+
#===コンストラクタ
|
120
|
+
#
|
121
|
+
#*java_class::constantの所有者であるJavaクラス
|
122
|
+
#*tag::constantの種類を示すタグ
|
123
|
+
#*class_name_index::フィールドorメソッドを持つクラス名を示すconstant_poolのインデックス
|
124
|
+
#*name_and_type_index::フィールドorメソッドの名前とディスクリプタを示すconstant_poolのインデックス
|
125
|
+
#
|
126
|
+
def initialize( java_class, tag=nil, class_name_index=nil, name_and_type_index=nil )
|
127
|
+
super
|
128
|
+
end
|
129
|
+
end
|
130
|
+
#
|
131
|
+
#=== メソッドのConstant
|
132
|
+
#
|
133
|
+
class MethodRefConstant < MemberRefConstant
|
134
|
+
#
|
135
|
+
#===コンストラクタ
|
136
|
+
#
|
137
|
+
#*java_class::constantの所有者であるJavaクラス
|
138
|
+
#*tag::constantの種類を示すタグ
|
139
|
+
#*class_name_index::フィールドorメソッドを持つクラス名を示すconstant_poolのインデックス
|
140
|
+
#*name_and_type_index::フィールドorメソッドの名前とディスクリプタを示すconstant_poolのインデックス
|
141
|
+
#
|
142
|
+
def initialize( java_class, tag=nil, class_name_index=nil, name_and_type_index=nil )
|
143
|
+
super
|
144
|
+
end
|
145
|
+
end
|
146
|
+
#
|
147
|
+
#=== インターフェイスメソッドのConstant
|
148
|
+
#
|
149
|
+
class InterfaceMethodRefConstant < MemberRefConstant
|
150
|
+
#
|
151
|
+
#===コンストラクタ
|
152
|
+
#
|
153
|
+
#*java_class::constantの所有者であるJavaクラス
|
154
|
+
#*tag::constantの種類を示すタグ
|
155
|
+
#*class_name_index::フィールドorメソッドを持つクラス名を示すconstant_poolのインデックス
|
156
|
+
#*name_and_type_index::フィールドorメソッドの名前とディスクリプタを示すconstant_poolのインデックス
|
157
|
+
#
|
158
|
+
def initialize( java_class, tag=nil, class_name_index=nil, name_and_type_index=nil )
|
159
|
+
super
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
#=== 名前と型のConstant
|
165
|
+
#
|
166
|
+
class NameAndTypeConstant < Constant
|
167
|
+
#
|
168
|
+
#===コンストラクタ
|
169
|
+
#
|
170
|
+
#*java_class::constantの所有者であるJavaクラス
|
171
|
+
#*tag::constantの種類を示すタグ
|
172
|
+
#*name_index::名前を示すconstant_poolのインデックス
|
173
|
+
#*descriptor_index::ディスクリプタを示すconstant_poolのインデックス
|
174
|
+
#
|
175
|
+
def initialize( java_class, tag=nil, name_index=nil, descriptor_index=nil )
|
176
|
+
super(java_class, tag)
|
177
|
+
@name_index = name_index
|
178
|
+
@descriptor_index = descriptor_index
|
179
|
+
end
|
180
|
+
#
|
181
|
+
#=== 名前を取得する
|
182
|
+
#
|
183
|
+
#<b>戻り値</b>::名前
|
184
|
+
#
|
185
|
+
def name
|
186
|
+
@java_class.get_constant_value(@name_index)
|
187
|
+
end
|
188
|
+
#
|
189
|
+
#=== ディスクリプタを取得する
|
190
|
+
#
|
191
|
+
#<b>戻り値</b>::ディスクリプタ
|
192
|
+
#
|
193
|
+
def descriptor
|
194
|
+
@java_class.get_constant_value(@descriptor_index)
|
195
|
+
end
|
196
|
+
def to_bytes()
|
197
|
+
bytes = super
|
198
|
+
bytes += to_byte( @name_index, 2 )
|
199
|
+
bytes += to_byte( @descriptor_index, 2 )
|
200
|
+
end
|
201
|
+
attr :name_index, true
|
202
|
+
attr :descriptor_index, true
|
203
|
+
end
|
204
|
+
|
205
|
+
#
|
206
|
+
#=== 文字列のConstant
|
207
|
+
#
|
208
|
+
class StringConstant < Constant
|
209
|
+
#
|
210
|
+
#===コンストラクタ
|
211
|
+
#
|
212
|
+
#*java_class::constantの所有者であるJavaクラス
|
213
|
+
#*tag::constantの種類を示すタグ
|
214
|
+
#*string_index::値を示すconstant_poolのインデックス
|
215
|
+
#
|
216
|
+
def initialize( java_class, tag=nil, string_index=nil )
|
217
|
+
super(java_class, tag)
|
218
|
+
@string_index = string_index
|
219
|
+
end
|
220
|
+
#
|
221
|
+
#=== 値を取得する
|
222
|
+
#
|
223
|
+
#<b>戻り値</b>::値
|
224
|
+
#
|
225
|
+
def bytes
|
226
|
+
@java_class.get_constant_value(@string_index)
|
227
|
+
end
|
228
|
+
def to_bytes()
|
229
|
+
tmp = super
|
230
|
+
tmp += to_byte( @string_index, 2)
|
231
|
+
end
|
232
|
+
def to_s
|
233
|
+
bytes != nil ? "\"#{bytes}\"" : "null"
|
234
|
+
end
|
235
|
+
attr :string_index, true
|
236
|
+
end
|
237
|
+
|
238
|
+
#
|
239
|
+
#=== 文字列のConstant
|
240
|
+
#
|
241
|
+
class UTF8Constant < Constant
|
242
|
+
#
|
243
|
+
#===コンストラクタ
|
244
|
+
#
|
245
|
+
#*java_class::constantの所有者であるJavaクラス
|
246
|
+
#*tag::constantの種類を示すタグ
|
247
|
+
#*bytes::値
|
248
|
+
#
|
249
|
+
def initialize( java_class, tag=nil, bytes=nil )
|
250
|
+
super(java_class, tag)
|
251
|
+
@bytes = bytes
|
252
|
+
end
|
253
|
+
def to_bytes()
|
254
|
+
tmp = super
|
255
|
+
body = []
|
256
|
+
@bytes.each_byte {|i|
|
257
|
+
body += to_byte( i, 1 )
|
258
|
+
}
|
259
|
+
tmp += to_byte( body.length, 2 )
|
260
|
+
tmp += body
|
261
|
+
end
|
262
|
+
def to_s
|
263
|
+
"\"#{bytes}\""
|
264
|
+
end
|
265
|
+
attr :bytes, true
|
266
|
+
end
|
267
|
+
|
268
|
+
#
|
269
|
+
#=== 整数のConstant
|
270
|
+
#
|
271
|
+
class IntegerConstant < Constant
|
272
|
+
#
|
273
|
+
#===コンストラクタ
|
274
|
+
#
|
275
|
+
#*java_class::constantの所有者であるJavaクラス
|
276
|
+
#*tag::constantの種類を示すタグ
|
277
|
+
#*bytes::値
|
278
|
+
#
|
279
|
+
def initialize( java_class, tag=nil, bytes=nil )
|
280
|
+
super(java_class, tag)
|
281
|
+
@bytes = bytes
|
282
|
+
end
|
283
|
+
def bytes()
|
284
|
+
IntegerConstant::value_from_bytes(@bytes)
|
285
|
+
end
|
286
|
+
def bytes=(value)
|
287
|
+
@bytes = IntegerConstant::bytes_from_value(value)
|
288
|
+
end
|
289
|
+
def to_bytes()
|
290
|
+
tmp = super
|
291
|
+
tmp += to_byte( @bytes, 4 )
|
292
|
+
end
|
293
|
+
def to_s
|
294
|
+
bytes.to_s
|
295
|
+
end
|
296
|
+
private
|
297
|
+
def self.value_from_bytes(bytes)
|
298
|
+
return nil if bytes == nil
|
299
|
+
e = bytes & 0x7FFFFFFF
|
300
|
+
value = ((bytes >> 31) == 0) ? e : e - 0x80000000
|
301
|
+
return value
|
302
|
+
end
|
303
|
+
def self.bytes_from_value(value)
|
304
|
+
return nil if value == nil
|
305
|
+
if value > 2147483647 || value < -2147483648
|
306
|
+
raise RangeError.new
|
307
|
+
end
|
308
|
+
tmp = value >= 0 ? value : 0x80000000 + value
|
309
|
+
tmp |= (value >= 0 ? 0 : 1) << 31
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
#
|
314
|
+
#=== FloatのConstant
|
315
|
+
#
|
316
|
+
class FloatConstant < Constant
|
317
|
+
#
|
318
|
+
#===コンストラクタ
|
319
|
+
#
|
320
|
+
#*java_class::constantの所有者であるJavaクラス
|
321
|
+
#*tag::constantの種類を示すタグ
|
322
|
+
#*bytes::値
|
323
|
+
#
|
324
|
+
def initialize( java_class, tag=nil, bytes=nil )
|
325
|
+
super(java_class, tag)
|
326
|
+
@bytes = bytes
|
327
|
+
end
|
328
|
+
def bytes()
|
329
|
+
FloatConstant.value_from_bytes(@bytes)
|
330
|
+
end
|
331
|
+
def bytes=(value)
|
332
|
+
raise "not implements yet."
|
333
|
+
end
|
334
|
+
def to_bytes()
|
335
|
+
tmp = super
|
336
|
+
tmp += to_byte( @bytes, 4)
|
337
|
+
end
|
338
|
+
def to_s
|
339
|
+
tmp = bytes
|
340
|
+
str =tmp.to_s
|
341
|
+
str << "F" unless ( tmp.kind_of?(Float) && (tmp.nan? || tmp.infinite? ))
|
342
|
+
return str
|
343
|
+
end
|
344
|
+
private
|
345
|
+
def self.value_from_bytes(bytes)
|
346
|
+
return nil if bytes == nil
|
347
|
+
return 1.0/0 if bytes == 0x7f800000
|
348
|
+
return -1.0/0 if bytes == 0xff800000
|
349
|
+
return 0.0/0.0 if bytes >= 0x7f800001 && bytes <= 0x7fffffff
|
350
|
+
return 0.0/0.0 if bytes >= 0xff800001 && bytes <= 0xffffffff
|
351
|
+
s = ((bytes >> 31) == 0) ? 1 : -1
|
352
|
+
e = ((bytes >> 23) & 0xff)
|
353
|
+
m = (e == 0) ? ((bytes & 0x7fffff) << 1) : ((bytes & 0x7fffff) | 0x800000)
|
354
|
+
return s*m*(2**(e-150))
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
#
|
359
|
+
#=== LongのConstant
|
360
|
+
#
|
361
|
+
class LongConstant < Constant
|
362
|
+
#
|
363
|
+
#===コンストラクタ
|
364
|
+
#
|
365
|
+
#*java_class::constantの所有者であるJavaクラス
|
366
|
+
#*tag::constantの種類を示すタグ
|
367
|
+
#*bytes::値
|
368
|
+
#
|
369
|
+
def initialize( java_class, tag=nil, bytes=nil )
|
370
|
+
super(java_class, tag)
|
371
|
+
@bytes = bytes
|
372
|
+
end
|
373
|
+
def bytes()
|
374
|
+
LongConstant::value_from_bytes(@bytes)
|
375
|
+
end
|
376
|
+
def bytes=(value)
|
377
|
+
@bytes = LongConstant::bytes_from_value(value) # TODO
|
378
|
+
end
|
379
|
+
def to_bytes()
|
380
|
+
tmp = super
|
381
|
+
tmp += to_byte( @bytes, 8)
|
382
|
+
end
|
383
|
+
def to_s
|
384
|
+
bytes.to_s << "L"
|
385
|
+
end
|
386
|
+
private
|
387
|
+
def self.value_from_bytes(bytes)
|
388
|
+
return nil if bytes == nil
|
389
|
+
e = bytes & 0x7FFFFFFFFFFFFFFF
|
390
|
+
value = ((bytes >> 63) == 0) ? e : e - 0x8000000000000000
|
391
|
+
return value
|
392
|
+
end
|
393
|
+
def self.bytes_from_value(value)
|
394
|
+
return nil if value == nil
|
395
|
+
if value > 9223372036854775807 || value < -9223372036854775808
|
396
|
+
raise RangeError.new
|
397
|
+
end
|
398
|
+
tmp = value >= 0 ? value : 0x8000000000000000 + value
|
399
|
+
tmp |= (value >= 0 ? 0 : 1) << 63
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
#
|
404
|
+
#=== DoubleのConstant
|
405
|
+
#
|
406
|
+
class DoubleConstant < Constant
|
407
|
+
#
|
408
|
+
#===コンストラクタ
|
409
|
+
#
|
410
|
+
#*java_class::constantの所有者であるJavaクラス
|
411
|
+
#*tag::constantの種類を示すタグ
|
412
|
+
#*bytes::値
|
413
|
+
#
|
414
|
+
def initialize( java_class, tag=nil, bytes=nil )
|
415
|
+
super(java_class, tag)
|
416
|
+
@bytes = bytes
|
417
|
+
end
|
418
|
+
def bytes()
|
419
|
+
DoubleConstant.value_from_bytes(@bytes)
|
420
|
+
end
|
421
|
+
def bytes=(value)
|
422
|
+
raise "not implements yet." # TODO
|
423
|
+
end
|
424
|
+
def to_bytes()
|
425
|
+
tmp = super
|
426
|
+
tmp += to_byte( @bytes, 8)
|
427
|
+
end
|
428
|
+
def to_s
|
429
|
+
tmp = bytes
|
430
|
+
str =tmp.to_s
|
431
|
+
str << "D" unless ( tmp.kind_of?(Float) && (tmp.nan? || tmp.infinite? ))
|
432
|
+
return str
|
433
|
+
end
|
434
|
+
private
|
435
|
+
def self.value_from_bytes(bytes)
|
436
|
+
return nil if bytes == nil
|
437
|
+
return 1.0/0 if bytes == 0x7ff0000000000000
|
438
|
+
return -1.0/0 if bytes == 0xfff0000000000000
|
439
|
+
return 0.0/0.0 if bytes >= 0x7ff0000000000001 && bytes <= 0x7fffffffffffffff
|
440
|
+
return 0.0/0.0 if bytes >= 0xfff0000000000001 && bytes <= 0xffffffffffffffff
|
441
|
+
s = ((bytes >> 63) == 0) ? 1 : -1
|
442
|
+
e = ((bytes >> 52) & 0x7ff)
|
443
|
+
m = (e == 0) ? ((bytes & 0xfffffffffffff) << 1 ) : ((bytes & 0xfffffffffffff) | 0x10000000000000)
|
444
|
+
return s*m*(2**(e-1075))
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
#
|
449
|
+
#===Constantを新規に作成するためのユーティリティ
|
450
|
+
#
|
451
|
+
module ConstantFactory
|
452
|
+
module_function
|
453
|
+
|
454
|
+
#=== UTF8のConstantを生成する。
|
455
|
+
#*value::文字列値
|
456
|
+
def utf8(value)
|
457
|
+
UTF8Constant.new( nil, Constant::CONSTANT_Utf8, value )
|
458
|
+
end
|
459
|
+
|
460
|
+
#=== 整数ののConstantを生成する。
|
461
|
+
#*value::値
|
462
|
+
def int(value)
|
463
|
+
IntegerConstant.new( nil, Constant::CONSTANT_Integer, value )
|
464
|
+
end
|
465
|
+
|
466
|
+
# def float(value)
|
467
|
+
# FloatConstant.new( nil, Constant::CONSTANT_Float, value )
|
468
|
+
# end
|
469
|
+
|
470
|
+
#=== 整数(Long)のConstantを生成する。
|
471
|
+
#*value::値
|
472
|
+
def long(value)
|
473
|
+
LongConstant.new( nil, Constant::CONSTANT_Long, value )
|
474
|
+
end
|
475
|
+
|
476
|
+
# def double(value)
|
477
|
+
# DoubleConstant.new( nil, Constant::CONSTANT_Double, value )
|
478
|
+
# end
|
479
|
+
|
480
|
+
#=== 名前と型を示すConstantを生成する。
|
481
|
+
#*name_index::名前を示すconstant_poolのインデックス
|
482
|
+
#*descriptor_index::ディスクリプタを示すconstant_poolのインデックス
|
483
|
+
def name_and_type(name_index=nil, descriptor_index=nil)
|
484
|
+
NameAndTypeConstant.new( nil, Constant::CONSTANT_NameAndType, name_index, descriptor_index )
|
485
|
+
end
|
486
|
+
|
487
|
+
#=== 文字列(String)のConstantを生成する。
|
488
|
+
#*string_index::値を示すUTF8Constantのconstant_poolにおけるインデックス
|
489
|
+
#
|
490
|
+
def string(string_index=nil)
|
491
|
+
StringConstant.new( nil, Constant::CONSTANT_String, string_index )
|
492
|
+
end
|
493
|
+
|
494
|
+
#=== インターフェイスのメソッドを示すConstantを生成する。
|
495
|
+
#*class_name_index::フィールドorメソッドを持つクラス名を示すconstant_poolのインデックス
|
496
|
+
#*name_and_type_index::フィールドorメソッドの名前とディスクリプタを示すconstant_poolのインデックス
|
497
|
+
def interface_methodref(class_name_index=nil, name_and_type_index=nil)
|
498
|
+
InterfaceMethodRefConstant.new( nil, Constant::CONSTANT_InterfaceMethodref, class_name_index, name_and_type_index )
|
499
|
+
end
|
500
|
+
|
501
|
+
#=== メソッドを示すConstantを生成する。
|
502
|
+
#*class_name_index::フィールドorメソッドを持つクラス名を示すconstant_poolのインデックス
|
503
|
+
#*name_and_type_index::フィールドorメソッドの名前とディスクリプタを示すconstant_poolのインデックス
|
504
|
+
def methodref(class_name_index=nil, name_and_type_index=nil)
|
505
|
+
MethodRefConstant.new( nil, Constant::CONSTANT_Methodref, class_name_index, name_and_type_index )
|
506
|
+
end
|
507
|
+
|
508
|
+
#=== フィールドを示すConstantを生成する。
|
509
|
+
#*class_name_index::フィールドorメソッドを持つクラス名を示すconstant_poolのインデックス
|
510
|
+
#*name_and_type_index::フィールドorメソッドの名前とディスクリプタを示すconstant_poolのインデックス
|
511
|
+
def fieldref(class_name_index=nil, name_and_type_index=nil)
|
512
|
+
FieldRefConstant.new( nil, Constant::CONSTANT_Fieldref, class_name_index, name_and_type_index )
|
513
|
+
end
|
514
|
+
|
515
|
+
#=== クラスを示すConstantを生成する。
|
516
|
+
#*name_index::クラス名を示すconstant_poolのインデックス
|
517
|
+
def class_constant(name_index=nil)
|
518
|
+
ClassConstant.new( nil, Constant::CONSTANT_Class, name_index )
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require "javaclass/base"
|
2
|
+
|
3
|
+
module JavaClass
|
4
|
+
|
5
|
+
#
|
6
|
+
#=== Field,Methodの基底クラス
|
7
|
+
#
|
8
|
+
class Member
|
9
|
+
include JavaClass::Base
|
10
|
+
include JavaClass::Converters
|
11
|
+
include JavaClass::Item
|
12
|
+
|
13
|
+
#
|
14
|
+
#===コンストラクタ
|
15
|
+
#
|
16
|
+
#*java_class::メンバーの所有者であるJavaクラス
|
17
|
+
#
|
18
|
+
def initialize( java_class )
|
19
|
+
@java_class = java_class
|
20
|
+
@attributes = {}
|
21
|
+
end
|
22
|
+
#
|
23
|
+
#===名前を取得する。
|
24
|
+
#
|
25
|
+
#<b>戻り値</b>::名前
|
26
|
+
#
|
27
|
+
def name
|
28
|
+
@java_class.get_constant_value(@name_index)
|
29
|
+
end
|
30
|
+
#
|
31
|
+
#===ディスクリプタを取得する。
|
32
|
+
#
|
33
|
+
#<b>戻り値</b>::ディスクリプタ
|
34
|
+
#
|
35
|
+
def descriptor
|
36
|
+
@java_class.get_constant_value(@descriptor_index)
|
37
|
+
end
|
38
|
+
def to_bytes()
|
39
|
+
bytes = @access_flag.to_bytes()
|
40
|
+
bytes += to_byte( @name_index, 2)
|
41
|
+
bytes += to_byte( @descriptor_index, 2)
|
42
|
+
bytes += to_byte( @attributes.size, 2)
|
43
|
+
@attributes.keys.sort!.each {|k|
|
44
|
+
bytes += @attributes[k].to_bytes()
|
45
|
+
}
|
46
|
+
return bytes
|
47
|
+
end
|
48
|
+
# JavaClass
|
49
|
+
attr :java_class, true
|
50
|
+
# アクセスフラグ
|
51
|
+
attr :access_flag, true
|
52
|
+
# 名前を示すconstant_poolのインデックス
|
53
|
+
attr :name_index, true
|
54
|
+
# ディスクリプタを示すconstant_poolのインデックス
|
55
|
+
attr :descriptor_index, true
|
56
|
+
# 属性名をキーとする属性のハッシュ
|
57
|
+
attr :attributes, true
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
#=== Field
|
62
|
+
#
|
63
|
+
class Field < Member
|
64
|
+
#
|
65
|
+
#===コンストラクタ
|
66
|
+
#
|
67
|
+
#*java_class::Fieldの所有者であるJavaクラス
|
68
|
+
#
|
69
|
+
def initialize( java_class )
|
70
|
+
super( java_class )
|
71
|
+
end
|
72
|
+
#
|
73
|
+
#=== 定数フィールドの初期値を取得する
|
74
|
+
#
|
75
|
+
#<b>戻り値</b>::定数フィールドの初期値。定数でない場合や初期値が設定されていない場合nil
|
76
|
+
#
|
77
|
+
def static_value
|
78
|
+
(attributes.key? "ConstantValue") ? attributes["ConstantValue"].value : nil
|
79
|
+
end
|
80
|
+
def to_s
|
81
|
+
str = ""
|
82
|
+
str << attributes["Signature"].to_s << "\n" if attributes.key? "Signature"
|
83
|
+
str << "// !deprecated!\n" if deprecated?
|
84
|
+
str << annotations.inject( "" ){|s, e| s << e.to_s << "\n" }
|
85
|
+
datas = []
|
86
|
+
datas << access_flag.to_s if access_flag.to_s.length > 0
|
87
|
+
datas << convert_field_descriptor(descriptor)
|
88
|
+
datas << name
|
89
|
+
str << datas.join(" ")
|
90
|
+
str << " = " << attributes["ConstantValue"].to_s if attributes.key? "ConstantValue"
|
91
|
+
return str
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
#=== Method
|
97
|
+
#
|
98
|
+
class Method < Member
|
99
|
+
#
|
100
|
+
#===コンストラクタ
|
101
|
+
#
|
102
|
+
#*java_class::Methodの所有者であるJavaクラス
|
103
|
+
#
|
104
|
+
def initialize( java_class )
|
105
|
+
super( java_class )
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
#=== メソッドで発生する例外のクラス名を配列で取得する
|
110
|
+
#
|
111
|
+
#<b>戻り値</b>::メソッドで発生する例外クラス名の配列
|
112
|
+
#
|
113
|
+
def exceptions
|
114
|
+
(attributes.key? "Exceptions") ?
|
115
|
+
attributes["Exceptions"].exceptions.map{|i|i.name} : []
|
116
|
+
end
|
117
|
+
#
|
118
|
+
#=== 引数のクラス名を配列で取得する
|
119
|
+
#
|
120
|
+
#<b>戻り値</b>::引数のクラス名の配列
|
121
|
+
#
|
122
|
+
def parameters
|
123
|
+
convert_method_descriptor( descriptor )[:args]
|
124
|
+
end
|
125
|
+
#
|
126
|
+
#=== メソッドの戻り値クラス名を取得する
|
127
|
+
#
|
128
|
+
#<b>戻り値</b>::メソッドの戻り値クラス名
|
129
|
+
#
|
130
|
+
def return_type
|
131
|
+
convert_method_descriptor( descriptor )[:return]
|
132
|
+
end
|
133
|
+
#
|
134
|
+
#===指定したパラメータに設定されているアノテーションを配列で取得する。
|
135
|
+
#
|
136
|
+
#<b>戻り値</b>::アノテーションの配列
|
137
|
+
#
|
138
|
+
def parameter_annotations(index)
|
139
|
+
['RuntimeVisibleParameterAnnotations',
|
140
|
+
'RuntimeInvisibleParameterAnnotations'].inject([]) { |l, k|
|
141
|
+
l.concat( attributes[k][index] ) if attributes.key? k
|
142
|
+
l
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
def to_s
|
147
|
+
str = ""
|
148
|
+
str << attributes["Signature"].to_s << "\n" if attributes.key? "Signature"
|
149
|
+
str << "// !deprecated!\n" if deprecated?
|
150
|
+
str << annotations.inject( "" ){|s, e| s << e.to_s << "\n" }
|
151
|
+
d = convert_method_descriptor( descriptor )
|
152
|
+
i = 0
|
153
|
+
args = d[:args].map(){|item|
|
154
|
+
a = parameter_annotations(i)
|
155
|
+
tmp = a.length > 0 ? a.map(){|a| a.to_s}.join("\n") << " " : ""
|
156
|
+
i+=1
|
157
|
+
tmp << "#{item} arg#{i}"
|
158
|
+
}.join(", ")
|
159
|
+
datas = []
|
160
|
+
datas << access_flag.to_s if access_flag.to_s.length > 0
|
161
|
+
datas << d[:return]
|
162
|
+
datas << name
|
163
|
+
datas << "("
|
164
|
+
datas << args
|
165
|
+
datas << ")"
|
166
|
+
str << datas.join(" ")
|
167
|
+
str << "\n" << attributes["Exceptions"].to_s if attributes.key? "Exceptions"
|
168
|
+
if ( attributes.key? "Code")
|
169
|
+
str << " {\n"
|
170
|
+
# codes = attributes["Code"]
|
171
|
+
# local_types = codes.attributes["LocalVariableTypeTable"] if codes.attributes.key? "LocalVariableTypeTable"
|
172
|
+
#
|
173
|
+
# if codes.attributes.key? "LocalVariableTable"
|
174
|
+
# codes.attributes["LocalVariableTable"].local_variable_table.each {|l|
|
175
|
+
# type = local_types.find_by_index(l.index) if local_types != nil
|
176
|
+
# str << " // signature " << type.signature << "\n" if type != nil
|
177
|
+
# str << " " << convert_field_descriptor(l.descriptor)
|
178
|
+
# str << " " << l.name << ";\n"
|
179
|
+
# }
|
180
|
+
# end
|
181
|
+
# str << "\n"
|
182
|
+
# lines = codes.attributes["LineNumberTable"] if codes.attributes.key? "LineNumberTable"
|
183
|
+
# codes.codes.each_index {|i|
|
184
|
+
# str << " " << convert_code(codes.codes[i])
|
185
|
+
# str << " // line : #{lines.line_number(i)}" if lines != nil && lines.line_number(i) != nil
|
186
|
+
# str << "\n";
|
187
|
+
# }
|
188
|
+
str << "}"
|
189
|
+
end
|
190
|
+
str << " #{attributes['AnnotationDefault'].to_s}" if attributes.key? 'AnnotationDefault'
|
191
|
+
return str
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|