class YARD::Tags::TypesExplainer::Parser
@private
Constants
- TOKENS
Public Class Methods
Source
# File lib/yard/tags/types_explainer.rb, line 173 def initialize(string) @scanner = StringScanner.new(string) end
Source
# File lib/yard/tags/types_explainer.rb, line 169 def self.parse(string) new(string).parse end
Public Instance Methods
Source
# File lib/yard/tags/types_explainer.rb, line 178 def parse(until_tokens: [:parse_end]) parse_until(until_tokens).first end
@return [Array(Boolean, Array<Type>)] - finished, types
Private Instance Methods
Source
# File lib/yard/tags/types_explainer.rb, line 273 def create_type(name) if name[0, 1] == ":" || (name[0, 1] =~ /['"]/ && name[-1, 1] =~ /['"]/) LiteralType.new(name) elsif name[0, 1] == "#" DuckType.new(name) else Type.new(name) end end
Source
# File lib/yard/tags/types_explainer.rb, line 241 def parse_hash_collection(name) key_value_pairs = [] current_keys = [] finished = false parse_with_handlers do |token_type, token| case token_type when :type_name current_keys << create_type(token) when :type_next # Comma - continue collecting keys unless we just processed a value # In that case, start a new key group when :hash_collection_value # => - current keys map to the next value(s) raise SyntaxError, "no keys before =>" if current_keys.empty? values, end_token = parse_until([:hash_collection_value_end, :hash_collection_end, :parse_end]) key_value_pairs << [current_keys, values] current_keys = [] finished = end_token != :hash_collection_value_end when :hash_collection_end, :parse_end # End of hash finished = true when :whitespace # Ignore whitespace end [finished, HashCollectionType.new(name, key_value_pairs)] end end
Source
# File lib/yard/tags/types_explainer.rb, line 184 def parse_until(until_tokens) current_parsed_types = [] type = nil name = nil finished = false end_token = nil types = parse_with_handlers do |token_type, token| case token_type when *until_tokens raise SyntaxError, "expecting name, got '#{token}'" if name.nil? type = create_type(name) unless type current_parsed_types << type finished = true end_token = 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? type = create_type(name) unless type current_parsed_types << type name = nil type = nil when :fixed_collection_start, :collection_start name ||= "Array" klass = token_type == :collection_start ? CollectionType : FixedCollectionType nested_types, = parse_until([:fixed_collection_end, :collection_end, :parse_end]) type = klass.new(name, nested_types) when :hash_collection_start name ||= "Hash" type = parse_hash_collection(name) end [finished, current_parsed_types] end [types, end_token] end
Source
# File lib/yard/tags/types_explainer.rb, line 223 def parse_with_handlers loop do found = false TOKENS.each do |token_type, match| # TODO: cleanup this code. # rubocop:disable Lint/AssignmentInCondition next unless (match.nil? && @scanner.eos?) || (match && token = @scanner.scan(match)) found = true # @type [Array<Type>] finished, types = yield(token_type, token) return types if finished break end raise SyntaxError, "invalid character at #{@scanner.peek(1)}" unless found end nil end
@return [Array<Type>]