graphql 2.0.13 → 2.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
  3. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  4. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  5. data/lib/generators/graphql/install_generator.rb +3 -0
  6. data/lib/generators/graphql/mutation_delete_generator.rb +1 -1
  7. data/lib/generators/graphql/mutation_update_generator.rb +1 -1
  8. data/lib/generators/graphql/relay.rb +18 -1
  9. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  10. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  11. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  12. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  13. data/lib/generators/graphql/templates/base_field.erb +2 -0
  14. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  15. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  16. data/lib/generators/graphql/templates/base_object.erb +2 -0
  17. data/lib/generators/graphql/templates/base_resolver.erb +6 -0
  18. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  19. data/lib/generators/graphql/templates/base_union.erb +2 -0
  20. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  21. data/lib/generators/graphql/templates/loader.erb +2 -0
  22. data/lib/generators/graphql/templates/mutation.erb +2 -0
  23. data/lib/generators/graphql/templates/node_type.erb +2 -0
  24. data/lib/generators/graphql/templates/query_type.erb +2 -0
  25. data/lib/generators/graphql/templates/schema.erb +8 -0
  26. data/lib/graphql/analysis/analyzer.rb +89 -0
  27. data/lib/graphql/analysis/field_usage.rb +82 -0
  28. data/lib/graphql/analysis/max_query_complexity.rb +20 -0
  29. data/lib/graphql/analysis/max_query_depth.rb +20 -0
  30. data/lib/graphql/analysis/query_complexity.rb +183 -0
  31. data/lib/graphql/analysis/query_depth.rb +58 -0
  32. data/lib/graphql/analysis/visitor.rb +283 -0
  33. data/lib/graphql/analysis.rb +92 -1
  34. data/lib/graphql/backtrace/inspect_result.rb +0 -12
  35. data/lib/graphql/backtrace/table.rb +2 -2
  36. data/lib/graphql/backtrace/trace.rb +93 -0
  37. data/lib/graphql/backtrace/tracer.rb +1 -1
  38. data/lib/graphql/backtrace.rb +2 -1
  39. data/lib/graphql/coercion_error.rb +1 -9
  40. data/lib/graphql/dataloader/async_dataloader.rb +88 -0
  41. data/lib/graphql/dataloader/null_dataloader.rb +1 -1
  42. data/lib/graphql/dataloader/request.rb +5 -0
  43. data/lib/graphql/dataloader/source.rb +89 -45
  44. data/lib/graphql/dataloader.rb +115 -142
  45. data/lib/graphql/duration_encoding_error.rb +16 -0
  46. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  47. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  48. data/lib/graphql/execution/interpreter/arguments_cache.rb +33 -33
  49. data/lib/graphql/execution/interpreter/resolve.rb +19 -0
  50. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +175 -0
  51. data/lib/graphql/execution/interpreter/runtime.rb +331 -455
  52. data/lib/graphql/execution/interpreter.rb +125 -61
  53. data/lib/graphql/execution/lazy.rb +6 -12
  54. data/lib/graphql/execution/lookahead.rb +124 -46
  55. data/lib/graphql/execution/multiplex.rb +3 -117
  56. data/lib/graphql/execution.rb +0 -1
  57. data/lib/graphql/introspection/directive_type.rb +3 -3
  58. data/lib/graphql/introspection/dynamic_fields.rb +1 -1
  59. data/lib/graphql/introspection/entry_points.rb +11 -5
  60. data/lib/graphql/introspection/field_type.rb +2 -2
  61. data/lib/graphql/introspection/schema_type.rb +10 -13
  62. data/lib/graphql/introspection/type_type.rb +17 -10
  63. data/lib/graphql/introspection.rb +3 -2
  64. data/lib/graphql/language/block_string.rb +34 -18
  65. data/lib/graphql/language/definition_slice.rb +1 -1
  66. data/lib/graphql/language/document_from_schema_definition.rb +75 -59
  67. data/lib/graphql/language/lexer.rb +358 -1506
  68. data/lib/graphql/language/nodes.rb +166 -93
  69. data/lib/graphql/language/parser.rb +795 -1953
  70. data/lib/graphql/language/printer.rb +340 -160
  71. data/lib/graphql/language/sanitized_printer.rb +21 -23
  72. data/lib/graphql/language/static_visitor.rb +167 -0
  73. data/lib/graphql/language/visitor.rb +188 -141
  74. data/lib/graphql/language.rb +61 -1
  75. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  76. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  77. data/lib/graphql/pagination/array_connection.rb +6 -6
  78. data/lib/graphql/pagination/connection.rb +33 -6
  79. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  80. data/lib/graphql/query/context/scoped_context.rb +101 -0
  81. data/lib/graphql/query/context.rb +117 -112
  82. data/lib/graphql/query/null_context.rb +12 -25
  83. data/lib/graphql/query/validation_pipeline.rb +6 -5
  84. data/lib/graphql/query/variables.rb +3 -3
  85. data/lib/graphql/query.rb +86 -30
  86. data/lib/graphql/railtie.rb +9 -6
  87. data/lib/graphql/rake_task.rb +29 -11
  88. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
  89. data/lib/graphql/schema/addition.rb +59 -23
  90. data/lib/graphql/schema/always_visible.rb +11 -0
  91. data/lib/graphql/schema/argument.rb +55 -26
  92. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  93. data/lib/graphql/schema/build_from_definition.rb +56 -32
  94. data/lib/graphql/schema/directive/one_of.rb +24 -0
  95. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  96. data/lib/graphql/schema/directive/transform.rb +1 -1
  97. data/lib/graphql/schema/directive.rb +15 -3
  98. data/lib/graphql/schema/enum.rb +35 -24
  99. data/lib/graphql/schema/enum_value.rb +2 -3
  100. data/lib/graphql/schema/field/connection_extension.rb +2 -16
  101. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  102. data/lib/graphql/schema/field.rb +147 -107
  103. data/lib/graphql/schema/field_extension.rb +1 -4
  104. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  105. data/lib/graphql/schema/has_single_input_argument.rb +158 -0
  106. data/lib/graphql/schema/input_object.rb +47 -11
  107. data/lib/graphql/schema/interface.rb +15 -21
  108. data/lib/graphql/schema/introspection_system.rb +7 -17
  109. data/lib/graphql/schema/late_bound_type.rb +10 -0
  110. data/lib/graphql/schema/list.rb +2 -2
  111. data/lib/graphql/schema/loader.rb +2 -3
  112. data/lib/graphql/schema/member/base_dsl_methods.rb +18 -14
  113. data/lib/graphql/schema/member/build_type.rb +11 -3
  114. data/lib/graphql/schema/member/has_arguments.rb +170 -130
  115. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  116. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  117. data/lib/graphql/schema/member/has_directives.rb +81 -61
  118. data/lib/graphql/schema/member/has_fields.rb +100 -38
  119. data/lib/graphql/schema/member/has_interfaces.rb +65 -10
  120. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  121. data/lib/graphql/schema/member/has_validators.rb +32 -6
  122. data/lib/graphql/schema/member/relay_shortcuts.rb +19 -0
  123. data/lib/graphql/schema/member/scoped.rb +19 -0
  124. data/lib/graphql/schema/member/type_system_helpers.rb +16 -0
  125. data/lib/graphql/schema/member/validates_input.rb +3 -3
  126. data/lib/graphql/schema/mutation.rb +7 -0
  127. data/lib/graphql/schema/object.rb +16 -5
  128. data/lib/graphql/schema/printer.rb +11 -8
  129. data/lib/graphql/schema/relay_classic_mutation.rb +7 -129
  130. data/lib/graphql/schema/resolver/has_payload_type.rb +9 -9
  131. data/lib/graphql/schema/resolver.rb +47 -32
  132. data/lib/graphql/schema/scalar.rb +3 -3
  133. data/lib/graphql/schema/subscription.rb +11 -4
  134. data/lib/graphql/schema/subset.rb +397 -0
  135. data/lib/graphql/schema/timeout.rb +25 -29
  136. data/lib/graphql/schema/type_expression.rb +2 -2
  137. data/lib/graphql/schema/type_membership.rb +3 -0
  138. data/lib/graphql/schema/union.rb +11 -2
  139. data/lib/graphql/schema/unique_within_type.rb +1 -1
  140. data/lib/graphql/schema/validator/all_validator.rb +60 -0
  141. data/lib/graphql/schema/validator.rb +4 -2
  142. data/lib/graphql/schema/warden.rb +238 -93
  143. data/lib/graphql/schema.rb +498 -103
  144. data/lib/graphql/static_validation/all_rules.rb +2 -1
  145. data/lib/graphql/static_validation/base_visitor.rb +7 -6
  146. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  147. data/lib/graphql/static_validation/literal_validator.rb +24 -7
  148. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  149. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
  150. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -2
  151. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
  152. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  153. data/lib/graphql/static_validation/rules/fields_will_merge.rb +10 -10
  154. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  155. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
  156. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  157. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  158. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  159. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  160. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  161. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -4
  162. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  163. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  164. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  165. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
  166. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  167. data/lib/graphql/static_validation/validation_context.rb +5 -5
  168. data/lib/graphql/static_validation/validator.rb +4 -1
  169. data/lib/graphql/static_validation.rb +0 -1
  170. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +11 -4
  171. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  172. data/lib/graphql/subscriptions/event.rb +11 -10
  173. data/lib/graphql/subscriptions/serialize.rb +2 -0
  174. data/lib/graphql/subscriptions.rb +20 -13
  175. data/lib/graphql/testing/helpers.rb +151 -0
  176. data/lib/graphql/testing.rb +2 -0
  177. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  178. data/lib/graphql/tracing/appoptics_trace.rb +251 -0
  179. data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
  180. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  181. data/lib/graphql/tracing/data_dog_trace.rb +183 -0
  182. data/lib/graphql/tracing/data_dog_tracing.rb +9 -21
  183. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +10 -28
  184. data/lib/graphql/tracing/legacy_trace.rb +69 -0
  185. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  186. data/lib/graphql/tracing/notifications_trace.rb +45 -0
  187. data/lib/graphql/tracing/platform_trace.rb +118 -0
  188. data/lib/graphql/tracing/platform_tracing.rb +17 -3
  189. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +4 -2
  190. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  191. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  192. data/lib/graphql/tracing/scout_trace.rb +72 -0
  193. data/lib/graphql/tracing/sentry_trace.rb +112 -0
  194. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  195. data/lib/graphql/tracing/trace.rb +76 -0
  196. data/lib/graphql/tracing.rb +20 -40
  197. data/lib/graphql/type_kinds.rb +7 -4
  198. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  199. data/lib/graphql/types/relay/base_connection.rb +1 -1
  200. data/lib/graphql/types/relay/connection_behaviors.rb +68 -6
  201. data/lib/graphql/types/relay/edge_behaviors.rb +33 -5
  202. data/lib/graphql/types/relay/node_behaviors.rb +8 -2
  203. data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
  204. data/lib/graphql/types/relay.rb +0 -1
  205. data/lib/graphql/types/string.rb +1 -1
  206. data/lib/graphql/types.rb +1 -0
  207. data/lib/graphql/version.rb +1 -1
  208. data/lib/graphql.rb +27 -20
  209. data/readme.md +13 -3
  210. metadata +96 -47
  211. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  212. data/lib/graphql/analysis/ast/field_usage.rb +0 -57
  213. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
  214. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  215. data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
  216. data/lib/graphql/analysis/ast/query_depth.rb +0 -55
  217. data/lib/graphql/analysis/ast/visitor.rb +0 -269
  218. data/lib/graphql/analysis/ast.rb +0 -81
  219. data/lib/graphql/deprecation.rb +0 -9
  220. data/lib/graphql/filter.rb +0 -53
  221. data/lib/graphql/language/lexer.rl +0 -280
  222. data/lib/graphql/language/parser.y +0 -554
  223. data/lib/graphql/language/token.rb +0 -34
  224. data/lib/graphql/schema/base_64_bp.rb +0 -26
  225. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  226. data/lib/graphql/static_validation/type_stack.rb +0 -216
  227. data/lib/graphql/subscriptions/instrumentation.rb +0 -28
  228. data/lib/graphql/types/relay/default_relay.rb +0 -21
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- # @api private
4
- class Filter
5
- def initialize(only: nil, except: nil)
6
- @only = only
7
- @except = except
8
- end
9
-
10
- # Returns true if `member, ctx` passes this filter
11
- def call(member, ctx)
12
- (@only ? @only.call(member, ctx) : true) &&
13
- (@except ? !@except.call(member, ctx) : true)
14
- end
15
-
16
- def merge(only: nil, except: nil)
17
- onlies = [self].concat(Array(only))
18
- merged_only = MergedOnly.build(onlies)
19
- merged_except = MergedExcept.build(Array(except))
20
- self.class.new(only: merged_only, except: merged_except)
21
- end
22
-
23
- private
24
-
25
- class MergedOnly
26
- def initialize(first, second)
27
- @first = first
28
- @second = second
29
- end
30
-
31
- def call(member, ctx)
32
- @first.call(member, ctx) && @second.call(member, ctx)
33
- end
34
-
35
- def self.build(onlies)
36
- case onlies.size
37
- when 0
38
- nil
39
- when 1
40
- onlies[0]
41
- else
42
- onlies.reduce { |memo, only| self.new(memo, only) }
43
- end
44
- end
45
- end
46
-
47
- class MergedExcept < MergedOnly
48
- def call(member, ctx)
49
- @first.call(member, ctx) || @second.call(member, ctx)
50
- end
51
- end
52
- end
53
- end
@@ -1,280 +0,0 @@
1
- %%{
2
- machine graphql_lexer;
3
-
4
- IDENTIFIER = [_A-Za-z][_0-9A-Za-z]*;
5
- NEWLINE = [\c\r\n];
6
- BLANK = [, \t]+;
7
- COMMENT = '#' [^\n\r]*;
8
- INT = '-'? ('0'|[1-9][0-9]*);
9
- FLOAT_DECIMAL = '.'[0-9]+;
10
- FLOAT_EXP = ('e' | 'E')?('+' | '-')?[0-9]+;
11
- FLOAT = INT FLOAT_DECIMAL? FLOAT_EXP?;
12
- ON = 'on';
13
- FRAGMENT = 'fragment';
14
- TRUE = 'true';
15
- FALSE = 'false';
16
- NULL = 'null';
17
- QUERY = 'query';
18
- MUTATION = 'mutation';
19
- SUBSCRIPTION = 'subscription';
20
- SCHEMA = 'schema';
21
- SCALAR = 'scalar';
22
- TYPE = 'type';
23
- EXTEND = 'extend';
24
- IMPLEMENTS = 'implements';
25
- INTERFACE = 'interface';
26
- UNION = 'union';
27
- ENUM = 'enum';
28
- INPUT = 'input';
29
- DIRECTIVE = 'directive';
30
- REPEATABLE = 'repeatable';
31
- LCURLY = '{';
32
- RCURLY = '}';
33
- LPAREN = '(';
34
- RPAREN = ')';
35
- LBRACKET = '[';
36
- RBRACKET = ']';
37
- COLON = ':';
38
- QUOTE = '"';
39
- BACKSLASH = '\\';
40
- # Could limit to hex here, but “bad unicode escape” on 0XXF is probably a
41
- # more helpful error than “unknown char”
42
- UNICODE_DIGIT = [0-9A-Za-z];
43
- FOUR_DIGIT_UNICODE = UNICODE_DIGIT{4};
44
- N_DIGIT_UNICODE = LCURLY UNICODE_DIGIT{4,} RCURLY;
45
- UNICODE_ESCAPE = '\\u' (FOUR_DIGIT_UNICODE | N_DIGIT_UNICODE);
46
- # https://graphql.github.io/graphql-spec/June2018/#sec-String-Value
47
- STRING_ESCAPE = '\\' [\\/bfnrt];
48
- BLOCK_QUOTE = '"""';
49
- ESCAPED_BLOCK_QUOTE = '\\"""';
50
- BLOCK_STRING_CHAR = (ESCAPED_BLOCK_QUOTE | ^QUOTE | QUOTE{1,2} ^QUOTE);
51
- ESCAPED_QUOTE = '\\"';
52
- STRING_CHAR = ((ESCAPED_QUOTE | ^QUOTE) - BACKSLASH) | UNICODE_ESCAPE | STRING_ESCAPE;
53
- VAR_SIGN = '$';
54
- DIR_SIGN = '@';
55
- ELLIPSIS = '...';
56
- EQUALS = '=';
57
- BANG = '!';
58
- PIPE = '|';
59
- AMP = '&';
60
-
61
- QUOTED_STRING = QUOTE STRING_CHAR* QUOTE;
62
- BLOCK_STRING = BLOCK_QUOTE BLOCK_STRING_CHAR* QUOTE{0,2} BLOCK_QUOTE;
63
- # catch-all for anything else. must be at the bottom for precedence.
64
- UNKNOWN_CHAR = /./;
65
-
66
- # Used with ragel -V for graphviz visualization
67
- str := |*
68
- QUOTED_STRING => { emit_string(ts, te, meta, block: false) };
69
- *|;
70
-
71
- main := |*
72
- INT => { emit(:INT, ts, te, meta) };
73
- FLOAT => { emit(:FLOAT, ts, te, meta) };
74
- ON => { emit(:ON, ts, te, meta, "on") };
75
- FRAGMENT => { emit(:FRAGMENT, ts, te, meta, "fragment") };
76
- TRUE => { emit(:TRUE, ts, te, meta, "true") };
77
- FALSE => { emit(:FALSE, ts, te, meta, "false") };
78
- NULL => { emit(:NULL, ts, te, meta, "null") };
79
- QUERY => { emit(:QUERY, ts, te, meta, "query") };
80
- MUTATION => { emit(:MUTATION, ts, te, meta, "mutation") };
81
- SUBSCRIPTION => { emit(:SUBSCRIPTION, ts, te, meta, "subscription") };
82
- SCHEMA => { emit(:SCHEMA, ts, te, meta) };
83
- SCALAR => { emit(:SCALAR, ts, te, meta) };
84
- TYPE => { emit(:TYPE, ts, te, meta) };
85
- EXTEND => { emit(:EXTEND, ts, te, meta) };
86
- IMPLEMENTS => { emit(:IMPLEMENTS, ts, te, meta) };
87
- INTERFACE => { emit(:INTERFACE, ts, te, meta) };
88
- UNION => { emit(:UNION, ts, te, meta) };
89
- ENUM => { emit(:ENUM, ts, te, meta) };
90
- INPUT => { emit(:INPUT, ts, te, meta) };
91
- DIRECTIVE => { emit(:DIRECTIVE, ts, te, meta) };
92
- REPEATABLE => { emit(:REPEATABLE, ts, te, meta, "repeatable") };
93
- RCURLY => { emit(:RCURLY, ts, te, meta, "}") };
94
- LCURLY => { emit(:LCURLY, ts, te, meta, "{") };
95
- RPAREN => { emit(:RPAREN, ts, te, meta, ")") };
96
- LPAREN => { emit(:LPAREN, ts, te, meta, "(")};
97
- RBRACKET => { emit(:RBRACKET, ts, te, meta, "]") };
98
- LBRACKET => { emit(:LBRACKET, ts, te, meta, "[") };
99
- COLON => { emit(:COLON, ts, te, meta, ":") };
100
- QUOTED_STRING => { emit_string(ts, te, meta, block: false) };
101
- BLOCK_STRING => { emit_string(ts, te, meta, block: true) };
102
- VAR_SIGN => { emit(:VAR_SIGN, ts, te, meta, "$") };
103
- DIR_SIGN => { emit(:DIR_SIGN, ts, te, meta, "@") };
104
- ELLIPSIS => { emit(:ELLIPSIS, ts, te, meta, "...") };
105
- EQUALS => { emit(:EQUALS, ts, te, meta, "=") };
106
- BANG => { emit(:BANG, ts, te, meta, "!") };
107
- PIPE => { emit(:PIPE, ts, te, meta, "|") };
108
- AMP => { emit(:AMP, ts, te, meta, "&") };
109
- IDENTIFIER => { emit(:IDENTIFIER, ts, te, meta) };
110
- COMMENT => { record_comment(ts, te, meta) };
111
-
112
- NEWLINE => {
113
- meta[:line] += 1
114
- meta[:col] = 1
115
- };
116
-
117
- BLANK => { meta[:col] += te - ts };
118
-
119
- UNKNOWN_CHAR => { emit(:UNKNOWN_CHAR, ts, te, meta) };
120
-
121
- *|;
122
- }%%
123
-
124
- # frozen_string_literal: true
125
-
126
- module GraphQL
127
- module Language
128
- module Lexer
129
- def self.tokenize(query_string)
130
- run_lexer(query_string)
131
- end
132
-
133
- # Replace any escaped unicode or whitespace with the _actual_ characters
134
- # To avoid allocating more strings, this modifies the string passed into it
135
- def self.replace_escaped_characters_in_place(raw_string)
136
- raw_string.gsub!(ESCAPES, ESCAPES_REPLACE)
137
- raw_string.gsub!(UTF_8) do |_matched_str|
138
- codepoint_1 = ($1 || $2).to_i(16)
139
- codepoint_2 = $3
140
-
141
- if codepoint_2
142
- codepoint_2 = codepoint_2.to_i(16)
143
- if (codepoint_1 >= 0xD800 && codepoint_1 <= 0xDBFF) && # leading surrogate
144
- (codepoint_2 >= 0xDC00 && codepoint_2 <= 0xDFFF) # trailing surrogate
145
- # A surrogate pair
146
- combined = ((codepoint_1 - 0xD800) * 0x400) + (codepoint_2 - 0xDC00) + 0x10000
147
- [combined].pack('U'.freeze)
148
- else
149
- # Two separate code points
150
- [codepoint_1].pack('U'.freeze) + [codepoint_2].pack('U'.freeze)
151
- end
152
- else
153
- [codepoint_1].pack('U'.freeze)
154
- end
155
- end
156
- nil
157
- end
158
-
159
- private
160
-
161
- %% write data;
162
-
163
- def self.run_lexer(query_string)
164
- data = query_string.unpack(PACK_DIRECTIVE)
165
- eof = data.length
166
-
167
- # Since `Lexer` is a module, store all lexer state
168
- # in this local variable:
169
- meta = {
170
- line: 1,
171
- col: 1,
172
- data: data,
173
- tokens: [],
174
- previous_token: nil,
175
- }
176
-
177
- p ||= 0
178
- pe ||= data.length
179
-
180
- %% write init;
181
-
182
- %% write exec;
183
-
184
- meta[:tokens]
185
- end
186
-
187
- def self.record_comment(ts, te, meta)
188
- token = GraphQL::Language::Token.new(
189
- :COMMENT,
190
- meta[:data][ts, te - ts].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING),
191
- meta[:line],
192
- meta[:col],
193
- meta[:previous_token],
194
- )
195
-
196
- meta[:previous_token] = token
197
-
198
- meta[:col] += te - ts
199
- end
200
-
201
- def self.emit(token_name, ts, te, meta, token_value = nil)
202
- token_value ||= meta[:data][ts, te - ts].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING)
203
- meta[:tokens] << token = GraphQL::Language::Token.new(
204
- token_name,
205
- token_value,
206
- meta[:line],
207
- meta[:col],
208
- meta[:previous_token],
209
- )
210
- meta[:previous_token] = token
211
- # Bump the column counter for the next token
212
- meta[:col] += te - ts
213
- end
214
-
215
- ESCAPES = /\\["\\\/bfnrt]/
216
- ESCAPES_REPLACE = {
217
- '\\"' => '"',
218
- "\\\\" => "\\",
219
- "\\/" => '/',
220
- "\\b" => "\b",
221
- "\\f" => "\f",
222
- "\\n" => "\n",
223
- "\\r" => "\r",
224
- "\\t" => "\t",
225
- }
226
-
227
- UTF_8 = /\\u(?:([\dAa-f]{4})|\{([\da-f]{4,})\})(?:\\u([\dAa-f]{4}))?/i
228
-
229
-
230
- VALID_STRING = /\A(?:[^\\]|#{ESCAPES}|#{UTF_8})*\z/o
231
-
232
- PACK_DIRECTIVE = "c*"
233
- UTF_8_ENCODING = "UTF-8"
234
-
235
- def self.emit_string(ts, te, meta, block:)
236
- quotes_length = block ? 3 : 1
237
- value = meta[:data][ts + quotes_length, te - ts - 2 * quotes_length].pack(PACK_DIRECTIVE).force_encoding(UTF_8_ENCODING) || ''
238
- line_incr = 0
239
- if block && !value.empty?
240
- line_incr = value.count("\n")
241
- value = GraphQL::Language::BlockString.trim_whitespace(value)
242
- end
243
-
244
- if !value.valid_encoding? || !value.match?(VALID_STRING)
245
- meta[:tokens] << token = GraphQL::Language::Token.new(
246
- :BAD_UNICODE_ESCAPE,
247
- value,
248
- meta[:line],
249
- meta[:col],
250
- meta[:previous_token],
251
- )
252
- else
253
- replace_escaped_characters_in_place(value)
254
-
255
- if !value.valid_encoding?
256
- meta[:tokens] << token = GraphQL::Language::Token.new(
257
- :BAD_UNICODE_ESCAPE,
258
- value,
259
- meta[:line],
260
- meta[:col],
261
- meta[:previous_token],
262
- )
263
- else
264
- meta[:tokens] << token = GraphQL::Language::Token.new(
265
- :STRING,
266
- value,
267
- meta[:line],
268
- meta[:col],
269
- meta[:previous_token],
270
- )
271
- end
272
- end
273
-
274
- meta[:previous_token] = token
275
- meta[:col] += te - ts
276
- meta[:line] += line_incr
277
- end
278
- end
279
- end
280
- end