Module: Tapioca::Runtime::Reflection

Constant Summary collapse

CLASS_METHOD =
T.let(Kernel.instance_method(:class), UnboundMethod)
CONSTANTS_METHOD =
T.let(Module.instance_method(:constants), UnboundMethod)
NAME_METHOD =
T.let(Module.instance_method(:name), UnboundMethod)
SINGLETON_CLASS_METHOD =
T.let(Object.instance_method(:singleton_class), UnboundMethod)
ANCESTORS_METHOD =
T.let(Module.instance_method(:ancestors), UnboundMethod)
SUPERCLASS_METHOD =
T.let(Class.instance_method(:superclass), UnboundMethod)
OBJECT_ID_METHOD =
T.let(BasicObject.instance_method(:__id__), UnboundMethod)
EQUAL_METHOD =
T.let(BasicObject.instance_method(:equal?), UnboundMethod)
PUBLIC_INSTANCE_METHODS_METHOD =
T.let(Module.instance_method(:public_instance_methods), UnboundMethod)
PROTECTED_INSTANCE_METHODS_METHOD =
T.let(Module.instance_method(:protected_instance_methods), UnboundMethod)
PRIVATE_INSTANCE_METHODS_METHOD =
T.let(Module.instance_method(:private_instance_methods), UnboundMethod)
METHOD_METHOD =
T.let(Kernel.instance_method(:method), UnboundMethod)
UNDEFINED_CONSTANT =
T.let(Module.new.freeze, Module)
REQUIRED_FROM_LABELS =
T.let(["<top (required)>", "<main>"].freeze, T::Array[String])

Instance Method Summary collapse

Methods included from AttachedClassOf

#attached_class_of

Instance Method Details

#abstract_type_of(constant) ⇒ Object



207
208
209
210
# File 'lib/tapioca/runtime/reflection.rb', line 207

def abstract_type_of(constant)
  T::Private::Abstract::Data.get(constant, :abstract_type) ||
    T::Private::Abstract::Data.get(singleton_class_of(constant), :abstract_type)
end

#ancestors_of(constant) ⇒ Object



77
78
79
# File 'lib/tapioca/runtime/reflection.rb', line 77

def ancestors_of(constant)
  ANCESTORS_METHOD.bind_call(constant)
end

#are_equal?(object, other) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/tapioca/runtime/reflection.rb', line 92

def are_equal?(object, other)
  EQUAL_METHOD.bind_call(object, other)
end

#class_of(object) ⇒ Object



56
57
58
# File 'lib/tapioca/runtime/reflection.rb', line 56

def class_of(object)
  CLASS_METHOD.bind_call(object)
end

#constant_defined?(constant) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/tapioca/runtime/reflection.rb', line 38

def constant_defined?(constant)
  !UNDEFINED_CONSTANT.eql?(constant)
end

#constantize(symbol, inherit: false, namespace: Object) ⇒ Object



49
50
51
52
53
# File 'lib/tapioca/runtime/reflection.rb', line 49

def constantize(symbol, inherit: false, namespace: Object)
  namespace.const_get(symbol, inherit)
rescue NameError, LoadError, RuntimeError, ArgumentError, TypeError
  UNDEFINED_CONSTANT
end

#constants_of(constant) ⇒ Object



61
62
63
# File 'lib/tapioca/runtime/reflection.rb', line 61

def constants_of(constant)
  CONSTANTS_METHOD.bind_call(constant, false)
end

#descendants_of(klass) ⇒ Object



172
173
174
175
176
177
178
# File 'lib/tapioca/runtime/reflection.rb', line 172

def descendants_of(klass)
  result = ObjectSpace.each_object(klass.singleton_class).reject do |k|
    k.singleton_class? || k == klass
  end

  T.unsafe(result)
end

#file_candidates_for(constant) ⇒ Object



200
201
202
203
204
# File 'lib/tapioca/runtime/reflection.rb', line 200

def file_candidates_for(constant)
  relevant_methods_for(constant).filter_map do |method|
    method.source_location&.first
  end.to_set
end

