Class: Rigor::TypeNode::ResolverChain

Inherits:
Object
  • Object
show all
Defined in:
lib/rigor/type_node/resolver_chain.rb

Overview

Walks an ordered list of Plugin::TypeNodeResolver instances, returning the first non-nil ‘resolve(node, scope)` answer. ADR-13 § “`Plugin::TypeNodeResolver` shape” — first non-nil wins; registration order is the user’s lever for shadowing per WD3 / WD5.

The chain is itself a ‘TypeNodeResolver`-shaped object (`#resolve(node, scope)`) so it slots into a NameScope as the `resolver:` field without further indirection: a plugin resolver that wants to recursively resolve a nested argument calls `scope.resolver.resolve(arg, scope)` and reaches every resolver in the chain plus the built-in registry through the same entry point.

Constructed once per ‘Analysis::Runner.run` from `Plugin::Registry#type_node_resolvers`. The chain is immutable and re-entrant; the parser may consult it many times for the same node.

Constant Summary collapse

EMPTY =

Shared empty chain — a ‘NameScope` constructed without any plugin-supplied resolvers can use this to satisfy the `responds_to?(:resolve)` contract without a per-call allocation.

new([]).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resolvers) ⇒ ResolverChain

Returns a new instance of ResolverChain.



24
25
26
27
28
29
30
31
32
33
# File 'lib/rigor/type_node/resolver_chain.rb', line 24

def initialize(resolvers)
  unless resolvers.is_a?(Array) && resolvers.all? { |r| r.respond_to?(:resolve) }
    raise ArgumentError,
          "TypeNode::ResolverChain expects an Array of resolvers " \
          "responding to #resolve(node, scope), got #{resolvers.inspect}"
  end

  @resolvers = resolvers.dup.freeze
  freeze
end

Instance Attribute Details

#resolversArray<Rigor::Plugin::TypeNodeResolver> (readonly)

Returns ordered resolver instances, in plugin-registration order.

Returns:



37
38
39
# File 'lib/rigor/type_node/resolver_chain.rb', line 37

def resolvers
  @resolvers
end

Instance Method Details

#resolve(node, scope) ⇒ Object

First non-nil ‘resolve(node, scope)` answer from the chain; `nil` when every resolver declined.



41
42
43
44
45
46
47
# File 'lib/rigor/type_node/resolver_chain.rb', line 41

def resolve(node, scope)
  @resolvers.each do |resolver|
    result = resolver.resolve(node, scope)
    return result unless result.nil?
  end
  nil
end