Class: JavaClass::Class

Inherits:
Object
  • Object
show all
Includes:
Base, Converters, Item
Defined in:
lib/javaclass/class.rb

Overview

クラス

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Item

#annotations, #deprecated?, #signature

Methods included from Converters

convert_code, convert_field_descriptor, convert_method_descriptor

Methods included from Base

#==, #===, #dump, #eql?, #hash, #to_byte

Constructor Details

#initializeClass

コンストラクタ



16
17
18
19
20
21
22
# File 'lib/javaclass/class.rb', line 16

def initialize(  )
  @constant_pool = []
  @interface_indexs = []
  @fields  = []
  @methods = []
  @attributes = {}
end

Instance Attribute Details

#access_flagObject

Returns the value of attribute access_flag.



275
276
277
# File 'lib/javaclass/class.rb', line 275

def access_flag
  @access_flag
end

#attributesObject

Returns the value of attribute attributes.



281
282
283
# File 'lib/javaclass/class.rb', line 281

def attributes
  @attributes
end

#constant_poolObject

Returns the value of attribute constant_pool.



274
275
276
# File 'lib/javaclass/class.rb', line 274

def constant_pool
  @constant_pool
end

#fieldsObject

Returns the value of attribute fields.



279
280
281
# File 'lib/javaclass/class.rb', line 279

def fields
  @fields
end

#interface_indexsObject

Returns the value of attribute interface_indexs.



278
279
280
# File 'lib/javaclass/class.rb', line 278

def interface_indexs
  @interface_indexs
end

#major_versionObject

Returns the value of attribute major_version.



272
273
274
# File 'lib/javaclass/class.rb', line 272

def major_version
  @major_version
end

#methodsObject

Returns the value of attribute methods.



280
281
282
# File 'lib/javaclass/class.rb', line 280

def methods
  @methods
end

#minor_versionObject

Returns the value of attribute minor_version.



273
274
275
# File 'lib/javaclass/class.rb', line 273

def minor_version
  @minor_version
end

#super_class_indexObject

Returns the value of attribute super_class_index.



277
278
279
# File 'lib/javaclass/class.rb', line 277

def super_class_index
  @super_class_index
end

#this_class_indexObject

Returns the value of attribute this_class_index.



276
277
278
# File 'lib/javaclass/class.rb', line 276

def this_class_index
  @this_class_index
end

Instance Method Details

#enclosing_methodObject

クラス名を取得する。

戻り値::クラス名



71
72
73
74
# File 'lib/javaclass/class.rb', line 71

def enclosing_method
  attributes.key?('EnclosingMethod') ?
    attributes['EnclosingMethod'] : nil 
end

#find_field(name) ⇒ Object

条件にマッチするフィールドを取得する。

*name::メソッド名 *return_type::戻り値型(省略した場合、戻り値を問わない) *parameters::引数型の配列(省略した場合、パラメータタイプを問わない) 戻り値::条件にマッチするメソッド。存在しない場合nil



192
193
194
195
196
# File 'lib/javaclass/class.rb', line 192

def find_field( name )
  @fields.find {|f|
    f.name.eql?( name ) 
  }
end

#find_method(name, return_type = nil, parameters = nil) ⇒ Object

条件にマッチするメソッドを取得する。

*name::メソッド名 *return_type::戻り値型(省略した場合、戻り値を問わない) *parameters::引数型の配列(省略した場合、パラメータタイプを問わない) 戻り値::条件にマッチするメソッド。存在しない場合nil



177
178
179
180
181
182
183
# File 'lib/javaclass/class.rb', line 177

def find_method( name, return_type=nil, parameters=nil )
  @methods.find {|m|
    ( m.name.eql?( name ) ) \
    && ( return_type != nil ? m.return_type.eql?(return_type) : true ) \
    && ( parameters  != nil ? m.parameters.eql?(parameters)   : true )
  }
end

#get_constant(index) ⇒ Object

indexのConstantを取得する。

*index::constant_poolでのConstantのインデックス 戻り値::Constant



90
91
92
93
# File 'lib/javaclass/class.rb', line 90

def get_constant( index )
  return nil if index == 0
  return @constant_pool[index]
end

#get_constant_as_string(index) ⇒ Object

indexのConstantの値の文字列表現を取得する。

*index::constant_poolでのConstantのインデックス 戻り値::Constantの値の文字列表現



108
109
110
111
# File 'lib/javaclass/class.rb', line 108

def get_constant_as_string( index )
  return nil if index == 0
  return @constant_pool[index].to_s
end

#get_constant_value(index) ⇒ Object

indexのConstantの値を取得する。

*index::constant_poolでのConstantのインデックス 戻り値::Constantの値



99
100
101
102
# File 'lib/javaclass/class.rb', line 99

def get_constant_value( index )
  return nil if index == 0
  return @constant_pool[index].bytes
end

#indent(str, size) ⇒ Object



236
237
238
239
# File 'lib/javaclass/class.rb', line 236

def indent( str, size )
  ind = " "*size
  ind += str.gsub( /\n/, "\n" << " "*size  )
end

#inner_classesObject

クラスで利用しているインナークラスを配列で取得する。

戻り値::インナークラスの配列



80
81
82
83
# File 'lib/javaclass/class.rb', line 80

def inner_classes
  attributes.key?('InnerClasses') ?
    attributes['InnerClasses'].classes : []
end

#interfacesObject

実装しているインターフェイス名を配列で取得する。

戻り値::実装しているインターフェイス名の配列



54
55
56
# File 'lib/javaclass/class.rb', line 54

def interfaces
  @interface_indexs.map {|i| get_constant(i).name }
end

#nameObject

クラス名を取得する。

戻り値::クラス名



