Class: YardTypes::Parser Private

Inherits:
Object
  • Object
show all
Defined in:
lib/yard_types/parser.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Initial code taken from https://github.com/lsegal/yard-types-parser -- unfortunately that was never released as a gem; and the code on master doesn't actually run.

See Also:

Constant Summary collapse

TOKENS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

{
  collection_start: /</,
  collection_end: />/,
  tuple_start: /\(/,
  tuple_end: /\)/,
  type_name: /#\w+|((::)?\w+)+/,
  type_next: /[,;]/,
  whitespace: /\s+/,
  hash_start: /\{/,
  hash_next: /=>/,
  hash_end: /\}/,
  parse_end: nil
}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(string) ⇒ Parser

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Parser


30
31
32
# File 'lib/yard_types/parser.rb', line 30

def initialize(string)
  @scanner = StringScanner.new(string)
end

Class Method Details

.parse(string) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


26
27
28
# File 'lib/yard_types/parser.rb', line 26

def self.parse(string)
  TypeConstraint.new(new(string).parse)
end

Instance Method Details

#parseObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/yard_types/parser.rb', line 34

def parse
  types = []
  type = nil
  name = nil

  loop do
    found = false
    TOKENS.each do |token_type, match|
      if (match.nil? && @scanner.eos?) || (match && token = @scanner.scan(match))
        found = true
        case token_type
        when :type_name
          raise SyntaxError, "expecting END, got name '#{token}'" if name
          name = token

        when :type_next
          raise SyntaxError, "expecting name, got '#{token}' at #{@scanner.pos}" if name.nil?
          unless type
            type = Type.for(name)
          end
          types << type
          type = nil
          name = nil

        when :tuple_start, :collection_start
          name ||=
            token_type == :collection_start ? 'Array' : '<generic-tuple>'

          type =
            if name == 'Hash' && token_type == :collection_start
              contents = parse
              if contents.length != 2
                raise SyntaxError, "expected 2 types for key/value; got #{contents.length}"
              end

              HashType.new(name, [contents[0]], [contents[1]])
            elsif token_type == :collection_start
              CollectionType.new(name, parse)
            else
              TupleType.new(name, parse)
            end

        when :hash_start
          name ||= "Hash"
          type = HashType.new(name, parse, parse)

        when :hash_next, :hash_end, :tuple_end, :collection_end, :parse_end
          raise SyntaxError, "expecting name, got '#{token}'" if name.nil?
          unless type
            type = Type.for(name)
          end
          types << type
          return types
        end
      end

    end
    raise SyntaxError, "invalid character at #{@scanner.peek(1)}" unless found
  end
end