class TypedRb::TypeSignature::Parser

Constants

PARSERS

Attributes

method_info[R]

Public Class Methods

new(method_info = {}) click to toggle source
# File lib/typed/type_signature/parser.rb, line 169
def initialize(method_info = {})
  @method_info = method_info
  @current_type = []
  @current_function = []
  @stack = []
  @in_binding = false
end
parse(expr, method_info = {}) click to toggle source
# File lib/typed/type_signature/parser.rb, line 163
def self.parse(expr, method_info = {})
  (@parser || Parser.new(method_info)).parse(expr)
end

Public Instance Methods

parse(expr) click to toggle source
# File lib/typed/type_signature/parser.rb, line 177
def parse(expr)
  @input_expression = expr
  expr = sanitize_input(expr)
  expr.each_char { |elem| parse_next_char(elem) }
  build_final_signature
rescue TypedRb::TypeSignature::ParsingError => e
  raise e
rescue StandardError => e
  raise TypedRb::TypeSignature::ParsingError.new(expr, e.message)
end

Private Instance Methods

build_final_signature() click to toggle source
# File lib/typed/type_signature/parser.rb, line 219
def build_final_signature
  fail ParsingError.new(@input_expression, 'Unbalanced parentheses.') unless @stack.empty?
  new_type = parse_new_type

  @current_function << new_type unless @current_type.empty?
  @current_type = []
  final_function = transform_function_tokens(@current_function)

  # Distinguis between function without arguments:
  #   -> unit => [:<, 'unit']
  # and generic type without function (e.g. in the
  # type parameter of a class Array.('Array[Integer]'))
  #   Array[Integer] => ['Array', {:type ... }]
  if @current_function.at(0) != :< && final_function.size == 1
    final_function.last
  else
    final_function
  end
end
parse_next_char(elem) click to toggle source
# File lib/typed/type_signature/parser.rb, line 204
def parse_next_char(elem)
  setup_binding_context(elem)
  if PARSERS[elem]
    PARSERS[elem][self]
  else
    @current_type << elem
  end
end
sanitize_input(expr) click to toggle source
# File lib/typed/type_signature/parser.rb, line 190
def sanitize_input(expr)
  expr.gsub(/\s+/, '').gsub('->', '/')
end
setup_binding_context(elem) click to toggle source
# File lib/typed/type_signature/parser.rb, line 213
def setup_binding_context(elem)
  @in_binding = true  if elem == '['
  @in_binding = false if elem == ']'
  @binding = elem     if elem == '<' || elem == '>'
end