Class: Ruby::Rego::Evaluator::ReferenceResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby/rego/evaluator/reference_resolver.rb

Overview

Resolves AST references against input/data and rule outputs. rubocop:disable Metrics/ClassLength

Defined Under Namespace

Classes: StaticKeyBuilder

Constant Summary collapse

UNCACHEABLE =
Object.new.freeze

Instance Method Summary collapse

Constructor Details

#initialize(environment:, package_path:, rule_value_provider:, imports: [], memoization: nil) ⇒ ReferenceResolver

Returns a new instance of ReferenceResolver.

Parameters:



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ruby/rego/evaluator/reference_resolver.rb', line 54

def initialize(environment:, package_path:, rule_value_provider:, imports: [], memoization: nil)
  @environment = environment
  @package_path = package_path
  @rule_value_provider = rule_value_provider
  @memoization = memoization
  @key_resolver = ReferenceKeyResolver.new(
    environment: environment,
    variable_resolver: method(:resolve_variable_key)
  )
  @import_map = build_import_map(imports)
end

Instance Method Details

#function_reference_name(reference) ⇒ String?

Resolve a function call reference to a rule name when possible.

Parameters:

Returns:

  • (String, nil)


108
109
110
111
112
113
114
115
# File 'lib/ruby/rego/evaluator/reference_resolver.rb', line 108

def function_reference_name(reference)
  return nil unless reference.is_a?(AST::Reference)

  target = function_reference_target(reference)
  return nil unless target

  resolve_function_reference_name(target)
end

#function_reference_target(reference) ⇒ Object

:reek:FeatureEnvy



118
119
120
121
122
123
124
125
126
127
# File 'lib/ruby/rego/evaluator/reference_resolver.rb', line 118

def function_reference_target(reference)
  import_reference = import_reference_for(reference)
  return reference unless import_reference

  AST::Reference.new(
    base: import_reference.base,
    path: import_reference.path + reference.path,
    location: reference.location
  )
end

#resolve(ref) ⇒ Value

Parameters:

  • ref (Object)

Returns:



68
69
70
71
72
73
74
75
76
77
# File 'lib/ruby/rego/evaluator/reference_resolver.rb', line 68

def resolve(ref)
  return environment.resolve_reference(ref) unless ref.is_a?(AST::Reference)

  cached = cached_reference_value(ref)
  return cached if cached

  value = resolve_reference_value(ref)
  cache_reference_value(ref, value) if cacheable_reference?(ref)
  value
end

#resolve_function_reference_name(reference) ⇒ Object

:reek:FeatureEnvy



130
131
132
133
134
135
136
137
# File 'lib/ruby/rego/evaluator/reference_resolver.rb', line 130

def resolve_function_reference_name(reference)
  base = reference.base
  return nil unless base.is_a?(AST::Variable) && base.name == "data"

  rule_reference(reference.path)&.then do |(rule_name, remaining_path)|
    remaining_path.empty? ? rule_name : nil
  end
end

#resolve_import_variable(name) ⇒ Value?

Resolve an import alias used as a bare variable.

Parameters:

  • name (String)

Returns:



83
84
85
86
87
88
89
90
# File 'lib/ruby/rego/evaluator/reference_resolver.rb', line 83

def resolve_import_variable(name)
  reference = import_map[name.to_s]
  return nil unless reference
  return nil if environment.local_bound?(name)
  return nil unless environment.lookup(name).is_a?(UndefinedValue)

  resolve(reference)
end

#resolve_rule_variable(name) ⇒ Value?

Resolve a rule name used as a bare variable.

Parameters:

  • name (String)

Returns:



96
97
98
99
100
101
102
# File 'lib/ruby/rego/evaluator/reference_resolver.rb', line 96

def resolve_rule_variable(name)
  return nil if environment.local_bound?(name)
  return nil unless environment.lookup(name).is_a?(UndefinedValue)
  return nil unless rule_value_provider.rule_defined?(name)

  rule_value_provider.value_for(name)
end