Class: Duby::JVM::Types::TypeFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/duby/jvm/types/factory.rb

Defined Under Namespace

Classes: ParanoidHash

Constant Summary collapse

BASIC_TYPES =
{
  "boolean" => Boolean,
  "byte" => Byte,
  "char" => Char,
  "short" => Short,
  "int" => Int,
  "long" => Long,
  "float" => Float,
  "double" => Double,
  "fixnum" => Int,
  "string" => String,
  "java.lang.String" => String,
  "String" => String,
  "java.lang.Object" => Object,
  "Object" => Object,
  "java.lang.Iterable" => Iterable,
  "Iterable" => Iterable,
  "void" => Void,
  "notype" => Void,
  "null" => Null,
  "dynamic" => DynamicType.new
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename = '') ⇒ TypeFactory

Returns a new instance of TypeFactory.



37
38
39
40
41
42
43
44
45
46
# File 'lib/duby/jvm/types/factory.rb', line 37

def initialize(filename='')
  @known_types = ParanoidHash.new
  @known_types.update(BASIC_TYPES)
  @declarations = []
  @package = File.dirname(filename).tr('/', '.')
  @package.sub! /^\.+/, ''
  @package = nil if @package.empty?
  @search_packages = [@package, 'java.lang']
  @mirrors = {}
end

Instance Attribute Details

#known_typesObject (readonly)

Returns the value of attribute known_types.



28
29
30
# File 'lib/duby/jvm/types/factory.rb', line 28

def known_types
  @known_types
end

#packageObject

Returns the value of attribute package.



27
28
29
# File 'lib/duby/jvm/types/factory.rb', line 27

def package
  @package
end

Instance Method Details

#alias(from, to) ⇒ Object



134
135
136
137
138
139
140
# File 'lib/duby/jvm/types/factory.rb', line 134

def alias(from, to)
  if from == '*'
    @search_packages << to.sub(".*", "")
  else
    @known_types[from] = type(to)
  end
end

#basic_type(name) ⇒ Object

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/duby/jvm/types/factory.rb', line 68

def basic_type(name)
  if name.kind_of?(Type) || name.kind_of?(NarrowingType)
    return name.basic_type
  end
  orig = name
  if name.kind_of? Java::JavaClass
    if name.array?
      return type(name.component_type, true)
    else
      name = name.name
    end
  elsif name.respond_to? :java_class
    name = name.java_class.name
  end
  name = name.to_s unless name.kind_of?(::String)
  return @known_types[name].basic_type if @known_types[name]
  raise ArgumentError, "Bad Type #{orig}" if name =~ /Java::/
  raise ArgumentError, "Bad Type #{orig.inspect}" if name == '' || name.nil?
  if name.include? '.'
    alt_names = []
  else
    alt_names = @search_packages.map {|package| "#{package}.#{name}"}
  end
  full_name = name
  begin
    @known_types[name] = Type.new(get_mirror(full_name))
  rescue NameError
    unless alt_names.empty?
      full_name = alt_names.shift
      retry
    end
    raise $!
  end
end

#declare_type(node) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/duby/jvm/types/factory.rb', line 107

def declare_type(node)
  if node.kind_of? ::String
    name = node
    node = nil
  else
    name = node.name
  end

  if @known_types.include? name
    existing = @known_types[name]
    existing.node ||= node
    existing
  else
    full_name = name
    if !name.include?('.') && package
      full_name = "#{package}.#{name}"
    end
    if Duby::AST::InterfaceDeclaration === node
      klass = InterfaceDefinition
    else
      klass = TypeDefinition
    end
    @known_types[full_name] = klass.new(full_name, node)
    @known_types[name] = @known_types[full_name]
  end
end

#define_types(builder) ⇒ Object



48
49
50
51
52
# File 'lib/duby/jvm/types/factory.rb', line 48

def define_types(builder)
  @declarations.each do |declaration|
    declaration.define(builder)
  end
end

#fixnum(parent, line_number, literal) ⇒ Object



146
147
148
# File 'lib/duby/jvm/types/factory.rb', line 146

def fixnum(parent, line_number, literal)
  FixnumLiteralNode.new(parent, line_number, literal)
end

#float(parent, line_number, literal) ⇒ Object



150
151
152
# File 'lib/duby/jvm/types/factory.rb', line 150

def float(parent, line_number, literal)
  FloatLiteralNode.new(parent, line_number, literal)
end

#get_mirror(name) ⇒ Object



154
155
156
157
158
159
160
161
# File 'lib/duby/jvm/types/factory.rb', line 154

def get_mirror(name)
  @mirrors[name] ||= begin
    classname = name.tr('.', '/') + ".class"
    stream = JRuby.runtime.jruby_class_loader.getResourceAsStream(classname)
    raise NameError, "Class '#{name}' not found." unless stream
    BiteScript::ASM::ClassMirror.load(stream)
  end
end

#known_type(name) ⇒ Object



103
104
105
# File 'lib/duby/jvm/types/factory.rb', line 103

def known_type(name)
  basic_type(name) rescue nil
end

#no_typeObject



142
143
144
# File 'lib/duby/jvm/types/factory.rb', line 142

def no_type
  Void
end

#type(name, array = false, meta = false) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/duby/jvm/types/factory.rb', line 54

def type(name, array=false, meta=false)
  if name.kind_of?(BiteScript::ASM::Type)
    if name.getDescriptor[0] == ?[
      return type(name.getElementType, true, meta)
    else
      name = name.getClassName
    end
  end
  type = basic_type(name)
  type = type.meta if meta
  type = type.array_type if array
  return type
end