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