Module: Rigor::Inference::ParameterArgTypes

Defined in:
lib/rigor/inference/parameter_inference_collector.rb

Overview

Pure argument-type classification for ParameterInferenceCollector — no collector state, so it lives outside the orchestration class. Decides which argument types may seed a parameter (concrete enough for the protection metric to bite) and widens a literal argument to its nominal.

Constant Summary collapse

CONSTANT_CLASSES =
{
  Integer => "Integer", Float => "Float", String => "String",
  Symbol => "Symbol", Range => "Range", TrueClass => "TrueClass",
  FalseClass => "FalseClass", NilClass => "NilClass"
}.freeze

Class Method Summary collapse

Class Method Details

.class_name_of(type) ⇒ Object



56
57
58
# File 'lib/rigor/inference/parameter_inference_collector.rb', line 56

def class_name_of(type)
  type.class_name if type.is_a?(Type::Nominal) || type.is_a?(Type::Singleton)
end

.concrete_class_name(type) ⇒ Object

The dispatch class for a receiver type, for the subset the collector resolves to a user ‘def` (mirrors `CheckRules#concrete_class_name` for the carriers a user-method receiver is typed as). `class_name_of` is the Nominal/Singleton-only variant for an implicit-self `self_type`.



48
49
50
51
52
53
54
# File 'lib/rigor/inference/parameter_inference_collector.rb', line 48

def concrete_class_name(type)
  case type
  when Type::Nominal, Type::Singleton then type.class_name
  when Type::Tuple then "Array"
  when Type::HashShape then "Hash"
  end
end

.constant_class_name(value) ⇒ Object



39
40
41
42
# File 'lib/rigor/inference/parameter_inference_collector.rb', line 39

def constant_class_name(value)
  CONSTANT_CLASSES.each { |klass, name| return name if value.is_a?(klass) }
  nil
end

.non_concrete?(type) ⇒ Boolean

Whether ‘type` is too gradual to seed (not a concrete dispatch target) —the negation of `ProtectionScanner#concrete_receiver?` (a union is concrete only when every arm is).

Returns:

  • (Boolean)


63
64
65
66
67
68
69
# File 'lib/rigor/inference/parameter_inference_collector.rb', line 63

def non_concrete?(type)
  case type
  when Type::Dynamic, Type::Top, Type::Bot then true
  when Type::Union then type.members.any? { |member| non_concrete?(member) }
  else false
  end
end

.widen_for_param(type) ⇒ Object

A parameter holds a *value of* a type across its lifetime, not a pinned literal — so a ‘Constant<“text”>` argument widens to its nominal (`String`); recurses through unions so `Constant<“a”> | Constant<“b”>` collapses to `String`.



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rigor/inference/parameter_inference_collector.rb', line 27

def widen_for_param(type)
  case type
  when Type::Constant
    name = constant_class_name(type.value)
    name ? Type::Combinator.nominal_of(name) : type
  when Type::Union
    Type::Combinator.union(*type.members.map { |member| widen_for_param(member) })
  else
    type
  end
end