Class: Low::Evaluator

Inherits:
Object show all
Includes:
ExpressionHelpers, Types
Defined in:
lib/definitions/evaluator.rb

Overview

Evaluate code stored in strings into constants and values. ┌────────┐ ┌─────────┐ ┌─────────────┐ ┌─────────┐ ┌─────────┐│ Lowkey │ │ Proxies │ │ Expressions │ │ LowType │ │ Methods │└────┬───┘ └────┬────┘ └──────┬──────┘ └────┬────┘ └────┬────┘

│              │                 │                 │               │
│ Parses AST   │                 │                 │               │
├─────────────►│                 │                 │               │
│              │                 │                 │               │
│              │ Stores          │                 │               │
│              ├────────────────►│                 │               │
│              │                 │                 │               │
│              │                 │ Evaluates <-- YOU ARE HERE.     |
│              │                 │◄────────────────┤               │
│              │                 │                 │               │
│              │                 │                 │ Redefines     │
│              │                 │                 ├──────────────►│
│              │                 │                 │               │
│              │                 │ Validates       │               │
│              │                 │◄┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┤
│              │                 │                 │               │

Constant Summary

Constants included from Types

Types::COMPLEX_TYPES

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ExpressionHelpers

#type, #value

Class Method Details

.evaluate(method_proxies:, class_binding: nil) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/definitions/evaluator.rb', line 49

def evaluate(method_proxies:, class_binding: nil)
  require_relative '../syntax/union_types' if LowType.config.union_type_expressions

  method_proxies.each_value do |method_proxy|
    evaluate_param_proxy_expressions(method_proxy:, class_binding:)
    evaluate_return_proxy_expression(return_proxy: method_proxy.return_proxy) if method_proxy.return_proxy
  end
end

.evaluate_param_proxy_expressions(method_proxy:, class_binding: nil) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/definitions/evaluator.rb', line 58

def evaluate_param_proxy_expressions(method_proxy:, class_binding: nil)
  begin # rubocop:disable Style/RedundantBegin
    method_proxy.tagged_params(:value).each do |param_proxy|
      expression = begin
        new.instance_evaluate(proxy: param_proxy)
      rescue NameError
        raise unless class_binding

        new.class_evaluate(proxy: param_proxy, class_binding:)
      end
      param_proxy.expression = cast_type_expression(expression:, method_proxy:)
    end
  rescue NameError => e
    mp = method_proxy
    raise NameError, "Unknown type '#{e.name}' for #{mp.scope} at #{mp.file_path}:#{mp.start_line}"
  end
end

.evaluate_return_proxy_expression(return_proxy:) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/definitions/evaluator.rb', line 76

def evaluate_return_proxy_expression(return_proxy:)
  begin
    expression = new.instance_evaluate(proxy: return_proxy)
  rescue NameError
    rp = return_proxy
    raise NameError, "Unknown return type '#{rp.value}' for #{rp.scope} at #{rp.file_path}:#{rp.start_line}"
  end

  expression = TypeExpression.new(type: expression) unless expression.is_a?(TypeExpression)

  return_proxy.expression = expression
end

Instance Method Details

#class_evaluate(proxy:, class_binding:) ⇒ Object



43
44
45
46
# File 'lib/definitions/evaluator.rb', line 43

def class_evaluate(proxy:, class_binding:)
  # Not a security risk because the code comes from a trusted source; the file that included lowtype.
  eval(proxy.value, class_binding, proxy.file_path, proxy.start_line) # rubocop:disable Security/Eval
end

#instance_evaluate(proxy:) ⇒ Object



38
39
40
41
# File 'lib/definitions/evaluator.rb', line 38

def instance_evaluate(proxy:)
  # Not a security risk because the code comes from a trusted source; the file that included lowtype.
  eval(proxy.value, binding, proxy.file_path, proxy.start_line) # rubocop:disable Security/Eval
end