unageanu-javaclass 0.0.1 → 0.1.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.
@@ -1,282 +1,282 @@
1
- require "javaclass/base"
2
-
3
- module JavaClass
4
-
5
- #
6
- #===クラス
7
- #
8
- class Class
9
- include JavaClass::Base
10
- include JavaClass::Converters
11
- include JavaClass::Item
12
-
13
- #
14
- #=== コンストラクタ
15
- #
16
- def initialize( )
17
- @constant_pool = []
18
- @interface_indexs = []
19
- @fields = []
20
- @methods = []
21
- @attributes = {}
22
- end
23
-
24
- #
25
- #===クラスバージョンを文字列で取得する
26
- #<b>戻り値</b>::クラスバージョン
27
- #
28
- def version
29
- @major_version.to_s << "." << @minor_version.to_s
30
- end
31
-
32
- #
33
- #=== クラス名を取得する。
34
- #<b>戻り値</b>::クラス名
35
- #
36
- def name
37
- get_constant(@this_class_index).name
38
- end
39
-
40
- #
41
- #=== 親クラス名を取得する。
42
- #<b>戻り値</b>::親クラス名
43
- #
44
- def super_class
45
- get_constant(@super_class_index).name
46
- end
47
-
48
- #
49
- #=== 実装しているインターフェイス名を配列で取得する。
50
- #<b>戻り値</b>::実装しているインターフェイス名の配列
51
- #
52
- def interfaces
53
- @interface_indexs.map {|i| get_constant(i).name }
54
- end
55
-
56
- #
57
- #=== ソースファイルを取得する。
58
- #<b>戻り値</b>::ソースファイル
59
- #
60
- def source_file
61
- attributes.key?('SourceFile') ?
62
- attributes['SourceFile'].source_file : nil
63
- end
64
-
65
- #
66
- #=== クラス名を取得する。
67
- #<b>戻り値</b>::クラス名
68
- #
69
- def enclosing_method
70
- attributes.key?('EnclosingMethod') ?
71
- attributes['EnclosingMethod'] : nil
72
- end
73
-
74
- #
75
- #=== クラスで利用しているインナークラスを配列で取得する。
76
- #<b>戻り値</b>::インナークラスの配列
77
- #
78
- def inner_classes
79
- attributes.key?('InnerClasses') ?
80
- attributes['InnerClasses'].classes : []
81
- end
82
-
83
- #
84
- #===indexのConstantを取得する。
85
- #*index::constant_poolでのConstantのインデックス
86
- #<b>戻り値</b>::Constant
87
- #
88
- def get_constant( index )
89
- return nil if index == 0
90
- return @constant_pool[index]
91
- end
92
- #
93
- #===indexのConstantの値を取得する。
94
- #*index::constant_poolでのConstantのインデックス
95
- #<b>戻り値</b>::Constantの値
96
- #
97
- def get_constant_value( index )
98
- return nil if index == 0
99
- return @constant_pool[index].bytes
100
- end
101
- #
102
- #===indexのConstantの値の文字列表現を取得する。
103
- #*index::constant_poolでのConstantのインデックス
104
- #<b>戻り値</b>::Constantの値の文字列表現
105
- #
106
- def get_constant_as_string( index )
107
- return nil if index == 0
108
- return @constant_pool[index].to_s
109
- end
110
- #
111
- #===同じConstantがなければ追加する。
112
- #*constant::Constant
113
- #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
114
- #
115
- def put_constant( constant )
116
- index = @constant_pool.index constant
117
- if index == nil
118
- constant.java_class = self
119
- index = @constant_pool.push( constant ).length-1
120
- # doubleとlongの場合、次は欠番
121
- tag = constant.tag
122
- if tag == JavaClass::Constant::CONSTANT_Double \
123
- || tag == JavaClass::Constant::CONSTANT_Long
124
- @constant_pool.push( nil )
125
- end
126
- end
127
- return index
128
- end
129
-
130
- #
131
- #===UTF8Constantがプールになければ追加する。
132
- #*value::文字列値
133
- #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
134
- #
135
- def put_utf8_constant( value )
136
- put_constant( UTF8Constant.new( nil, Constant::CONSTANT_Utf8, value ))
137
- end
138
-
139
- #
140
- #===整数型のConstantがプールになければ追加する。
141
- #*value::整数値
142
- #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
143
- #
144
- def put_integer_constant( value )
145
- put_constant( IntegerConstant.new( nil, Constant::CONSTANT_Integer, value ))
146
- end
147
-
148
- #
149
- #===整数(Long)型のConstantがプールになければ追加する。
150
- #*value::整数値
151
- #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
152
- #
153
- def put_long_constant( value )
154
- put_constant( LongConstant.new( nil, Constant::CONSTANT_Long, value ))
155
- end
156
-
157
- #
158
- #===文字列型のConstantがプールになければ追加する。
159
- #*value::文字列値
160
- #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
161
- #
162
- def put_string_constant( value )
163
- put_constant( StringConstant.new( nil, Constant::CONSTANT_String,
164
- put_utf8_constant( value ) ))
165
- end
166
-
167
-
168
- #
169
- #===条件にマッチするメソッドを取得する。
170
- #*name::メソッド名
171
- #*return_type::戻り値型(省略した場合、戻り値を問わない)
172
- #*parameters::引数型の配列(省略した場合、パラメータタイプを問わない)
173
- #<b>戻り値</b>::条件にマッチするメソッド。存在しない場合nil
174
- #
175
- def find_method( name, return_type=nil, parameters=nil )
176
- @methods.find {|m|
177
- ( m.name.eql?( name ) ) \
178
- && ( return_type != nil ? m.return_type.eql?(return_type) : true ) \
179
- && ( parameters != nil ? m.parameters.eql?(parameters) : true )
180
- }
181
- end
182
-
183
- #
184
- #===条件にマッチするフィールドを取得する。
185
- #*name::メソッド名
186
- #*return_type::戻り値型(省略した場合、戻り値を問わない)
187
- #*parameters::引数型の配列(省略した場合、パラメータタイプを問わない)
188
- #<b>戻り値</b>::条件にマッチするメソッド。存在しない場合nil
189
- #
190
- def find_field( name )
191
- @fields.find {|f|
192
- f.name.eql?( name )
193
- }
194
- end
195
-
196
- def new_field
197
-
198
- end
199
-
200
- def new_method( name, descriptor )
201
-
202
- end
203
-
204
-
205
- # クラスの文字列表現を得る
206
- def to_s
207
- str = "// version #{version}\n"
208
- str << attributes["Signature"].to_s << "\n" if attributes.key? "Signature"
209
- str << "// !deprecated!\n" if deprecated?
210
- str << "#{attributes['SourceFile'].to_s}\n" if attributes.key? 'SourceFile'
211
- str << "#{attributes['EnclosingMethod'].to_s}\n" if attributes.key? 'EnclosingMethod'
212
- str << annotations.inject( "" ){|s, e| s << e.to_s << "\n" }
213
- str << "#{access_flag.to_s} #{name} "
214
- str << "\nextends #{super_class} " if super_class != nil
215
- if interfaces.size > 0
216
- interface_names = interfaces.map {|interface| interface }
217
- str << "\nimplements #{interface_names.join(', ')} "
218
- end
219
- str << "{\n\n"
220
- inner_classes.each {|inner_class|
221
- str << " " << inner_class.to_s << "\n"
222
- }
223
- str << "\n"
224
- @fields.each {|f|
225
- str << indent( f.to_s + ";", 4 ) << "\n"
226
- }
227
- str << "\n"
228
- @methods.each {|m|
229
- str << indent( m.to_s, 4 ) << "\n"
230
- }
231
- str << "\n}"
232
- end
233
-
234
- def indent( str, size )
235
- ind = " "*size
236
- ind += str.gsub( /\n/, "\n" << " "*size )
237
- end
238
-
239
- def to_bytes()
240
- bytes = to_byte( 0xCAFEBABE, 4)
241
- bytes += to_byte( @minor_version, 2)
242
- bytes += to_byte( @major_version, 2)
243
-
244
- bytes += to_byte( @constant_pool.length, 2)
245
- @constant_pool.each {|c|
246
- bytes += c.to_bytes() if c != nil
247
- }
248
- bytes += @access_flag.to_bytes()
249
- bytes += to_byte( @this_class_index, 2)
250
- bytes += to_byte( @super_class_index, 2)
251
- bytes += to_byte( @interface_indexs.length, 2)
252
- @interface_indexs.each {|i|
253
- bytes += to_byte( i, 2 )
254
- }
255
- bytes += to_byte( @fields.length, 2)
256
- @fields.each {|f|
257
- bytes += f.to_bytes()
258
- }
259
- bytes += to_byte( @methods.length, 2)
260
- @methods.each {|m|
261
- bytes += m.to_bytes()
262
- }
263
- bytes += to_byte( @attributes.size, 2)
264
- @attributes.keys.sort!.each {|k|
265
- bytes += @attributes[k].to_bytes()
266
- }
267
- return bytes
268
- end
269
-
270
- attr :major_version, true
271
- attr :minor_version, true
272
- attr :constant_pool, true
273
- attr :access_flag, true
274
- attr :this_class_index, true
275
- attr :super_class_index, true
276
- attr :interface_indexs, true
277
- attr :fields, true
278
- attr :methods, true
279
- attr :attributes, true
280
- end
281
-
1
+ require "javaclass/base"
2
+
3
+ module JavaClass
4
+
5
+ #
6
+ #===クラス
7
+ #
8
+ class Class
9
+ include JavaClass::Base
10
+ include JavaClass::Converters
11
+ include JavaClass::Item
12
+
13
+ #
14
+ #=== コンストラクタ
15
+ #
16
+ def initialize( )
17
+ @constant_pool = []
18
+ @interface_indexs = []
19
+ @fields = []
20
+ @methods = []
21
+ @attributes = {}
22
+ end
23
+
24
+ #
25
+ #===クラスバージョンを文字列で取得する
26
+ #<b>戻り値</b>::クラスバージョン
27
+ #
28
+ def version
29
+ @major_version.to_s << "." << @minor_version.to_s
30
+ end
31
+
32
+ #
33
+ #=== クラス名を取得する。
34
+ #<b>戻り値</b>::クラス名
35
+ #
36
+ def name
37
+ get_constant(@this_class_index).name
38
+ end
39
+
40
+ #
41
+ #=== 親クラス名を取得する。
42
+ #<b>戻り値</b>::親クラス名
43
+ #
44
+ def super_class
45
+ get_constant(@super_class_index).name
46
+ end
47
+
48
+ #
49
+ #=== 実装しているインターフェイス名を配列で取得する。
50
+ #<b>戻り値</b>::実装しているインターフェイス名の配列
51
+ #
52
+ def interfaces
53
+ @interface_indexs.map {|i| get_constant(i).name }
54
+ end
55
+
56
+ #
57
+ #=== ソースファイルを取得する。
58
+ #<b>戻り値</b>::ソースファイル
59
+ #
60
+ def source_file
61
+ attributes.key?('SourceFile') ?
62
+ attributes['SourceFile'].source_file : nil
63
+ end
64
+
65
+ #
66
+ #=== クラス名を取得する。
67
+ #<b>戻り値</b>::クラス名
68
+ #
69
+ def enclosing_method
70
+ attributes.key?('EnclosingMethod') ?
71
+ attributes['EnclosingMethod'] : nil
72
+ end
73
+
74
+ #
75
+ #=== クラスで利用しているインナークラスを配列で取得する。
76
+ #<b>戻り値</b>::インナークラスの配列
77
+ #
78
+ def inner_classes
79
+ attributes.key?('InnerClasses') ?
80
+ attributes['InnerClasses'].classes : []
81
+ end
82
+
83
+ #
84
+ #===indexのConstantを取得する。
85
+ #*index::constant_poolでのConstantのインデックス
86
+ #<b>戻り値</b>::Constant
87
+ #
88
+ def get_constant( index )
89
+ return nil if index == 0
90
+ return @constant_pool[index]
91
+ end
92
+ #
93
+ #===indexのConstantの値を取得する。
94
+ #*index::constant_poolでのConstantのインデックス
95
+ #<b>戻り値</b>::Constantの値
96
+ #
97
+ def get_constant_value( index )
98
+ return nil if index == 0
99
+ return @constant_pool[index].bytes
100
+ end
101
+ #
102
+ #===indexのConstantの値の文字列表現を取得する。
103
+ #*index::constant_poolでのConstantのインデックス
104
+ #<b>戻り値</b>::Constantの値の文字列表現
105
+ #
106
+ def get_constant_as_string( index )
107
+ return nil if index == 0
108
+ return @constant_pool[index].to_s
109
+ end
110
+ #
111
+ #===同じConstantがなければ追加する。
112
+ #*constant::Constant
113
+ #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
114
+ #
115
+ def put_constant( constant )
116
+ index = @constant_pool.index constant
117
+ if index == nil
118
+ constant.java_class = self
119
+ index = @constant_pool.push( constant ).length-1
120
+ # doubleとlongの場合、次は欠番
121
+ tag = constant.tag
122
+ if tag == JavaClass::Constant::CONSTANT_Double \
123
+ || tag == JavaClass::Constant::CONSTANT_Long
124
+ @constant_pool.push( nil )
125
+ end
126
+ end
127
+ return index
128
+ end
129
+
130
+ #
131
+ #===UTF8Constantがプールになければ追加する。
132
+ #*value::文字列値
133
+ #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
134
+ #
135
+ def put_utf8_constant( value )
136
+ put_constant( UTF8Constant.new( nil, Constant::CONSTANT_Utf8, value ))
137
+ end
138
+
139
+ #
140
+ #===整数型のConstantがプールになければ追加する。
141
+ #*value::整数値
142
+ #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
143
+ #
144
+ def put_integer_constant( value )
145
+ put_constant( IntegerConstant.new( nil, Constant::CONSTANT_Integer, value ))
146
+ end
147
+
148
+ #
149
+ #===整数(Long)型のConstantがプールになければ追加する。
150
+ #*value::整数値
151
+ #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
152
+ #
153
+ def put_long_constant( value )
154
+ put_constant( LongConstant.new( nil, Constant::CONSTANT_Long, value ))
155
+ end
156
+
157
+ #
158
+ #===文字列型のConstantがプールになければ追加する。
159
+ #*value::文字列値
160
+ #<b>戻り値</b>::追加したConstantのインデックス。すでに存在する場合、そのインデックス。
161
+ #
162
+ def put_string_constant( value )
163
+ put_constant( StringConstant.new( nil, Constant::CONSTANT_String,
164
+ put_utf8_constant( value ) ))
165
+ end
166
+
167
+
168
+ #
169
+ #===条件にマッチするメソッドを取得する。
170
+ #*name::メソッド名
171
+ #*return_type::戻り値型(省略した場合、戻り値を問わない)
172
+ #*parameters::引数型の配列(省略した場合、パラメータタイプを問わない)
173
+ #<b>戻り値</b>::条件にマッチするメソッド。存在しない場合nil
174
+ #
175
+ def find_method( name, return_type=nil, parameters=nil )
176
+ @methods.find {|m|
177
+ ( m.name.eql?( name ) ) \
178
+ && ( return_type != nil ? m.return_type.eql?(return_type) : true ) \
179
+ && ( parameters != nil ? m.parameters.eql?(parameters) : true )
180
+ }
181
+ end
182
+
183
+ #
184
+ #===条件にマッチするフィールドを取得する。
185
+ #*name::メソッド名
186
+ #*return_type::戻り値型(省略した場合、戻り値を問わない)
187
+ #*parameters::引数型の配列(省略した場合、パラメータタイプを問わない)
188
+ #<b>戻り値</b>::条件にマッチするメソッド。存在しない場合nil
189
+ #
190
+ def find_field( name )
191
+ @fields.find {|f|
192
+ f.name.eql?( name )
193
+ }
194
+ end
195
+
196
+ def new_field
197
+
198
+ end
199
+
200
+ def new_method( name, descriptor )
201
+
202
+ end
203
+
204
+
205
+ # クラスの文字列表現を得る
206
+ def to_s
207
+ str = "// version #{version}\n"
208
+ str << attributes["Signature"].to_s << "\n" if attributes.key? "Signature"
209
+ str << "// !deprecated!\n" if deprecated?
210
+ str << "#{attributes['SourceFile'].to_s}\n" if attributes.key? 'SourceFile'
211
+ str << "#{attributes['EnclosingMethod'].to_s}\n" if attributes.key? 'EnclosingMethod'
212
+ str << annotations.inject( "" ){|s, e| s << e.to_s << "\n" }
213
+ str << "#{access_flag.to_s} #{name} "
214
+ str << "\nextends #{super_class} " if super_class != nil
215
+ if interfaces.size > 0
216
+ interface_names = interfaces.map {|interface| interface }
217
+ str << "\nimplements #{interface_names.join(', ')} "
218
+ end
219
+ str << "{\n\n"
220
+ inner_classes.each {|inner_class|
221
+ str << " " << inner_class.to_s << "\n"
222
+ }
223
+ str << "\n"
224
+ @fields.each {|f|
225
+ str << indent( f.to_s + ";", 4 ) << "\n"
226
+ }
227
+ str << "\n"
228
+ @methods.each {|m|
229
+ str << indent( m.to_s, 4 ) << "\n"
230
+ }
231
+ str << "\n}"
232
+ end
233
+
234
+ def indent( str, size )
235
+ ind = " "*size
236
+ ind += str.gsub( /\n/, "\n" << " "*size )
237
+ end
238
+
239
+ def to_bytes()
240
+ bytes = to_byte( 0xCAFEBABE, 4)
241
+ bytes += to_byte( @minor_version, 2)
242
+ bytes += to_byte( @major_version, 2)
243
+
244
+ bytes += to_byte( @constant_pool.length, 2)
245
+ @constant_pool.each {|c|
246
+ bytes += c.to_bytes() if c != nil
247
+ }
248
+ bytes += @access_flag.to_bytes()
249
+ bytes += to_byte( @this_class_index, 2)
250
+ bytes += to_byte( @super_class_index, 2)
251
+ bytes += to_byte( @interface_indexs.length, 2)
252
+ @interface_indexs.each {|i|
253
+ bytes += to_byte( i, 2 )
254
+ }
255
+ bytes += to_byte( @fields.length, 2)
256
+ @fields.each {|f|
257
+ bytes += f.to_bytes()
258
+ }
259
+ bytes += to_byte( @methods.length, 2)
260
+ @methods.each {|m|
261
+ bytes += m.to_bytes()
262
+ }
263
+ bytes += to_byte( @attributes.size, 2)
264
+ @attributes.keys.sort!.each {|k|
265
+ bytes += @attributes[k].to_bytes()
266
+ }
267
+ return bytes
268
+ end
269
+
270
+ attr :major_version, true
271
+ attr :minor_version, true
272
+ attr :constant_pool, true
273
+ attr :access_flag, true
274
+ attr :this_class_index, true
275
+ attr :super_class_index, true
276
+ attr :interface_indexs, true
277
+ attr :fields, true
278
+ attr :methods, true
279
+ attr :attributes, true
280
+ end
281
+
282
282
  end