class Dry::Types::PredicateInferrer::Compiler

Compiler reduces type AST into a list of predicates

@api private

Attributes

registry[R]

@return [PredicateRegistry] @api private

Public Class Methods

new(registry) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 53
def initialize(registry)
  @registry = registry
end

Public Instance Methods

infer_predicate(type) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 58
        def infer_predicate(type)
          pred = TYPE_TO_PREDICATE.fetch(type) do
            if type.name.nil? || self.class.infer_predicate_by_class_name.equal?(false)
              nil
            else
              candidate = :"#{type.name.split("::").last.downcase}?"

              if registry.key?(candidate)
                if self.class.infer_predicate_by_class_name
                  candidate
                else
                  raise ::KeyError, <<~MESSAGE
                    Automatic predicate inferring from class names is deprecated
                    and will be removed in dry-types 2.0.
                    Use `Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name true`
                    to restore the previous behavior
                    or `Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name false`
                    to explicitly opt-out (i.e. no exception + no inferring).
                    Note: for dry-schema and dry-validation use Dry::Schema::PredicateInferrer::Compiler.
                  MESSAGE
                end
              else
                nil
              end
            end
          end

          if pred.nil?
            EMPTY_ARRAY
          else
            [pred]
          end
        end
visit(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 93
def visit(node)
  meth, rest = node
  public_send(:"visit_#{meth}", rest)
end
visit_and(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 169
def visit_and(node)
  left, right = node
  visit(left) + visit(right)
end
visit_any(_) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 164
def visit_any(_)
  EMPTY_ARRAY
end
visit_array(_) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 117
def visit_array(_)
  ARRAY
end
visit_constrained(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 152
def visit_constrained(node)
  other, rules = node
  predicates = visit(rules)

  if predicates.empty?
    visit(other)
  else
    [*visit(other), *merge_predicates(predicates)]
  end
end
visit_constructor(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 127
def visit_constructor(node)
  other, * = node
  visit(other)
end
visit_enum(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 133
def visit_enum(node)
  other, * = node
  visit(other)
end
visit_hash(_) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 111
def visit_hash(_)
  HASH
end
Also aliased as: visit_schema
visit_lax(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 122
def visit_lax(node)
  visit(node)
end
visit_nominal(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 99
def visit_nominal(node)
  type = node[0]
  predicate = infer_predicate(type)

  if !predicate.empty? && registry.key?(predicate[0])
    predicate
  else
    [type?: type]
  end
end
visit_predicate(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 175
def visit_predicate(node)
  pred, args = node

  if pred.equal?(:type?)
    EMPTY_ARRAY
  elsif registry.key?(pred)
    *curried, _ = args
    values = curried.map { |_, v| v }

    if values.empty?
      [pred]
    else
      [pred => values[0]]
    end
  else
    EMPTY_ARRAY
  end
end
visit_schema(_)
Alias for: visit_hash
visit_sum(node) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 139
def visit_sum(node)
  left_node, right_node, = node
  left = visit(left_node)
  right = visit(right_node)

  if left.eql?(NIL)
    right
  else
    [[left, right]]
  end
end

Private Instance Methods

merge_predicates(nodes) click to toggle source

@api private

# File lib/dry/types/predicate_inferrer.rb, line 197
def merge_predicates(nodes)
  preds, merged = nodes.each_with_object([[], {}]) do |predicate, (ps, h)|
    if predicate.is_a?(::Hash)
      h.update(predicate)
    else
      ps << predicate
    end
  end

  merged.empty? ? preds : [*preds, merged]
end