Module: Rigor::Reflection
- Defined in:
- lib/rigor/reflection.rb
Overview
Read-side facade over Rigor’s three reflection sources:
-
**‘Rigor::Environment::ClassRegistry`** — Ruby `Class` / `Module` objects (Integer, Float, Set, Pathname, …) registered at boot. Static; never changes during a `rigor check` run.
-
**‘Rigor::Environment::RbsLoader`** — RBS-side declarations (instance / singleton methods, class hierarchy, constants). Loaded on demand from the project’s ‘sig/` directory + the bundled stdlib RBS.
-
**‘Rigor::Scope` discovered facts** — source-side discoveries produced by `Rigor::Inference::ScopeIndexer` (user-defined classes / modules, in-source constants, discovered method nodes, class ivar / cvar declarations).
This module is the **stable read shape** the plugin API is designed against (ADR-2, ‘docs/adr/2-extension-api.md`).
The facade is **read-only and additive**. Existing call sites that read directly from ‘Rigor::Scope` or `Rigor::Environment::RbsLoader` continue to work unchanged; they migrate to the facade at their own pace. The facade performs no caching beyond what the underlying sources already provide.
## Public surface (v0.0.7 first pass)
-
Reflection.class_known? — does any source recognise this class / module name?
-
Reflection.class_ordering — ‘:equal` / `:subclass` / `:superclass` / `:disjoint` / `:unknown` ordering between two class names.
-
Reflection.nominal_for_name — ‘Rigor::Type::Nominal` for the class name, joining registry + RBS lookups.
-
Reflection.singleton_for_name — ‘Rigor::Type::Singleton` for the class name’s class object.
-
Reflection.constant_type_for — type of a constant (joins in-source constants and RBS-side constants).
-
Reflection.instance_method_definition / Reflection.singleton_method_definition — RBS-side ‘RBS::Definition::Method` for the method, or `nil` when the method is not declared in RBS. Source-side discovered methods are exposed through Reflection.discovered_method? below until the unified `MethodDefinition` carrier ships.
-
Reflection.discovered_class? / Reflection.discovered_method? — has the ScopeIndexer pass recorded the class / method as user- defined in the analyzed sources?
The provenance side of the API (which source family contributed each fact) is explicitly out of scope for the v0.0.7 first pass; v0.1.0’s plugin API added it as a separate concern.
Class Method Summary collapse
- .class_known?(class_name, scope: Scope.empty) ⇒ Boolean
-
.class_ordering(lhs, rhs, scope: Scope.empty) ⇒ Symbol
One of ‘:equal`, `:subclass`, `:superclass`, `:disjoint`, `:unknown`.
-
.class_type_param_names(class_name, scope: nil, environment: nil) ⇒ Object
Returns the RBS-declared type parameter names for the class (e.g. ‘[:A]` for `Array`), or `[]` when the class is non-generic / not in RBS.
-
.constant_type_for(constant_name, scope: Scope.empty) ⇒ Object
Returns the type of the named constant.
-
.discovered_class?(class_name, scope: Scope.empty) ⇒ Boolean
True when the analyzed source contains a class / module declaration for the given name.
-
.discovered_method?(class_name, method_name, kind: :instance, scope: Scope.empty) ⇒ Boolean
True when the ScopeIndexer recorded a ‘def` for the given method on the given class with the matching kind.
-
.instance_definition(class_name, scope: nil, environment: nil) ⇒ Object
Returns the full RBS instance-side class definition (‘RBS::Definition`), used by callers that walk the method table or member list.
-
.instance_method_definition(class_name, method_name, scope: nil, environment: nil) ⇒ Object
Returns the RBS ‘RBS::Definition::Method` for the instance method, or nil when the class or method is not in RBS.
-
.nominal_for_name(class_name, scope: Scope.empty) ⇒ Object
Returns the ‘Rigor::Type::Nominal` for the class name, or nil when no source knows the class.
-
.rbs_class_known?(class_name, scope: nil, environment: nil) ⇒ Boolean
RBS-only variant of Reflection.class_known?.
-
.singleton_definition(class_name, scope: nil, environment: nil) ⇒ Object
Returns the full RBS singleton-side class definition.
-
.singleton_for_name(class_name, scope: Scope.empty) ⇒ Object
Returns the ‘Rigor::Type::Singleton` for the class name’s class object, or nil when no source knows the class.
-
.singleton_method_definition(class_name, method_name, scope: nil, environment: nil) ⇒ Object
Returns the RBS ‘RBS::Definition::Method` for the singleton (class-side) method, or nil.
Class Method Details
.class_known?(class_name, scope: Scope.empty) ⇒ Boolean
60 61 62 63 64 |
# File 'lib/rigor/reflection.rb', line 60 def class_known?(class_name, scope: Scope.empty) return true if scope.discovered_classes.key?(class_name.to_s) scope.environment.class_known?(class_name) end |
.class_ordering(lhs, rhs, scope: Scope.empty) ⇒ Symbol
Returns one of ‘:equal`, `:subclass`, `:superclass`, `:disjoint`, `:unknown`.
88 89 90 |
# File 'lib/rigor/reflection.rb', line 88 def class_ordering(lhs, rhs, scope: Scope.empty) scope.environment.class_ordering(lhs, rhs) end |
.class_type_param_names(class_name, scope: nil, environment: nil) ⇒ Object
Returns the RBS-declared type parameter names for the class (e.g. ‘[:A]` for `Array`), or `[]` when the class is non-generic / not in RBS. Used by the dispatcher when binding generic method types to a concrete receiver.
165 166 167 168 169 170 |
# File 'lib/rigor/reflection.rb', line 165 def class_type_param_names(class_name, scope: nil, environment: nil) loader = rbs_loader_for(scope, environment) return [] if loader.nil? loader.class_type_param_names(class_name.to_s) end |
.constant_type_for(constant_name, scope: Scope.empty) ⇒ Object
Returns the type of the named constant. Joins in-source constants (recorded by ‘ScopeIndexer`) and RBS-side constants. In-source wins on collision because the user’s source is the authoritative declaration.
108 109 110 111 112 113 114 |
# File 'lib/rigor/reflection.rb', line 108 def constant_type_for(constant_name, scope: Scope.empty) key = constant_name.to_s in_source = scope.in_source_constants[key] return in_source if in_source scope.environment.constant_for_name(constant_name) end |
.discovered_class?(class_name, scope: Scope.empty) ⇒ Boolean
Returns true when the analyzed source contains a class / module declaration for the given name. Does NOT consult the RBS loader (use class_known? for the union).
188 189 190 |
# File 'lib/rigor/reflection.rb', line 188 def discovered_class?(class_name, scope: Scope.empty) scope.discovered_classes.key?(class_name.to_s) end |
.discovered_method?(class_name, method_name, kind: :instance, scope: Scope.empty) ⇒ Boolean
Returns true when the ScopeIndexer recorded a ‘def` for the given method on the given class with the matching kind.
196 197 198 |
# File 'lib/rigor/reflection.rb', line 196 def discovered_method?(class_name, method_name, kind: :instance, scope: Scope.empty) scope.discovered_method?(class_name, method_name, kind) end |
.instance_definition(class_name, scope: nil, environment: nil) ⇒ Object
Returns the full RBS instance-side class definition (‘RBS::Definition`), used by callers that walk the method table or member list. Returns nil when the class is not in RBS or when the loader cannot build a definition (e.g. constant aliases, malformed signatures).
142 143 144 145 146 147 148 149 |
# File 'lib/rigor/reflection.rb', line 142 def instance_definition(class_name, scope: nil, environment: nil) loader = rbs_loader_for(scope, environment) return nil if loader.nil? loader.instance_definition(class_name.to_s) rescue ::RBS::BaseError nil end |
.instance_method_definition(class_name, method_name, scope: nil, environment: nil) ⇒ Object
Returns the RBS ‘RBS::Definition::Method` for the instance method, or nil when the class or method is not in RBS. The source-side discovered-method facts are reachable through discovered_method?; a future slice will unify the two under a `MethodDefinition` carrier.
121 122 123 124 125 126 |
# File 'lib/rigor/reflection.rb', line 121 def instance_method_definition(class_name, method_name, scope: nil, environment: nil) loader = rbs_loader_for(scope, environment) return nil if loader.nil? loader.instance_method(class_name: class_name.to_s, method_name: method_name.to_sym) end |
.nominal_for_name(class_name, scope: Scope.empty) ⇒ Object
Returns the ‘Rigor::Type::Nominal` for the class name, or nil when no source knows the class.
94 95 96 |
# File 'lib/rigor/reflection.rb', line 94 def nominal_for_name(class_name, scope: Scope.empty) scope.environment.nominal_for_name(class_name) end |
.rbs_class_known?(class_name, scope: nil, environment: nil) ⇒ Boolean
RBS-only variant of class_known?. Use when the caller needs to know specifically whether RBS has a definition for the class, independent of any source-discovered ‘class Foo; end` declarations. The diagnostic-rule code paths that walk RBS method tables to decide whether to flag a missing method use this variant; otherwise the source-discovered class would suppress the rule even when no RBS sig actually proves the method exists.
The kwarg accepts either ‘scope:` or `environment:`. The latter is for call sites that don’t carry a ‘Scope` (most are bottom-half dispatcher code paths called with only an environment).
79 80 81 82 83 84 |
# File 'lib/rigor/reflection.rb', line 79 def rbs_class_known?(class_name, scope: nil, environment: nil) loader = rbs_loader_for(scope, environment) return false if loader.nil? loader.class_known?(class_name) end |
.singleton_definition(class_name, scope: nil, environment: nil) ⇒ Object
Returns the full RBS singleton-side class definition.
152 153 154 155 156 157 158 159 |
# File 'lib/rigor/reflection.rb', line 152 def singleton_definition(class_name, scope: nil, environment: nil) loader = rbs_loader_for(scope, environment) return nil if loader.nil? loader.singleton_definition(class_name.to_s) rescue ::RBS::BaseError nil end |
.singleton_for_name(class_name, scope: Scope.empty) ⇒ Object
Returns the ‘Rigor::Type::Singleton` for the class name’s class object, or nil when no source knows the class.
100 101 102 |
# File 'lib/rigor/reflection.rb', line 100 def singleton_for_name(class_name, scope: Scope.empty) scope.environment.singleton_for_name(class_name) end |
.singleton_method_definition(class_name, method_name, scope: nil, environment: nil) ⇒ Object
Returns the RBS ‘RBS::Definition::Method` for the singleton (class-side) method, or nil.
130 131 132 133 134 135 |
# File 'lib/rigor/reflection.rb', line 130 def singleton_method_definition(class_name, method_name, scope: nil, environment: nil) loader = rbs_loader_for(scope, environment) return nil if loader.nil? loader.singleton_method(class_name: class_name.to_s, method_name: method_name.to_sym) end |