#final_module?(constant) ⇒ Boolean

Returns:

  • (Boolean)


213
214
215
# File 'lib/tapioca/runtime/reflection.rb', line 213

def final_module?(constant)
  T::Private::Final.final_module?(constant)
end

#inherited_ancestors_of(constant) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/tapioca/runtime/reflection.rb', line 112

def inherited_ancestors_of(constant)
  if Class === constant
    ancestors_of(superclass_of(constant) || Object)
  else
    Module.new.ancestors
  end
end

#method_of(constant, method) ⇒ Object



150
151
152
# File 'lib/tapioca/runtime/reflection.rb', line 150

def method_of(constant, method)
  METHOD_METHOD.bind_call(constant, method)
end

#name_of(constant) ⇒ Object



66
67
68
69
# File 'lib/tapioca/runtime/reflection.rb', line 66

def name_of(constant)
  name = NAME_METHOD.bind_call(constant)
  name&.start_with?("#<") ? nil : name
end

#name_of_type(type) ⇒ Object



145
146
147
# File 'lib/tapioca/runtime/reflection.rb', line 145

def name_of_type(type)
  type.to_s
end

#object_id_of(object) ⇒ Object



87
88
89
# File 'lib/tapioca/runtime/reflection.rb', line 87

def object_id_of(object)
  OBJECT_ID_METHOD.bind_call(object)
end

#private_instance_methods_of(constant) ⇒ Object



107
108
109
# File 'lib/tapioca/runtime/reflection.rb', line 107

def private_instance_methods_of(constant)
  PRIVATE_INSTANCE_METHODS_METHOD.bind_call(constant)
end

#protected_instance_methods_of(constant) ⇒ Object



102
103
104
# File 'lib/tapioca/runtime/reflection.rb', line 102

def protected_instance_methods_of(constant)
  PROTECTED_INSTANCE_METHODS_METHOD.bind_call(constant)
end

#public_instance_methods_of(constant) ⇒ Object



97
98
99
# File 'lib/tapioca/runtime/reflection.rb', line 97

def public_instance_methods_of(constant)
  PUBLIC_INSTANCE_METHODS_METHOD.bind_call(constant)
end

#qualified_name_of(constant) ⇒ Object



121
122
123
124
125
126
127
128
129
130
# File 'lib/tapioca/runtime/reflection.rb', line 121

def qualified_name_of(constant)
  name = name_of(constant)
  return if name.nil?

  if name.start_with?("::")
    name
  else
    "::#{name}"
  end
end

#resolve_loc(locations) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/tapioca/runtime/reflection.rb', line 185

def resolve_loc(locations)
  return "" unless locations

  resolved_loc = locations.find do |loc|
    label = loc.label
    next unless label

    REQUIRED_FROM_LABELS.include?(label) || label.start_with?("block in <class:")
  end
  return "" unless resolved_loc

  resolved_loc.absolute_path || ""
end

#sealed_module?(constant) ⇒ Boolean

Returns:

  • (Boolean)


218
219
220
# File 'lib/tapioca/runtime/reflection.rb', line 218

def sealed_module?(constant)
  T::Private::Sealed.sealed_module?(constant)
end

#signature_of(method) ⇒ Object



138
139
140
141
142
# File 'lib/tapioca/runtime/reflection.rb', line 138

def signature_of(method)
  signature_of!(method)
rescue LoadError, StandardError
  nil
end

#signature_of!(method) ⇒ Object



133
134
135
# File 'lib/tapioca/runtime/reflection.rb', line 133

def signature_of!(method)
  T::Utils.signature_for_method(method)
end

#singleton_class_of(constant) ⇒ Object



72
73
74
# File 'lib/tapioca/runtime/reflection.rb', line 72

def singleton_class_of(constant)
  SINGLETON_CLASS_METHOD.bind_call(constant)
end

#superclass_of(constant) ⇒ Object



82
83
84
# File 'lib/tapioca/runtime/reflection.rb', line 82

def superclass_of(constant)
  SUPERCLASS_METHOD.bind_call(constant)
end