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.



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

def access_flag
  @access_flag
end

#attributesObject

Returns the value of attribute attributes.



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

def attributes
  @attributes
end

#constant_poolObject

Returns the value of attribute constant_pool.



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

def constant_pool
  @constant_pool
end

#fieldsObject

Returns the value of attribute fields.



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

def fields
  @fields
end

#interface_indexsObject

Returns the value of attribute interface_indexs.



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

def interface_indexs
  @interface_indexs
end

#major_versionObject

Returns the value of attribute major_version.



270
271
272
# File 'lib/javaclass/class.rb', line 270

def major_version
  @major_version
end

#methodsObject

Returns the value of attribute methods.



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

def methods
  @methods
end

#minor_versionObject

Returns the value of attribute minor_version.



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

def minor_version
  @minor_version
end

#super_class_indexObject

Returns the value of attribute super_class_index.



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

def super_class_index
  @super_class_index
end

#this_class_indexObject

Returns the value of attribute this_class_index.



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

def this_class_index
  @this_class_index
end

Instance Method Details

#enclosing_methodObject

クラス名を取得する。

戻り値::クラス名



69
70
71
72
# File 'lib/javaclass/class.rb', line 69

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

#find_field(name) ⇒ Object

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

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



190
191
192
193
194
# File 'lib/javaclass/class.rb', line 190

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



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

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



88
89
90
91
# File 'lib/javaclass/class.rb', line 88

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の値の文字列表現



106
107
108
109
# File 'lib/javaclass/class.rb', line 106

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の値



97
98
99
100
# File 'lib/javaclass/class.rb', line 97

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

#indent(str, size) ⇒ Object



234
235
236
237
# File 'lib/javaclass/class.rb', line 234

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

#inner_classesObject

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

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



78
79
80
81
# File 'lib/javaclass/class.rb', line 78

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

#interfacesObject

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

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



52
53
54
# File 'lib/javaclass/class.rb', line 52

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

#nameObject

クラス名を取得する。

戻り値::クラス名



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

def name
  get_constant(@this_class_index).name
end

#new_fieldObject



196
197
198
# File 'lib/javaclass/class.rb', line 196

def new_field
  
end

#new_method(name, descriptor) ⇒ Object



200
201
202
# File 'lib/javaclass/class.rb', line 200

def new_method( name, descriptor )
  
end

#put_constant(constant) ⇒ Object

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

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



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

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のインデックス。すでに存在する場合、そのインデックス。



144
145
146
# File 'lib/javaclass/class.rb', line 144

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

#put_long_constant(value) ⇒ Object

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

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



153
154
155
# File 'lib/javaclass/class.rb', line 153

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

#put_string_constant(value) ⇒ Object

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

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



162
163
164
165
# File 'lib/javaclass/class.rb', line 162

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のインデックス。すでに存在する場合、そのインデックス。



135
136
137
# File 'lib/javaclass/class.rb', line 135

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

#source_fileObject

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

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



60
61
62
63
# File 'lib/javaclass/class.rb', line 60

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

#super_classObject

親クラス名を取得する。

戻り値::親クラス名



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

def super_class
  get_constant(@super_class_index).name
end

#to_bytesObject



239
240
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
# File 'lib/javaclass/class.rb', line 239

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

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



206
207
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
# File 'lib/javaclass/class.rb', line 206

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