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

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

Instance Method Summary collapse

Instance Method Details

#_constructor_callsObject



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

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

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



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/jtor-stdlib/base.rb', line 32

def add_java_constructor(param_types, constructor_call = nil, &block)
  add_method_to_lookup(: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



23
24
25
26
27
28
29
30
# File 'lib/jtor-stdlib/base.rb', line 23

def add_java_method(name, param_types, &block)
  previously_defined = _lookup_table[name]
  add_method_to_lookup(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(name, param_types, &block) ⇒ Object



75
76
77
78
# File 'lib/jtor-stdlib/base.rb', line 75

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

#lookup(name, *args) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/jtor-stdlib/base.rb', line 48

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



65
66
67
68
69
70
71
72
73
# File 'lib/jtor-stdlib/base.rb', line 65

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