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,449 @@
|
|
1
|
+
require "javaclass/base"
|
2
|
+
require "stringio"
|
3
|
+
|
4
|
+
module JavaClass
|
5
|
+
|
6
|
+
#
|
7
|
+
#=== byte配列をIOに見せかける。
|
8
|
+
#
|
9
|
+
class ArrayIO
|
10
|
+
def initialize( array )
|
11
|
+
@array = array
|
12
|
+
end
|
13
|
+
def getc
|
14
|
+
@array.shift
|
15
|
+
end
|
16
|
+
def read(length)
|
17
|
+
@array.slice!(0, length).pack("C*")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module_function
|
22
|
+
|
23
|
+
#
|
24
|
+
#===IOまたはバイト配列からクラスを読み込む。
|
25
|
+
#
|
26
|
+
#*io::IOまたはバイト配列。(IO.getc,IO.read(length)が実装されていればOK)
|
27
|
+
#<b>戻り値</b>::クラス
|
28
|
+
#
|
29
|
+
def from( src )
|
30
|
+
|
31
|
+
if ( src.kind_of?(Array) )
|
32
|
+
io = ArrayIO.new(src)
|
33
|
+
else
|
34
|
+
io = src
|
35
|
+
end
|
36
|
+
|
37
|
+
# magic
|
38
|
+
raise "illegal class data." if read( 4, io ) != 0xCAFEBABE
|
39
|
+
|
40
|
+
java_class = JavaClass::Class.new
|
41
|
+
|
42
|
+
# version
|
43
|
+
java_class.minor_version = read( 2, io )
|
44
|
+
java_class.major_version = read( 2, io )
|
45
|
+
|
46
|
+
# constant_pool
|
47
|
+
constant_pool_count = read( 2, io )
|
48
|
+
index = 1
|
49
|
+
while( index < constant_pool_count)
|
50
|
+
java_class.constant_pool[index] = read_constant(io, java_class)
|
51
|
+
# constantがdouble or longの場合、次のindexは欠番。
|
52
|
+
tag = java_class.constant_pool[index].tag
|
53
|
+
if tag == JavaClass::Constant::CONSTANT_Double \
|
54
|
+
|| tag == JavaClass::Constant::CONSTANT_Long
|
55
|
+
index += 1
|
56
|
+
end
|
57
|
+
index += 1
|
58
|
+
end
|
59
|
+
|
60
|
+
# access_flag
|
61
|
+
access_flag = read( 2, io )
|
62
|
+
java_class.access_flag = ClassAccessFlag.new(access_flag)
|
63
|
+
|
64
|
+
# class
|
65
|
+
java_class.this_class_index = read( 2, io )
|
66
|
+
java_class.super_class_index = read( 2, io )
|
67
|
+
interfaces_count = read( 2, io )
|
68
|
+
interfaces_count.times{|i|
|
69
|
+
java_class.interface_indexs << read( 2, io )
|
70
|
+
}
|
71
|
+
|
72
|
+
# field
|
73
|
+
fields_count = read( 2, io )
|
74
|
+
fields_count.times {|i|
|
75
|
+
java_class.fields << read_field( io, java_class )
|
76
|
+
}
|
77
|
+
|
78
|
+
# method
|
79
|
+
methods_count = read( 2, io )
|
80
|
+
methods_count.times {|i|
|
81
|
+
java_class.methods << read_method( io, java_class )
|
82
|
+
}
|
83
|
+
|
84
|
+
# attribute
|
85
|
+
read_attributes(io, java_class, java_class )
|
86
|
+
|
87
|
+
return java_class
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
#=== メソッドを読み込む
|
92
|
+
#
|
93
|
+
#*io::IO
|
94
|
+
#*java_class::Javaクラス
|
95
|
+
#
|
96
|
+
def read_method( io, java_class )
|
97
|
+
m = Method.new( java_class )
|
98
|
+
m.access_flag = MethodAccessFlag.new(read( 2, io ))
|
99
|
+
m.name_index = read( 2, io )
|
100
|
+
m.descriptor_index = read( 2, io )
|
101
|
+
read_attributes( io, java_class, m )
|
102
|
+
return m
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
#=== フィールドを読み込む
|
107
|
+
#
|
108
|
+
#*io::IO
|
109
|
+
#*java_class::Javaクラス
|
110
|
+
#
|
111
|
+
def read_field( io, java_class )
|
112
|
+
f = Field.new( java_class )
|
113
|
+
f.access_flag = FieldAccessFlag.new(read( 2, io ))
|
114
|
+
f.name_index = read( 2, io )
|
115
|
+
f.descriptor_index = read( 2, io )
|
116
|
+
read_attributes( io, java_class, f )
|
117
|
+
return f
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
#=== IOから指定したバイト数だけデータを読み込んで返す
|
122
|
+
#
|
123
|
+
#*size::読み込むだバイト数
|
124
|
+
#*io::IO
|
125
|
+
#<b>戻り値</b>::データ
|
126
|
+
#
|
127
|
+
def read( size, io )
|
128
|
+
res = 0
|
129
|
+
size.times{|i| res = res << 8 | io.getc }
|
130
|
+
return res
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
#===IOからconstantを読み込む。
|
135
|
+
#
|
136
|
+
#*io::IO。IO.getcが実装されていればOK
|
137
|
+
#*java_class::constantの所有者であるJavaクラス
|
138
|
+
#<b>戻り値</b>::クラス
|
139
|
+
#
|
140
|
+
def read_constant(io, java_class)
|
141
|
+
tag = read( 1, io )
|
142
|
+
case tag
|
143
|
+
when JavaClass::Constant::CONSTANT_Class
|
144
|
+
name_index = read( 2, io )
|
145
|
+
cp = ClassConstant.new( java_class, tag, name_index )
|
146
|
+
when JavaClass::Constant::CONSTANT_Fieldref, \
|
147
|
+
JavaClass::Constant::CONSTANT_Methodref, JavaClass::Constant::CONSTANT_InterfaceMethodref
|
148
|
+
class_name_index = read( 2, io )
|
149
|
+
name_and_type_index = read( 2, io )
|
150
|
+
case tag
|
151
|
+
when JavaClass::Constant::CONSTANT_Fieldref
|
152
|
+
cp = FieldRefConstant.new( java_class, tag, \
|
153
|
+
class_name_index, name_and_type_index )
|
154
|
+
when JavaClass::Constant::CONSTANT_Methodref
|
155
|
+
cp = MethodRefConstant.new( java_class, tag, \
|
156
|
+
class_name_index, name_and_type_index )
|
157
|
+
when JavaClass::Constant::CONSTANT_InterfaceMethodref
|
158
|
+
cp = InterfaceMethodRefConstant.new( java_class, tag, \
|
159
|
+
class_name_index, name_and_type_index )
|
160
|
+
end
|
161
|
+
when JavaClass::Constant::CONSTANT_NameAndType
|
162
|
+
name_index = read( 2, io )
|
163
|
+
descriptor_index = read( 2, io )
|
164
|
+
cp = NameAndTypeConstant.new( java_class, tag, name_index, descriptor_index )
|
165
|
+
when JavaClass::Constant::CONSTANT_String
|
166
|
+
string_index = read( 2, io )
|
167
|
+
cp = StringConstant.new( java_class, tag, string_index )
|
168
|
+
when JavaClass::Constant::CONSTANT_Integer
|
169
|
+
bytes = read( 4, io )
|
170
|
+
cp = IntegerConstant.new( java_class, tag, bytes )
|
171
|
+
when JavaClass::Constant::CONSTANT_Float
|
172
|
+
bytes = read( 4, io )
|
173
|
+
cp = FloatConstant.new( java_class, tag, bytes )
|
174
|
+
when JavaClass::Constant::CONSTANT_Long
|
175
|
+
bytes = read( 8, io )
|
176
|
+
cp = LongConstant.new( java_class, tag, bytes )
|
177
|
+
when JavaClass::Constant::CONSTANT_Double
|
178
|
+
bytes = read( 8, io )
|
179
|
+
cp = DoubleConstant.new( java_class, tag, bytes )
|
180
|
+
when JavaClass::Constant::CONSTANT_Utf8
|
181
|
+
length = read( 2, io )
|
182
|
+
bytes = io.read(length)
|
183
|
+
cp = UTF8Constant.new( java_class, tag, bytes )
|
184
|
+
else
|
185
|
+
raise "unknown constant_pool_tag. tag =" << tag.to_s
|
186
|
+
end
|
187
|
+
return cp
|
188
|
+
end
|
189
|
+
|
190
|
+
#
|
191
|
+
#=== 属性を読み込む
|
192
|
+
#
|
193
|
+
#*io::IO
|
194
|
+
#*java_class::Javaクラス
|
195
|
+
#*owner::属性の所有者
|
196
|
+
#
|
197
|
+
def read_attributes( io, java_class, owner )
|
198
|
+
count = read( 2, io )
|
199
|
+
count.times {|i|
|
200
|
+
attr = read_attribute( io, java_class )
|
201
|
+
owner.attributes[attr.name] = attr
|
202
|
+
}
|
203
|
+
end
|
204
|
+
#
|
205
|
+
#=== 属性を読み込む
|
206
|
+
#
|
207
|
+
#*io::IO
|
208
|
+
#*java_class::Javaクラス
|
209
|
+
#
|
210
|
+
def read_attribute( io, java_class )
|
211
|
+
|
212
|
+
# 名前
|
213
|
+
name_index = read( 2, io )
|
214
|
+
name = java_class.get_constant_value( name_index )
|
215
|
+
length = read( 4, io )
|
216
|
+
attr = nil
|
217
|
+
case name
|
218
|
+
when "ConstantValue"
|
219
|
+
constant_value_index = read( 2, io )
|
220
|
+
attr = ConstantValueAttribute.new( java_class, name_index, constant_value_index )
|
221
|
+
when "Exceptions"
|
222
|
+
exception_index_table = []
|
223
|
+
number_of_exceptions = read( 2, io )
|
224
|
+
number_of_exceptions.times {
|
225
|
+
exception_index_table << read( 2, io )
|
226
|
+
}
|
227
|
+
attr = ExceptionsAttribute.new( java_class, name_index, exception_index_table )
|
228
|
+
when "InnerClasses"
|
229
|
+
classes = []
|
230
|
+
number_of_classes = read( 2, io )
|
231
|
+
number_of_classes.times {
|
232
|
+
classes << read_inner_class( io, java_class )
|
233
|
+
}
|
234
|
+
attr = InnerClassesAttribute.new( java_class, name_index, classes )
|
235
|
+
when "EnclosingMethod"
|
236
|
+
class_index = read( 2, io )
|
237
|
+
method_index = read( 2, io )
|
238
|
+
attr = EnclosingMethodAttribute.new( java_class, name_index, class_index, method_index )
|
239
|
+
when "SourceFile"
|
240
|
+
source_file_index = read( 2, io )
|
241
|
+
attr = SourceFileAttribute.new( java_class, name_index, source_file_index )
|
242
|
+
when "SourceDebugExtension"
|
243
|
+
debug_extension = io.read(length)
|
244
|
+
attr = SourceDebugExtensionAttribute.new( java_class, name_index, debug_extension )
|
245
|
+
when "AnnotationDefault"
|
246
|
+
value = read_annotation_element_value( io, java_class )
|
247
|
+
attr = AnnotationDefaultAttribute.new( java_class, name_index, value )
|
248
|
+
when "Signature"
|
249
|
+
signature_index = read( 2, io )
|
250
|
+
attr = SignatureAttribute.new( java_class, name_index, signature_index )
|
251
|
+
when "Deprecated"
|
252
|
+
attr = DeprecatedAttribute.new( java_class, name_index )
|
253
|
+
when "Synthetic"
|
254
|
+
attr = SyntheticAttribute.new( java_class, name_index )
|
255
|
+
when "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations"
|
256
|
+
annotations = read_annotations( io, java_class )
|
257
|
+
attr = AnnotationsAttribute.new( java_class, name_index, annotations )
|
258
|
+
when "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations"
|
259
|
+
params = []
|
260
|
+
num_parameters = read( 1, io )
|
261
|
+
num_parameters.times {
|
262
|
+
params << read_annotations( io, java_class )
|
263
|
+
}
|
264
|
+
attr = ParameterAnnotationsAttribute.new( java_class, name_index, params )
|
265
|
+
when "AnnotationDefault"
|
266
|
+
value = read_annotation_element_value( io, java_class )
|
267
|
+
attr = AnnotationDefaultAttribute.new( java_class, name_index, value )
|
268
|
+
when "Code"
|
269
|
+
max_stack = read( 2, io )
|
270
|
+
max_locals = read( 2, io )
|
271
|
+
codes = []
|
272
|
+
code_length = read( 4, io )
|
273
|
+
code_length.times {
|
274
|
+
codes << read( 1, io )
|
275
|
+
}
|
276
|
+
exception_table = []
|
277
|
+
exception_table_length = read( 2, io )
|
278
|
+
exception_table_length.times {
|
279
|
+
exception_table << read_exception( io, java_class )
|
280
|
+
}
|
281
|
+
attr = CodeAttribute.new( java_class, name_index, max_stack, \
|
282
|
+
max_locals, codes, exception_table, {} )
|
283
|
+
read_attributes( io, java_class, attr )
|
284
|
+
when "LineNumberTable"
|
285
|
+
line_number_table = []
|
286
|
+
line_number_table_length = read( 2, io )
|
287
|
+
line_number_table_length.times {
|
288
|
+
line_number_table << read_line_number( io, java_class )
|
289
|
+
}
|
290
|
+
attr = LineNumberTableAttribute.new( java_class, name_index, line_number_table )
|
291
|
+
when "LocalVariableTable"
|
292
|
+
local_variable_table = []
|
293
|
+
local_variable_table_length = read( 2, io )
|
294
|
+
local_variable_table_length.times {
|
295
|
+
local_variable_table << read_local_variable( io, java_class )
|
296
|
+
}
|
297
|
+
attr = LocalVariableTableAttribute.new( java_class, name_index, local_variable_table )
|
298
|
+
when "LocalVariableTypeTable"
|
299
|
+
local_variable_type_table = []
|
300
|
+
local_variable_type_table_length = read( 2, io )
|
301
|
+
local_variable_type_table_length.times {
|
302
|
+
local_variable_type_table << read_local_variable_type( io, java_class )
|
303
|
+
}
|
304
|
+
attr = LocalVariableTypeTableAttribute.new( java_class, name_index, local_variable_type_table )
|
305
|
+
else
|
306
|
+
read( length, io ) # 読み飛ばす。
|
307
|
+
attr = Attribute.new( java_class, name_index )
|
308
|
+
end
|
309
|
+
return attr
|
310
|
+
end
|
311
|
+
|
312
|
+
#
|
313
|
+
#=== インナークラスを読み込む
|
314
|
+
#
|
315
|
+
#*io::IO
|
316
|
+
#*java_class::Javaクラス
|
317
|
+
#
|
318
|
+
def read_inner_class( io, java_class )
|
319
|
+
inner_class_info_index = read( 2, io )
|
320
|
+
outer_class_info_index = read( 2, io )
|
321
|
+
inner_name_index = read( 2, io )
|
322
|
+
inner_class_access_flags = InnerClassAccessFlag.new( read( 2, io ) )
|
323
|
+
return InnerClass.new( java_class, inner_class_info_index,
|
324
|
+
outer_class_info_index, inner_name_index, inner_class_access_flags )
|
325
|
+
end
|
326
|
+
|
327
|
+
#
|
328
|
+
#=== アノテーションを読み込む
|
329
|
+
#
|
330
|
+
#*io::IO
|
331
|
+
#*java_class::Javaクラス
|
332
|
+
#
|
333
|
+
def read_annotations( io, java_class )
|
334
|
+
annotations = []
|
335
|
+
num_annotations = read( 2, io )
|
336
|
+
num_annotations.times {|i|
|
337
|
+
annotations << read_annotation( io, java_class )
|
338
|
+
}
|
339
|
+
return annotations
|
340
|
+
end
|
341
|
+
|
342
|
+
#
|
343
|
+
#=== アノテーションを読み込む
|
344
|
+
#
|
345
|
+
#*io::IO
|
346
|
+
#*java_class::Javaクラス
|
347
|
+
#
|
348
|
+
def read_annotation( io, java_class )
|
349
|
+
elements = {}
|
350
|
+
type_index = read( 2, io )
|
351
|
+
num_element_value_pairs = read( 2, io )
|
352
|
+
num_element_value_pairs.times {|i|
|
353
|
+
e = read_annotation_element( io, java_class )
|
354
|
+
elements[e.name] = e
|
355
|
+
}
|
356
|
+
return Annotation.new( java_class, type_index, elements )
|
357
|
+
end
|
358
|
+
|
359
|
+
#
|
360
|
+
#=== アノテーションデータを読み込む
|
361
|
+
#
|
362
|
+
#*io::IO
|
363
|
+
#*java_class::Javaクラス
|
364
|
+
#
|
365
|
+
def read_annotation_element( io, java_class )
|
366
|
+
element_name_index = read( 2, io )
|
367
|
+
value = read_annotation_element_value( io, java_class )
|
368
|
+
return AnnotationElement.new( java_class, element_name_index, value )
|
369
|
+
end
|
370
|
+
|
371
|
+
#
|
372
|
+
#=== アノテーションデータを読み込む
|
373
|
+
#
|
374
|
+
#*io::IO
|
375
|
+
#*java_class::Javaクラス
|
376
|
+
#
|
377
|
+
def read_annotation_element_value( io, java_class )
|
378
|
+
tag = read( 1, io )
|
379
|
+
value = nil
|
380
|
+
case tag.chr
|
381
|
+
when 'B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', 's'
|
382
|
+
const_value_index = read( 2, io )
|
383
|
+
value = ConstAnnotationElementValue.new( java_class, tag, const_value_index )
|
384
|
+
when 'e'
|
385
|
+
type_name_index = read( 2, io )
|
386
|
+
const_name_index = read( 2, io )
|
387
|
+
value = EnumAnnotationElementValue.new( java_class, tag, type_name_index, const_name_index )
|
388
|
+
when 'c'
|
389
|
+
class_info_index = read( 2, io )
|
390
|
+
value = ClassAnnotationElementValue.new( java_class, tag, class_info_index )
|
391
|
+
when '@'
|
392
|
+
annotation = read_annotation( io, java_class )
|
393
|
+
value = AnnotationAnnotationElementValue.new( java_class, tag, annotation )
|
394
|
+
when '['
|
395
|
+
array = []
|
396
|
+
num_values = read( 2, io )
|
397
|
+
num_values.times{|i|
|
398
|
+
array << read_annotation_element_value( io, java_class )
|
399
|
+
}
|
400
|
+
value = ArrayAnnotationElementValue.new( java_class, tag, array )
|
401
|
+
end
|
402
|
+
return value
|
403
|
+
end
|
404
|
+
|
405
|
+
#
|
406
|
+
#=== メソッドの例外を読み込む
|
407
|
+
#
|
408
|
+
def read_exception( io, java_class )
|
409
|
+
start_pc = read( 2, io )
|
410
|
+
end_pc = read( 2, io )
|
411
|
+
handler_pc = read( 2, io )
|
412
|
+
catch_type = read( 2, io )
|
413
|
+
return Excpetion.new( java_class, start_pc, end_pc, handler_pc, catch_type )
|
414
|
+
end
|
415
|
+
|
416
|
+
#
|
417
|
+
#=== 行番号を読み込む
|
418
|
+
#
|
419
|
+
def read_line_number( io, java_class )
|
420
|
+
start_pc = read( 2, io )
|
421
|
+
line_number = read( 2, io )
|
422
|
+
return LineNumber.new( java_class, start_pc, line_number )
|
423
|
+
end
|
424
|
+
|
425
|
+
#
|
426
|
+
#=== メソッドのローカル変数を読み込む
|
427
|
+
#
|
428
|
+
def read_local_variable( io, java_class )
|
429
|
+
start_pc = read( 2, io )
|
430
|
+
length = read( 2, io )
|
431
|
+
name_index = read( 2, io )
|
432
|
+
descriptor_index = read( 2, io )
|
433
|
+
index = read( 2, io )
|
434
|
+
return LocalVariable.new( java_class, \
|
435
|
+
start_pc, length, name_index, descriptor_index, index )
|
436
|
+
end
|
437
|
+
#
|
438
|
+
#=== メソッドのローカル変数の型を読み込む
|
439
|
+
#
|
440
|
+
def read_local_variable_type( io, java_class )
|
441
|
+
start_pc = read( 2, io )
|
442
|
+
length = read( 2, io )
|
443
|
+
name_index = read( 2, io )
|
444
|
+
signature_index = read( 2, io )
|
445
|
+
index = read( 2, io )
|
446
|
+
return LocalVariableType.new( java_class, \
|
447
|
+
start_pc, length, name_index, signature_index, index )
|
448
|
+
end
|
449
|
+
end
|
data/lib/javaclass.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
require "rubygems"
|
3
|
+
require "javaclass"
|
4
|
+
require "zip/zip"
|
5
|
+
|
6
|
+
|
7
|
+
module Zip
|
8
|
+
class ZipInputStream
|
9
|
+
def getc
|
10
|
+
read(1)[0]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Zip::ZipFile.foreach(ARGV[0]) {|entry|
|
16
|
+
next unless entry.file?
|
17
|
+
next unless entry.name =~ /.*\.class$/
|
18
|
+
entry.get_input_stream {|io|
|
19
|
+
jc = JavaClass.from io
|
20
|
+
puts jc.name
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
$: << "../lib"
|
4
|
+
|
5
|
+
require "javaclass"
|
6
|
+
require "kconv"
|
7
|
+
require "erb"
|
8
|
+
|
9
|
+
|
10
|
+
PATH = 'aaa'
|
11
|
+
|
12
|
+
def create( file )
|
13
|
+
erb = ERB.new(IO.read("./assert.erb"), nil, "%" )
|
14
|
+
open( PATH + "/" + file, "r+b" ) {|io|
|
15
|
+
jc = JavaClass.from io
|
16
|
+
puts erb.result(binding).tosjis
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
Dir.foreach( PATH.gsub(/\\/, "/") ) {|f|
|
21
|
+
create( f ) if f =~ /\.class$/ && !( f =~ /\$[0-9]+\.class$/ )
|
22
|
+
}
|
23
|
+
|
24
|
+
=begin
|
25
|
+
% name = jc.this_class.name
|
26
|
+
/**
|
27
|
+
* {@link <%= name.gsub(/\$/, ".") %>} が同一であることを評価する。
|
28
|
+
*
|
29
|
+
* @param expected 期待値
|
30
|
+
* @param actual 実際の値
|
31
|
+
*/
|
32
|
+
public static final void assertEquals(
|
33
|
+
<%= name.gsub(/\$/, ".") %> expected,
|
34
|
+
<%= name.gsub(/\$/, ".") %> actual ) {
|
35
|
+
% jc.methods.each { |m|
|
36
|
+
% if m.name =~ /^get([A-Z][0-9a-zA-Z\_]+)/ || m.name =~ /^is([A-Z][0-9a-zA-Z\_])+/
|
37
|
+
% sname = $1
|
38
|
+
% prefix = m.attributes.key?('Deprecated') ? "//" : ""
|
39
|
+
% d = m.convert_method_descriptor( m.descriptor )
|
40
|
+
% next if d[:args].length > 0
|
41
|
+
% if d[:return] =~ /List/
|
42
|
+
<%= prefix %> <%= d[:return] %> actual<%= sname%> = actual.<%= m.name %>();
|
43
|
+
<%= prefix %> <%= d[:return] %> expected<%= sname%> = expected.<%= m.name %>();
|
44
|
+
<%= prefix %> if ( expected<%= sname%> != null ) {
|
45
|
+
<%= prefix %> assertEquals( actual<%= sname%>.size(), expected<%= sname%>.size() );
|
46
|
+
<%= prefix %> for ( int i = 0; i < expected<%= sname%>.size(); i++ ) {
|
47
|
+
<%= prefix %> assertEquals( expected<%= sname%>.get(i), actual<%= sname%>.get(i) );
|
48
|
+
<%= prefix %> }
|
49
|
+
<%= prefix %> } else {
|
50
|
+
<%= prefix %> assertEquals( actual<%= sname%>, expected<%= sname%> );
|
51
|
+
<%= prefix %> }
|
52
|
+
% elsif d[:return] =~ /.*\[\]/
|
53
|
+
<%= prefix %> <%= d[:return] %> actual<%= sname%> = actual.<%= m.name %>();
|
54
|
+
<%= prefix %> <%= d[:return] %> expected<%= sname%> = expected.<%= m.name %>();
|
55
|
+
<%= prefix %> if ( expected<%= sname%> != null ) {
|
56
|
+
<%= prefix %> assertEquals( actual<%= sname%>.length, expected<%= sname%>.length );
|
57
|
+
<%= prefix %> for ( int i = 0; i < expected<%= sname%>.length; i++ ) {
|
58
|
+
<%= prefix %> assertEquals( expected<%= sname%>[i], actual<%= sname%>[i] );
|
59
|
+
<%= prefix %> }
|
60
|
+
<%= prefix %> } else {
|
61
|
+
<%= prefix %> assertEquals( actual<%= sname%>, expected<%= sname%> );
|
62
|
+
<%= prefix %> }
|
63
|
+
% else
|
64
|
+
<%= prefix %> assertEquals( expected.<%= m.name %>(), actual.<%= m.name %>() );
|
65
|
+
% end
|
66
|
+
% end
|
67
|
+
% }
|
68
|
+
}
|
69
|
+
=end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,45 @@
|
|
1
|
+
package com.example;
|
2
|
+
|
3
|
+
import java.io.Serializable;
|
4
|
+
import java.util.ArrayList;
|
5
|
+
import java.util.List;
|
6
|
+
|
7
|
+
|
8
|
+
public interface Constants
|
9
|
+
extends Serializable {
|
10
|
+
|
11
|
+
static final String stringConstant = "あいう";
|
12
|
+
static int intConstant = 1;
|
13
|
+
static int intConstant2 = -1;
|
14
|
+
static int intConstantMax = Integer.MAX_VALUE;
|
15
|
+
static int intConstantMin = Integer.MIN_VALUE;
|
16
|
+
|
17
|
+
public static long longConstant = 100L;
|
18
|
+
public static long longConstant2 = -100L;
|
19
|
+
public static long longConstantMax = Long.MAX_VALUE;
|
20
|
+
public static long longConstantMin = Long.MIN_VALUE;
|
21
|
+
|
22
|
+
public static final List<String> listConstant = new ArrayList<String>();
|
23
|
+
|
24
|
+
float floatConstant0 = 0F;
|
25
|
+
float floatConstant = 16.5F;
|
26
|
+
float floatConstant2 = -16.5F;
|
27
|
+
float floatConstantNan = Float.NaN;
|
28
|
+
float floatConstantMax = Float.MAX_VALUE;
|
29
|
+
float floatConstantMin = Float.MIN_VALUE;
|
30
|
+
float floatConstantNegativeInfinity = Float.NEGATIVE_INFINITY;
|
31
|
+
float floatConstantPositiveInfinity = Float.POSITIVE_INFINITY;
|
32
|
+
|
33
|
+
double doubleConstant0 = 0D;
|
34
|
+
double doubleConstant = 16.5D;
|
35
|
+
double doubleConstant2 = -16.5D;
|
36
|
+
double doubleConstantMax = Double.MAX_VALUE;
|
37
|
+
double doubleConstantMin = Double.MIN_VALUE;
|
38
|
+
double doubleConstantNan = Double.NaN;
|
39
|
+
double doubleConstantNegativeInfinity = Double.NEGATIVE_INFINITY;
|
40
|
+
double doubleConstantPositiveInfinity = Double.POSITIVE_INFINITY;
|
41
|
+
|
42
|
+
public InnerClass.StaticInnerClass xx
|
43
|
+
= new InnerClass.StaticInnerClass();
|
44
|
+
|
45
|
+
}
|