Module: Jtor::StdLib::Base::ClassMethods

Defined in:
lib/jtor-stdlib/base.rb

Instance Method Summary collapse

Instance Method Details

#_constructor_callsObject



21
22
23
# File 'lib/jtor-stdlib/base.rb', line 21

def _constructor_calls
  @_constructor_calls ||= {}
end

#_lookup_tableObject



13
14
15
# File 'lib/jtor-stdlib/base.rb', line 13

def _lookup_table
  @_lookup_table ||= {}
end

#_lookup_table_staticObject



17
18
19
# File 'lib/jtor-stdlib/base.rb', line 17

def _lookup_table_static
  @_lookup_table_static ||= {}
end

#add_java_constructor(param_types, constructor_call = nil, &block) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/jtor-stdlib/base.rb', line 45

def add_java_constructor(param_types, constructor_call = nil, &block)
  add_method_to_lookup(_lookup_table, :initialize, param_types, &block)
  previously_defined = _constructor_calls.any?
  _constructor_calls[param_types] = constructor_call
  return if previously_defined
  define_method(:initialize) do |*args|
    method, constructor_call = self.class.lookup(:initialize, *args)
    # I really tried to avoid using eval fellows, but JRuby is very fixed
    # on `super` being called here first than anything, and it wouldn't
    # accept a `proc` calling `initialize` on `sup`, so this will have
    # to do for now.
    eval(constructor_call) #if constructor_call
    instance_exec(*args, &method)
  end
end

#add_java_method(name, param_types, &block) ⇒ Object

Method overloading is not a ruby thing, so we implement a pseudo-lookup mechanism for method based on the type/count of their args



27
28
29
30
31
32
33
34
# File 'lib/jtor-stdlib/base.rb', line 27

def add_java_method(name, param_types, &block)
  previously_defined = add_method_to_lookup(_lookup_table, name,
      param_types, &block)
  return if previously_defined
  define_method(name) do |*args|
    instance_exec(*args, &self.class.lookup(name, *args))
  end
end

#add_method_to_lookup(lookup_table, name, param_types, &block) ⇒ Object



88
89
90
91
92
93
# File 'lib/jtor-stdlib/base.rb', line 88

def add_method_to_lookup(lookup_table, name, param_types, &block)
  previously_defined = lookup_table[name]
  lookup_table[name] ||= {}
  lookup_table[name][param_types] = block
  previously_defined
end

#add_static_java_method(name, param_types, &block) ⇒ Object



36
37
38
39
40
41
42
43
# File 'lib/jtor-stdlib/base.rb', line 36

def add_static_java_method(name, param_types, &block)
  previously_defined = add_method_to_lookup(_lookup_table_static, name,
      param_types, &block)
  return if previously_defined
  define_singleton_method(name) do |*args|
    instance_exec(*args, &lookup(name, *args))
  end
end

#lookup(name, *args) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/jtor-stdlib/base.rb', line 61

def lookup(name, *args)
  if _lookup_table[name]
    _lookup_table[name].each do |param_types, method|
      # NOTE: This is an oversimplification of the way Java determines
      # which method to invoke. I may work further into this later (see
      # http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12)
      next unless params_match(param_types, args)
      return (if (constructor_call = _constructor_calls[param_types])
        [method, constructor_call]
      else
        method
      end)
    end
  end
  method_missing(name, *args)
end

#params_match(types, values) ⇒ Object



78
79
80
81
82
83
84
85
86
# File 'lib/jtor-stdlib/base.rb', line 78

def params_match(types, values)
  # TODO: Handle var args (...)
  return false if types.size != values.size
  types.each_with_index do |type, index|
    value = values[index]
    return false unless value.is_a?(type) || value.to_java.is_a?(type)
  end
  true
end