Module: GraphQL::Language

Included in:
StaticValidation::DirectivesAreInValidLocations
Defined in:
lib/graphql/language.rb,
lib/graphql/language/cache.rb,
lib/graphql/language/lexer.rb,
lib/graphql/language/nodes.rb,
lib/graphql/language/parser.rb,
lib/graphql/language/comment.rb,
lib/graphql/language/printer.rb,
lib/graphql/language/visitor.rb,
lib/graphql/language/generation.rb,
lib/graphql/language/block_string.rb,
lib/graphql/language/static_visitor.rb,
lib/graphql/language/definition_slice.rb,
lib/graphql/language/sanitized_printer.rb,
lib/graphql/language/document_from_schema_definition.rb

Defined Under Namespace

Modules: BlockString, Comment, DefinitionSlice, Generation, Nodes Classes: Cache, DocumentFromSchemaDefinition, Lexer, Parser, Printer, SanitizedPrinter, StaticVisitor, Visitor

Constant Summary collapse

LEADING_REGEX =
Regexp.union(" ", *Lexer::Punctuation.constants.map { |const| Lexer::Punctuation.const_get(const) })
EFFICIENT_NUMBER_REGEXP =

Optimized pattern using: - Possessive quantifiers (*+, ++) to prevent backtracking in number patterns - Atomic group (?>…) for IGNORE to prevent backtracking - Single unified number pattern instead of three alternatives

/-?(?:0|[1-9][0-9]*+)(?:\.[0-9]++)?(?:[eE][+-]?[0-9]++)?/
EFFICIENT_IGNORE_REGEXP =
/(?>[, \r\n\t]+|\#[^\n]*$)*/
MAYBE_INVALID_NUMBER =
/\d[_a-zA-Z]/
INVALID_NUMBER_FOLLOWED_BY_NAME_REGEXP =
%r{
  (?<leading>#{LEADING_REGEX})
  (?<num>#{EFFICIENT_NUMBER_REGEXP})
  (?<name>#{Lexer::IDENTIFIER_REGEXP})
  #{EFFICIENT_IGNORE_REGEXP}
  :
}x

Class Method Summary collapse

Class Method Details

.add_space_between_numbers_and_names(query_str) ⇒ Object



99
100
101
102
103
104
# File 'lib/graphql/language.rb', line 99

def self.add_space_between_numbers_and_names(query_str)
  # Fast check for digit followed by identifier char. If this doesn't match, skip the more expensive regexp entirely.
  return query_str unless query_str.match?(MAYBE_INVALID_NUMBER)
  return query_str unless query_str.match?(INVALID_NUMBER_FOLLOWED_BY_NAME_REGEXP)
  query_str.gsub(INVALID_NUMBER_FOLLOWED_BY_NAME_REGEXP, "\\k<leading>\\k<num> \\k<name>:")
end

.escape_single_quoted_newlines(query_str) ⇒ String

Returns a new string if any single-quoted newlines were escaped. Otherwise, returns query_str unchanged.

Returns:

  • (String)


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
# File 'lib/graphql/language.rb', line 47

def self.escape_single_quoted_newlines(query_str)
  scanner = StringScanner.new(query_str)
  inside_single_quoted_string = false
  new_query_str = nil
  while !scanner.eos?
    if scanner.skip(/(?:\\"|[^"\n\r]|""")+/m)
      new_query_str && (new_query_str << scanner.matched)
    elsif scanner.skip('"')
      new_query_str && (new_query_str << '"')
      inside_single_quoted_string = !inside_single_quoted_string
    elsif scanner.skip("\n")
      if inside_single_quoted_string
        new_query_str ||= query_str[0, scanner.pos - 1]
        new_query_str << '\\n'
      else
        new_query_str && (new_query_str << "\n")
      end
    elsif scanner.skip("\r")
      if inside_single_quoted_string
        new_query_str ||= query_str[0, scanner.pos - 1]
        new_query_str << '\\r'
      else
        new_query_str && (new_query_str << "\r")
      end
    elsif scanner.eos?
      break
    else
      raise ArgumentError, "Unmatchable string scanner segment: #{scanner.rest.inspect}"
    end
  end
  new_query_str || query_str
end

.serialize(value) ⇒ 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.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/graphql/language.rb', line 20

def self.serialize(value)
  if value.is_a?(Hash)
    serialized_hash = value.map do |k, v|
      "#{k}:#{serialize v}"
    end.join(",")

    "{#{serialized_hash}}"
  elsif value.is_a?(Array)
    serialized_array = value.map do |v|
      serialize v
    end.join(",")

    "[#{serialized_array}]"
  else
    JSON.generate(value, quirks_mode: true)
  end
rescue JSON::GeneratorError
  if Float::INFINITY == value
    "Infinity"
  else
    raise
  end
end