36
37
38
39
# File 'lib/javaclass/class.rb', line 36

def name
  c = get_constant(@this_class_index)
  c ? c.name : nil 
end

#new_fieldObject



198
199
200
# File 'lib/javaclass/class.rb', line 198

def new_field
  
end

#new_method(name, descriptor) ⇒ Object



202
203
204
# File 'lib/javaclass/class.rb', line 202

def new_method( name, descriptor )
  
end

#put_constant(constant) ⇒ Object

同じConstantがなければ追加する。

*constant::Constant 戻り値::追加したConstantのインデックス。すでに存在する場合、そのインデックス。



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/javaclass/class.rb', line 117

def put_constant( constant )
  index = @constant_pool.index constant
  if index == nil
    constant.java_class = self
    index = @constant_pool.push( constant ).length-1
    # doubleとlongの場合、次は欠番
    tag = constant.tag
    if tag == JavaClass::Constant::CONSTANT_Double \
      || tag == JavaClass::Constant::CONSTANT_Long
      @constant_pool.push( nil )
    end
  end
  return index
end

#put_integer_constant(value) ⇒ Object

整数型のConstantがプールになければ追加する。

*value::整数値 戻り値::追加したConstantのインデックス。すでに存在する場合、そのインデックス。



146
147
148
# File 'lib/javaclass/class.rb', line 146

def put_integer_constant( value )
  put_constant( IntegerConstant.new( nil, Constant::CONSTANT_Integer, value ))
end

#put_long_constant(value) ⇒ Object

整数(Long)型のConstantがプールになければ追加する。

*value::整数値 戻り値::追加したConstantのインデックス。すでに存在する場合、そのインデックス。



155
156
157
# File 'lib/javaclass/class.rb', line 155

def put_long_constant( value )
  put_constant( LongConstant.new( nil, Constant::CONSTANT_Long, value ))
end

#put_string_constant(value) ⇒ Object

文字列型のConstantがプールになければ追加する。

*value::文字列値 戻り値::追加したConstantのインデックス。すでに存在する場合、そのインデックス。



164
165
166
167
# File 'lib/javaclass/class.rb', line 164

def put_string_constant( value )
  put_constant( StringConstant.new( nil, Constant::CONSTANT_String, 
    put_utf8_constant( value ) ))
end

#put_utf8_constant(value) ⇒ Object

UTF8Constantがプールになければ追加する。

*value::文字列値 戻り値::追加したConstantのインデックス。すでに存在する場合、そのインデックス。



137
138
139
# File 'lib/javaclass/class.rb', line 137

def put_utf8_constant( value )
  put_constant( UTF8Constant.new( nil, Constant::CONSTANT_Utf8, value ))
end

#source_fileObject

ソースファイルを取得する。

戻り値::ソースファイル



62
63
64
65
# File 'lib/javaclass/class.rb', line 62

def source_file
  attributes.key?('SourceFile') ?
    attributes['SourceFile'].source_file : nil 
end

#super_classObject

親クラス名を取得する。

戻り値::親クラス名



45
46
47
48
# File 'lib/javaclass/class.rb', line 45

def super_class
  c = get_constant(@super_class_index)
  c ? c.name : nil 
end

#to_bytesObject



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/javaclass/class.rb', line 241

def to_bytes()
  bytes = to_byte( 0xCAFEBABE, 4)
  bytes += to_byte( @minor_version, 2)
  bytes += to_byte( @major_version, 2)
  
  bytes += to_byte( @constant_pool.length, 2)
  @constant_pool.each {|c|
    bytes += c.to_bytes() if c != nil
  }
  bytes += @access_flag.to_bytes()
  bytes += to_byte( @this_class_index, 2)
  bytes += to_byte( @super_class_index, 2)
  bytes += to_byte( @interface_indexs.length, 2)
  @interface_indexs.each {|i|
    bytes += to_byte( i, 2 )
  }
  bytes += to_byte( @fields.length, 2)
  @fields.each {|f|
    bytes += f.to_bytes()
  }
  bytes += to_byte( @methods.length, 2)
  @methods.each {|m|
    bytes += m.to_bytes()
  }
  bytes += to_byte( @attributes.size, 2)
  @attributes.keys.sort!.each {|k| 
    bytes += @attributes[k].to_bytes()
  }
  return bytes
end

#to_sObject

クラスの文字列表現を得る



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/javaclass/class.rb', line 208

def to_s
  str =  "// version #{version}\n"
  str << attributes["Signature"].to_s << "\n" if attributes.key? "Signature"
  str << "// !deprecated!\n" if deprecated?
  str << "#{attributes['SourceFile'].to_s}\n" if attributes.key? 'SourceFile'
  str << "#{attributes['EnclosingMethod'].to_s}\n" if attributes.key? 'EnclosingMethod'
  str << annotations.inject( "" ){|s, e| s << e.to_s << "\n" }
  str << "#{access_flag.to_s} #{name} "
  str << "\nextends #{super_class} " if super_class != nil
  if interfaces.size > 0
    interface_names = interfaces.map {|interface| interface }
    str << "\nimplements #{interface_names.join(', ')} "
  end
  str << "{\n\n"
  inner_classes.each {|inner_class|
    str << "    " << inner_class.to_s << "\n"
  }
  str << "\n"
  @fields.each {|f|
    str << indent( f.to_s + ";", 4 ) << "\n"
  }
  str << "\n"
  @methods.each {|m|
    str << indent( m.to_s, 4 ) << "\n"
  }
  str << "\n}"
end

#versionObject

クラスバージョンを文字列で取得する

戻り値::クラスバージョン



28
29
30
# File 'lib/javaclass/class.rb', line 28

def version
  @major_version.to_s << "." << @minor_version.to_s
end