rails-graphql 0.2.1 → 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (297) hide show
  1. checksums.yaml +4 -4
  2. data/ext/console.rb +18 -0
  3. data/ext/extconf.h +3 -0
  4. data/ext/extconf.rb +1 -54
  5. data/ext/gql_parser.c +646 -0
  6. data/ext/shared.c +482 -0
  7. data/ext/shared.h +177 -0
  8. data/lib/gql_parser.so +0 -0
  9. data/lib/rails/graphql/adapters/mysql_adapter.rb +59 -0
  10. data/lib/rails/graphql/adapters/pg_adapter.rb +25 -22
  11. data/lib/rails/graphql/adapters/sqlite_adapter.rb +17 -14
  12. data/lib/rails/graphql/alternative/field_set.rb +36 -0
  13. data/lib/rails/graphql/alternative/mutation.rb +17 -0
  14. data/lib/rails/graphql/alternative/query.rb +93 -0
  15. data/lib/rails/graphql/alternative/subscription.rb +17 -0
  16. data/lib/rails/graphql/alternative.rb +20 -0
  17. data/lib/rails/graphql/argument.rb +21 -24
  18. data/lib/rails/graphql/callback.rb +24 -9
  19. data/lib/rails/graphql/collectors/hash_collector.rb +14 -6
  20. data/lib/rails/graphql/collectors/idented_collector.rb +10 -7
  21. data/lib/rails/graphql/collectors/json_collector.rb +22 -17
  22. data/lib/rails/graphql/collectors.rb +4 -4
  23. data/lib/rails/graphql/config.rb +130 -15
  24. data/lib/rails/graphql/directive/cached_directive.rb +33 -0
  25. data/lib/rails/graphql/directive/deprecated_directive.rb +10 -10
  26. data/lib/rails/graphql/directive/include_directive.rb +5 -4
  27. data/lib/rails/graphql/directive/skip_directive.rb +5 -4
  28. data/lib/rails/graphql/directive.rb +118 -63
  29. data/lib/rails/graphql/errors.rb +33 -4
  30. data/lib/rails/graphql/event.rb +16 -5
  31. data/lib/rails/graphql/field/authorized_field.rb +19 -3
  32. data/lib/rails/graphql/field/input_field.rb +11 -10
  33. data/lib/rails/graphql/field/mutation_field.rb +42 -7
  34. data/lib/rails/graphql/field/output_field.rb +102 -13
  35. data/lib/rails/graphql/field/proxied_field.rb +31 -22
  36. data/lib/rails/graphql/field/resolved_field.rb +26 -24
  37. data/lib/rails/graphql/field/scoped_config.rb +10 -4
  38. data/lib/rails/graphql/field/subscription_field.rb +140 -0
  39. data/lib/rails/graphql/field/typed_field.rb +43 -22
  40. data/lib/rails/graphql/field.rb +70 -56
  41. data/lib/rails/graphql/global_id.rb +85 -0
  42. data/lib/rails/graphql/helpers/attribute_delegator.rb +5 -5
  43. data/lib/rails/graphql/helpers/inherited_collection/array.rb +50 -0
  44. data/lib/rails/graphql/helpers/inherited_collection/base.rb +43 -0
  45. data/lib/rails/graphql/helpers/inherited_collection/hash.rb +87 -0
  46. data/lib/rails/graphql/helpers/inherited_collection.rb +25 -76
  47. data/lib/rails/graphql/helpers/instantiable.rb +15 -0
  48. data/lib/rails/graphql/helpers/leaf_from_ar.rb +7 -7
  49. data/lib/rails/graphql/helpers/registerable.rb +44 -62
  50. data/lib/rails/graphql/helpers/unregisterable.rb +16 -0
  51. data/lib/rails/graphql/helpers/with_arguments.rb +31 -27
  52. data/lib/rails/graphql/helpers/with_assignment.rb +6 -6
  53. data/lib/rails/graphql/helpers/with_callbacks.rb +25 -8
  54. data/lib/rails/graphql/helpers/with_description.rb +71 -0
  55. data/lib/rails/graphql/helpers/with_directives.rb +54 -30
  56. data/lib/rails/graphql/helpers/with_events.rb +21 -23
  57. data/lib/rails/graphql/helpers/with_fields.rb +76 -22
  58. data/lib/rails/graphql/helpers/with_global_id.rb +22 -0
  59. data/lib/rails/graphql/helpers/with_name.rb +43 -0
  60. data/lib/rails/graphql/helpers/with_namespace.rb +7 -4
  61. data/lib/rails/graphql/helpers/with_owner.rb +8 -7
  62. data/lib/rails/graphql/helpers/with_schema_fields.rb +137 -55
  63. data/lib/rails/graphql/helpers/with_validator.rb +9 -9
  64. data/lib/rails/graphql/helpers.rb +10 -3
  65. data/lib/rails/graphql/introspection.rb +43 -36
  66. data/lib/rails/graphql/railtie.rb +88 -33
  67. data/lib/rails/graphql/railties/base_generator.rb +3 -9
  68. data/lib/rails/graphql/railties/channel.rb +157 -0
  69. data/lib/rails/graphql/railties/controller.rb +62 -17
  70. data/lib/rails/graphql/railties/controller_runtime.rb +5 -5
  71. data/lib/rails/graphql/railties/log_subscriber.rb +81 -14
  72. data/lib/rails/graphql/request/arguments.rb +24 -49
  73. data/lib/rails/graphql/request/backtrace.rb +191 -0
  74. data/lib/rails/graphql/request/component/field.rb +86 -65
  75. data/lib/rails/graphql/request/component/fragment.rb +72 -24
  76. data/lib/rails/graphql/request/component/operation/subscription.rb +164 -4
  77. data/lib/rails/graphql/request/component/operation.rb +63 -31
  78. data/lib/rails/graphql/request/component/spread.rb +68 -25
  79. data/lib/rails/graphql/request/component/typename.rb +27 -12
  80. data/lib/rails/graphql/request/component.rb +75 -36
  81. data/lib/rails/graphql/request/context.rb +18 -8
  82. data/lib/rails/graphql/request/errors.rb +16 -6
  83. data/lib/rails/graphql/request/event.rb +19 -8
  84. data/lib/rails/graphql/request/helpers/directives.rb +68 -27
  85. data/lib/rails/graphql/request/helpers/selection_set.rb +51 -25
  86. data/lib/rails/graphql/request/helpers/value_writers.rb +18 -16
  87. data/lib/rails/graphql/request/prepared_data.rb +98 -0
  88. data/lib/rails/graphql/request/steps/authorizable.rb +24 -14
  89. data/lib/rails/graphql/request/steps/organizable.rb +110 -48
  90. data/lib/rails/graphql/request/steps/{prepareable.rb → preparable.rb} +20 -7
  91. data/lib/rails/graphql/request/steps/{resolveable.rb → resolvable.rb} +15 -6
  92. data/lib/rails/graphql/request/strategy/cached_strategy.rb +64 -0
  93. data/lib/rails/graphql/request/strategy/dynamic_instance.rb +6 -6
  94. data/lib/rails/graphql/request/strategy/multi_query_strategy.rb +6 -13
  95. data/lib/rails/graphql/request/strategy/sequenced_strategy.rb +9 -9
  96. data/lib/rails/graphql/request/strategy.rb +131 -75
  97. data/lib/rails/graphql/request/subscription.rb +80 -0
  98. data/lib/rails/graphql/request.rb +305 -86
  99. data/lib/rails/graphql/schema.rb +240 -48
  100. data/lib/rails/graphql/shortcuts.rb +22 -3
  101. data/lib/rails/graphql/source/active_record/builders.rb +49 -35
  102. data/lib/rails/graphql/source/active_record_source.rb +70 -54
  103. data/lib/rails/graphql/source/base.rb +111 -0
  104. data/lib/rails/graphql/source/builder.rb +128 -0
  105. data/lib/rails/graphql/source/scoped_arguments.rb +31 -19
  106. data/lib/rails/graphql/source.rb +89 -213
  107. data/lib/rails/graphql/subscription/provider/action_cable.rb +112 -0
  108. data/lib/rails/graphql/subscription/provider/base.rb +191 -0
  109. data/lib/rails/graphql/subscription/provider.rb +18 -0
  110. data/lib/rails/graphql/subscription/store/base.rb +145 -0
  111. data/lib/rails/graphql/subscription/store/memory.rb +127 -0
  112. data/lib/rails/graphql/subscription/store.rb +19 -0
  113. data/lib/rails/graphql/subscription.rb +17 -0
  114. data/lib/rails/graphql/to_gql.rb +29 -32
  115. data/lib/rails/graphql/type/enum/directive_location_enum.rb +11 -11
  116. data/lib/rails/graphql/type/enum/type_kind_enum.rb +3 -3
  117. data/lib/rails/graphql/type/enum.rb +34 -48
  118. data/lib/rails/graphql/type/input.rb +74 -23
  119. data/lib/rails/graphql/type/interface.rb +16 -26
  120. data/lib/rails/graphql/type/object/directive_object.rb +4 -4
  121. data/lib/rails/graphql/type/object/enum_value_object.rb +3 -3
  122. data/lib/rails/graphql/type/object/field_object.rb +24 -6
  123. data/lib/rails/graphql/type/object/input_value_object.rb +3 -3
  124. data/lib/rails/graphql/type/object/schema_object.rb +5 -8
  125. data/lib/rails/graphql/type/object/type_object.rb +29 -19
  126. data/lib/rails/graphql/type/object.rb +26 -23
  127. data/lib/rails/graphql/type/scalar/any_scalar.rb +30 -0
  128. data/lib/rails/graphql/type/scalar/bigint_scalar.rb +5 -5
  129. data/lib/rails/graphql/type/scalar/binary_scalar.rb +3 -3
  130. data/lib/rails/graphql/type/scalar/boolean_scalar.rb +8 -8
  131. data/lib/rails/graphql/type/scalar/date_scalar.rb +3 -3
  132. data/lib/rails/graphql/type/scalar/date_time_scalar.rb +3 -3
  133. data/lib/rails/graphql/type/scalar/decimal_scalar.rb +3 -3
  134. data/lib/rails/graphql/type/scalar/float_scalar.rb +5 -5
  135. data/lib/rails/graphql/type/scalar/id_scalar.rb +6 -5
  136. data/lib/rails/graphql/type/scalar/int_scalar.rb +6 -5
  137. data/lib/rails/graphql/type/scalar/json_scalar.rb +39 -0
  138. data/lib/rails/graphql/type/scalar/string_scalar.rb +18 -4
  139. data/lib/rails/graphql/type/scalar/time_scalar.rb +5 -5
  140. data/lib/rails/graphql/type/scalar.rb +25 -22
  141. data/lib/rails/graphql/type/union.rb +14 -16
  142. data/lib/rails/graphql/type.rb +34 -25
  143. data/lib/rails/graphql/type_map.rb +256 -164
  144. data/lib/rails/graphql/uri.rb +166 -0
  145. data/lib/rails/graphql/version.rb +15 -3
  146. data/lib/rails/graphql.rake +3 -0
  147. data/lib/rails/graphql.rb +85 -52
  148. data/lib/rails-graphql.rb +1 -1
  149. data/test/assets/en.yml +29 -0
  150. data/test/assets/introspection-mem.txt +1 -1
  151. data/test/assets/mem.gql +18 -45
  152. data/test/assets/mysql.gql +392 -0
  153. data/test/assets/sqlite.gql +21 -12
  154. data/test/assets/translate.gql +335 -0
  155. data/test/config.rb +18 -8
  156. data/test/graphql/schema_test.rb +12 -19
  157. data/test/graphql/source_test.rb +8 -75
  158. data/test/graphql/type/enum_test.rb +207 -203
  159. data/test/graphql/type/input_test.rb +14 -9
  160. data/test/graphql/type/interface_test.rb +4 -4
  161. data/test/graphql/type/scalar/any_scalar_test.rb +38 -0
  162. data/test/graphql/type/scalar/boolean_scalar_test.rb +6 -3
  163. data/test/graphql/type/scalar/json_scalar_test.rb +23 -0
  164. data/test/graphql/type_map_test.rb +51 -66
  165. data/test/graphql/type_test.rb +0 -19
  166. data/test/graphql_test.rb +1 -1
  167. data/test/integration/{authorization/authorization_test.rb → authorization_test.rb} +40 -14
  168. data/test/integration/config.rb +36 -3
  169. data/test/integration/customization_test.rb +39 -0
  170. data/test/integration/global_id_test.rb +99 -0
  171. data/test/integration/memory/star_wars_introspection_test.rb +24 -16
  172. data/test/integration/memory/star_wars_query_test.rb +54 -3
  173. data/test/integration/memory/star_wars_validation_test.rb +1 -1
  174. data/test/integration/mysql/star_wars_introspection_test.rb +25 -0
  175. data/test/integration/persisted_query_test.rb +87 -0
  176. data/test/integration/resolver_precedence_test.rb +154 -0
  177. data/test/integration/schemas/memory.rb +22 -7
  178. data/test/integration/schemas/mysql.rb +62 -0
  179. data/test/integration/schemas/sqlite.rb +21 -12
  180. data/test/integration/sqlite/star_wars_global_id_test.rb +83 -0
  181. data/test/integration/sqlite/star_wars_introspection_test.rb +10 -0
  182. data/test/integration/sqlite/star_wars_query_test.rb +14 -1
  183. data/test/integration/translate_test.rb +61 -0
  184. data/test/test_ext.rb +16 -13
  185. metadata +108 -157
  186. data/ext/depend +0 -3
  187. data/ext/graphqlparser/Ast.cpp +0 -346
  188. data/ext/graphqlparser/Ast.h +0 -1214
  189. data/ext/graphqlparser/AstNode.h +0 -36
  190. data/ext/graphqlparser/AstVisitor.h +0 -137
  191. data/ext/graphqlparser/GraphQLParser.cpp +0 -76
  192. data/ext/graphqlparser/GraphQLParser.h +0 -55
  193. data/ext/graphqlparser/JsonVisitor.cpp +0 -161
  194. data/ext/graphqlparser/JsonVisitor.cpp.inc +0 -456
  195. data/ext/graphqlparser/JsonVisitor.h +0 -121
  196. data/ext/graphqlparser/JsonVisitor.h.inc +0 -110
  197. data/ext/graphqlparser/VERSION +0 -1
  198. data/ext/graphqlparser/c/GraphQLAst.cpp +0 -324
  199. data/ext/graphqlparser/c/GraphQLAst.h +0 -180
  200. data/ext/graphqlparser/c/GraphQLAstForEachConcreteType.h +0 -44
  201. data/ext/graphqlparser/c/GraphQLAstNode.cpp +0 -25
  202. data/ext/graphqlparser/c/GraphQLAstNode.h +0 -33
  203. data/ext/graphqlparser/c/GraphQLAstToJSON.cpp +0 -21
  204. data/ext/graphqlparser/c/GraphQLAstToJSON.h +0 -24
  205. data/ext/graphqlparser/c/GraphQLAstVisitor.cpp +0 -55
  206. data/ext/graphqlparser/c/GraphQLAstVisitor.h +0 -53
  207. data/ext/graphqlparser/c/GraphQLParser.cpp +0 -35
  208. data/ext/graphqlparser/c/GraphQLParser.h +0 -54
  209. data/ext/graphqlparser/dump_json_ast.cpp +0 -48
  210. data/ext/graphqlparser/lexer.lpp +0 -324
  211. data/ext/graphqlparser/parser.ypp +0 -693
  212. data/ext/graphqlparser/parsergen/lexer.cpp +0 -2633
  213. data/ext/graphqlparser/parsergen/lexer.h +0 -528
  214. data/ext/graphqlparser/parsergen/location.hh +0 -189
  215. data/ext/graphqlparser/parsergen/parser.tab.cpp +0 -3300
  216. data/ext/graphqlparser/parsergen/parser.tab.hpp +0 -646
  217. data/ext/graphqlparser/parsergen/position.hh +0 -179
  218. data/ext/graphqlparser/parsergen/stack.hh +0 -156
  219. data/ext/graphqlparser/syntaxdefs.h +0 -19
  220. data/ext/libgraphqlparser/AstNode.h +0 -36
  221. data/ext/libgraphqlparser/CMakeLists.txt +0 -148
  222. data/ext/libgraphqlparser/CONTRIBUTING.md +0 -23
  223. data/ext/libgraphqlparser/GraphQLParser.cpp +0 -76
  224. data/ext/libgraphqlparser/GraphQLParser.h +0 -55
  225. data/ext/libgraphqlparser/JsonVisitor.cpp +0 -161
  226. data/ext/libgraphqlparser/JsonVisitor.h +0 -121
  227. data/ext/libgraphqlparser/LICENSE +0 -22
  228. data/ext/libgraphqlparser/README.clang-tidy +0 -7
  229. data/ext/libgraphqlparser/README.md +0 -84
  230. data/ext/libgraphqlparser/ast/ast.ast +0 -203
  231. data/ext/libgraphqlparser/ast/ast.py +0 -61
  232. data/ext/libgraphqlparser/ast/c.py +0 -100
  233. data/ext/libgraphqlparser/ast/c.pyc +0 -0
  234. data/ext/libgraphqlparser/ast/c_impl.py +0 -61
  235. data/ext/libgraphqlparser/ast/c_impl.pyc +0 -0
  236. data/ext/libgraphqlparser/ast/c_visitor_impl.py +0 -39
  237. data/ext/libgraphqlparser/ast/c_visitor_impl.pyc +0 -0
  238. data/ext/libgraphqlparser/ast/casing.py +0 -26
  239. data/ext/libgraphqlparser/ast/casing.pyc +0 -0
  240. data/ext/libgraphqlparser/ast/cxx.py +0 -197
  241. data/ext/libgraphqlparser/ast/cxx.pyc +0 -0
  242. data/ext/libgraphqlparser/ast/cxx_impl.py +0 -61
  243. data/ext/libgraphqlparser/ast/cxx_impl.pyc +0 -0
  244. data/ext/libgraphqlparser/ast/cxx_json_visitor_header.py +0 -42
  245. data/ext/libgraphqlparser/ast/cxx_json_visitor_header.pyc +0 -0
  246. data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.py +0 -80
  247. data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.pyc +0 -0
  248. data/ext/libgraphqlparser/ast/cxx_visitor.py +0 -64
  249. data/ext/libgraphqlparser/ast/cxx_visitor.pyc +0 -0
  250. data/ext/libgraphqlparser/ast/js.py +0 -65
  251. data/ext/libgraphqlparser/ast/license.py +0 -10
  252. data/ext/libgraphqlparser/ast/license.pyc +0 -0
  253. data/ext/libgraphqlparser/c/GraphQLAstNode.cpp +0 -25
  254. data/ext/libgraphqlparser/c/GraphQLAstNode.h +0 -33
  255. data/ext/libgraphqlparser/c/GraphQLAstToJSON.cpp +0 -21
  256. data/ext/libgraphqlparser/c/GraphQLAstToJSON.h +0 -24
  257. data/ext/libgraphqlparser/c/GraphQLAstVisitor.cpp +0 -55
  258. data/ext/libgraphqlparser/c/GraphQLAstVisitor.h +0 -53
  259. data/ext/libgraphqlparser/c/GraphQLParser.cpp +0 -35
  260. data/ext/libgraphqlparser/c/GraphQLParser.h +0 -54
  261. data/ext/libgraphqlparser/clang-tidy-all.sh +0 -3
  262. data/ext/libgraphqlparser/cmake/version.cmake +0 -16
  263. data/ext/libgraphqlparser/dump_json_ast.cpp +0 -48
  264. data/ext/libgraphqlparser/go/README.md +0 -20
  265. data/ext/libgraphqlparser/go/callbacks.go +0 -18
  266. data/ext/libgraphqlparser/go/gotest.go +0 -64
  267. data/ext/libgraphqlparser/lexer.lpp +0 -324
  268. data/ext/libgraphqlparser/libgraphqlparser.pc.in +0 -11
  269. data/ext/libgraphqlparser/parser.ypp +0 -693
  270. data/ext/libgraphqlparser/parsergen/lexer.cpp +0 -2633
  271. data/ext/libgraphqlparser/parsergen/lexer.h +0 -528
  272. data/ext/libgraphqlparser/parsergen/location.hh +0 -189
  273. data/ext/libgraphqlparser/parsergen/parser.tab.cpp +0 -3300
  274. data/ext/libgraphqlparser/parsergen/parser.tab.hpp +0 -646
  275. data/ext/libgraphqlparser/parsergen/position.hh +0 -179
  276. data/ext/libgraphqlparser/parsergen/stack.hh +0 -156
  277. data/ext/libgraphqlparser/python/CMakeLists.txt +0 -14
  278. data/ext/libgraphqlparser/python/README.md +0 -5
  279. data/ext/libgraphqlparser/python/example.py +0 -31
  280. data/ext/libgraphqlparser/syntaxdefs.h +0 -19
  281. data/ext/libgraphqlparser/test/BuildCAPI.c +0 -5
  282. data/ext/libgraphqlparser/test/CMakeLists.txt +0 -25
  283. data/ext/libgraphqlparser/test/JsonVisitorTests.cpp +0 -28
  284. data/ext/libgraphqlparser/test/ParserTests.cpp +0 -352
  285. data/ext/libgraphqlparser/test/kitchen-sink.graphql +0 -59
  286. data/ext/libgraphqlparser/test/kitchen-sink.json +0 -1
  287. data/ext/libgraphqlparser/test/schema-kitchen-sink.graphql +0 -78
  288. data/ext/libgraphqlparser/test/schema-kitchen-sink.json +0 -1
  289. data/ext/libgraphqlparser/test/valgrind.supp +0 -33
  290. data/ext/version.cpp +0 -21
  291. data/lib/graphqlparser.so +0 -0
  292. data/lib/rails/graphql/native/functions.rb +0 -38
  293. data/lib/rails/graphql/native/location.rb +0 -41
  294. data/lib/rails/graphql/native/pointers.rb +0 -23
  295. data/lib/rails/graphql/native/visitor.rb +0 -349
  296. data/lib/rails/graphql/native.rb +0 -56
  297. data/test/integration/schemas/authorization.rb +0 -12
data/ext/shared.c ADDED
@@ -0,0 +1,482 @@
1
+ #include "ruby.h"
2
+
3
+ #include "shared.h"
4
+
5
+ VALUE GQLParser = Qnil;
6
+ VALUE QLGParserToken = Qnil;
7
+ VALUE gql_eParserError = Qnil;
8
+
9
+ const char *GQL_VALUE_KEYWORDS[] = {
10
+ "true",
11
+ "false",
12
+ "null"
13
+ };
14
+
15
+ const char *GQL_EXECUTION_KEYWORDS[] = {
16
+ "query",
17
+ "mutation",
18
+ "subscription",
19
+ "fragment",
20
+ "on"
21
+ };
22
+
23
+ const char *GQL_DEFINITION_KEYWORDS[] = {
24
+ "schema",
25
+ "directive",
26
+ "enum",
27
+ "input",
28
+ "interface",
29
+ "scalar",
30
+ "type",
31
+ "union",
32
+ "extend",
33
+ "implements",
34
+ "repeatable"
35
+ };
36
+
37
+ /* INTERNAL HELPERS */
38
+ // Just a helper to print things on the console while testing/debugging
39
+ void gql_debug_print(const char *message)
40
+ {
41
+ rb_funcall(rb_mKernel, rb_intern("puts"), 1, rb_str_new2(message));
42
+ }
43
+
44
+ // Initialize a new scanner
45
+ struct gql_scanner gql_new_scanner(VALUE source)
46
+ {
47
+ char *doc = RSTRING_PTR(source);
48
+ struct gql_scanner scanner = {
49
+ .start_pos = 1, // Set to 1 just to begin different from the current position
50
+ .current_pos = 0,
51
+ .current_line = 1,
52
+ .last_ln_at = 0,
53
+ .current = doc[0],
54
+ .doc = doc};
55
+
56
+ return scanner;
57
+ }
58
+
59
+ // Returns the base index of the lexeme from where the upgrade should move from
60
+ enum gql_lexeme gql_upgrade_basis(const char *upgrade_from[])
61
+ {
62
+ if (*upgrade_from == *GQL_VALUE_KEYWORDS)
63
+ return gql_iv_true;
64
+ else if (*upgrade_from == *GQL_EXECUTION_KEYWORDS)
65
+ return gql_ie_query;
66
+ else if (*upgrade_from == *GQL_DEFINITION_KEYWORDS)
67
+ return gql_id_schema;
68
+ else
69
+ return gql_i_unknown;
70
+ }
71
+
72
+ // This checks if the identifier in the scanner should be upgraded to a keyword
73
+ enum gql_lexeme gql_name_to_keyword(struct gql_scanner *scanner, const char *upgrade_from[])
74
+ {
75
+ unsigned long pos, len = GQL_SCAN_SIZE(scanner);
76
+ unsigned int valid = 0, i = 0;
77
+ const char *keyword;
78
+
79
+ // Check until it finds the end of the array
80
+ while ((keyword = upgrade_from[i]) != 0)
81
+ {
82
+ // Move ot the next item and check the current for different size
83
+ if(strlen(keyword) == len)
84
+ {
85
+ // We cannot use the normal strcomp because we are comparing a mid part of the string
86
+ for (pos = 0, valid = 1; valid == 1 && pos < len; pos++)
87
+ {
88
+ if (keyword[pos] != scanner->doc[scanner->start_pos + pos])
89
+ valid = 0;
90
+ }
91
+
92
+ // Only return if valid was kept as true
93
+ if (valid == 1) return gql_upgrade_basis(upgrade_from) + i;
94
+ }
95
+
96
+ // Move to the next index
97
+ i++;
98
+ }
99
+
100
+ // Return name if was not able to upgrade to a keyword
101
+ return gql_i_name;
102
+ }
103
+
104
+ /* SCANNER HELPERS */
105
+ enum gql_lexeme gql_read_name(struct gql_scanner *scanner)
106
+ {
107
+ // Read all the chars and digits
108
+ GQL_SCAN_WHILE(scanner, GQL_S_CHARACTER(scanner->current) || GQL_S_DIGIT(scanner->current));
109
+ return gql_i_name;
110
+ }
111
+
112
+ enum gql_lexeme gql_read_comment(struct gql_scanner *scanner)
113
+ {
114
+ // Move forward until it finds a new line, change the line indicator and return
115
+ GQL_SCAN_WHILE(scanner, scanner->current != '\n');
116
+ GQL_SCAN_NEW_LINE(scanner);
117
+ return gql_i_comment;
118
+ }
119
+
120
+ enum gql_lexeme gql_read_hash(struct gql_scanner *scanner)
121
+ {
122
+ // Start with 1 curly open and get the next
123
+ int curly_opens = 1;
124
+ GQL_SCAN_NEXT(scanner);
125
+
126
+ while (curly_opens > 0)
127
+ {
128
+ // EOF returns unknown, { adds to the open, } removes from the open, " reads as string
129
+ if (scanner->current == '\0')
130
+ return gql_i_unknown;
131
+ else if (scanner->current == '"' && gql_read_string(scanner, 0) != gql_iv_string)
132
+ return gql_i_unknown;
133
+ else if (scanner->current == '{')
134
+ curly_opens++;
135
+ else if (scanner->current == '}')
136
+ curly_opens--;
137
+ else if (scanner->current == '\n')
138
+ GQL_SCAN_NEW_LINE(scanner);
139
+
140
+ // Just move to the next char
141
+ GQL_SCAN_NEXT(scanner);
142
+ }
143
+
144
+ // Save the last position, move to the next and return as hash
145
+ return gql_iv_hash;
146
+ }
147
+
148
+ enum gql_lexeme gql_read_float(struct gql_scanner *scanner)
149
+ {
150
+ // If what made it get in here was an '.', then it can recurse to the exponent of a fraction
151
+ int at_fraction = scanner->current == '.';
152
+
153
+ // Skip the float mark and maybe
154
+ GQL_SCAN_NEXT(scanner);
155
+
156
+ // Skip the exponent sign if possible
157
+ if (!at_fraction && (scanner->current == '+' || scanner->current == '-'))
158
+ GQL_SCAN_NEXT(scanner);
159
+
160
+ // If the current char is not a digit, we have an unknown
161
+ if (!GQL_S_DIGIT(scanner->current)) return gql_i_unknown;
162
+ GQL_SCAN_NEXT(scanner);
163
+
164
+ // Read all the numbers
165
+ GQL_SCAN_WHILE(scanner, GQL_S_DIGIT(scanner->current));
166
+
167
+ // If it is at fraction and the next is an exponent marker, then recurse
168
+ if (at_fraction && (scanner->current == 'e' || scanner->current == 'E'))
169
+ return gql_read_float(scanner);
170
+
171
+ // Otherwise save the last position and just finish the float
172
+ return gql_iv_float;
173
+ }
174
+
175
+ enum gql_lexeme gql_read_number(struct gql_scanner *scanner)
176
+ {
177
+ // Pass over the negative sign
178
+ if (scanner->current == '-') GQL_SCAN_NEXT(scanner);
179
+
180
+ // If begins with zero, it can only be 0 or error
181
+ if (scanner->current == '0')
182
+ return (GQL_S_DIGIT(GQL_SCAN_LOOK(scanner, 1))) ? gql_i_unknown : gql_iv_integer;
183
+
184
+ // Read all the numbers
185
+ GQL_SCAN_WHILE(scanner, GQL_S_DIGIT(scanner->current));
186
+
187
+ // Save the last position and halt the process if it's not a float marker
188
+ return (GQL_S_FLOAT_MARK(scanner->current)) ? gql_read_float(scanner) : gql_iv_integer;
189
+ }
190
+
191
+ enum gql_lexeme gql_read_string(struct gql_scanner *scanner, int allow_heredoc)
192
+ {
193
+ int start_size, end_size = 0;
194
+ unsigned long start = scanner->current_pos;
195
+
196
+ // Read all the initial quotes and save the size
197
+ GQL_SCAN_WHILE(scanner, scanner->current == '"');
198
+ start_size = (int)(scanner->current_pos - start);
199
+
200
+ // 4, 5, or more than 6 means an invalid triple-quotes block
201
+ if (start_size == 4 || start_size == 5 || start_size > 6)
202
+ return gql_i_unknown;
203
+
204
+ // 3 but not accepting heredoc returns an unknown
205
+ if (allow_heredoc == 0 && start_size == 3)
206
+ return gql_i_unknown;
207
+
208
+ // 2 or 6 means empty string
209
+ if (start_size == 2 || start_size == 6)
210
+ return gql_iv_string;
211
+
212
+ // Read until the start and end number of quotes matches
213
+ while (start_size != end_size)
214
+ {
215
+ // If it is a quote, add to end and move ot the next
216
+ if (scanner->current == '"')
217
+ {
218
+ end_size++;
219
+ }
220
+ else
221
+ {
222
+ // Anything that is not a quote reset the end size
223
+ end_size = 0;
224
+
225
+ // If we get to the end of the file, return an unknown
226
+ if (scanner->current == '\0')
227
+ return gql_i_unknown;
228
+
229
+ // Make sure to mark any new lines
230
+ if (scanner->current == '\n')
231
+ GQL_SCAN_NEW_LINE(scanner);
232
+
233
+ // Skip one extra character, which means it is skipping the escaped char
234
+ if (scanner->current == '\\')
235
+ GQL_SCAN_NEXT(scanner);
236
+ }
237
+
238
+ // Move the cursor
239
+ GQL_SCAN_NEXT(scanner);
240
+ }
241
+
242
+ // Regardless if a quote comes next, this is now a valid string
243
+ return (start_size == 3) ? gql_iv_heredoc : gql_iv_string;
244
+ }
245
+
246
+ /* MOST IMPORTANT TOKEN READ FUNCTION */
247
+ void gql_next_lexeme(struct gql_scanner *scanner)
248
+ {
249
+ // Do not move forward if it is unknown
250
+ if (scanner->lexeme == gql_i_unknown)
251
+ return;
252
+
253
+ // Temporary save the end line and end column
254
+ GQL_SCAN_SET_END(scanner, 0);
255
+
256
+ // Skip everything that can be ignored
257
+ GQL_SCAN_WHILE(scanner, GQL_S_IGNORE(scanner->current));
258
+
259
+ // Mark where the new interesting thing has started
260
+ scanner->start_pos = scanner->current_pos;
261
+ scanner->begin_line = scanner->current_line;
262
+ scanner->begin_column = scanner->current_pos - scanner->last_ln_at;
263
+
264
+ // Find what might be the next interesting thing
265
+ if (scanner->current == '\0')
266
+ scanner->lexeme = gql_i_eof;
267
+ else if (GQL_S_CHARACTER(scanner->current))
268
+ scanner->lexeme = gql_read_name(scanner);
269
+ else if (scanner->current == '#')
270
+ scanner->lexeme = gql_read_comment(scanner);
271
+ else if (GQL_S_DIGIT(scanner->current) || scanner->current == '-')
272
+ scanner->lexeme = gql_read_number(scanner);
273
+ else if (scanner->current == '"')
274
+ scanner->lexeme = gql_read_string(scanner, 1);
275
+ else if (scanner->current == '[')
276
+ scanner->lexeme = gql_is_op_brack;
277
+ else if (scanner->current == '{')
278
+ scanner->lexeme = gql_is_op_curly;
279
+ else if (scanner->current == '}')
280
+ scanner->lexeme = gql_is_cl_curly;
281
+ else if (scanner->current == '(')
282
+ scanner->lexeme = gql_is_op_paren;
283
+ else if (scanner->current == ')')
284
+ scanner->lexeme = gql_is_cl_paren;
285
+ else if (scanner->current == ':')
286
+ scanner->lexeme = gql_is_colon;
287
+ else if (scanner->current == '=')
288
+ scanner->lexeme = gql_is_equal;
289
+ else if (scanner->current == '.')
290
+ scanner->lexeme = gql_is_period;
291
+ else if (scanner->current == '@')
292
+ scanner->lexeme = gql_i_directive;
293
+ else if (scanner->current == '$')
294
+ scanner->lexeme = gql_i_variable;
295
+ else
296
+ scanner->lexeme = gql_i_unknown;
297
+ }
298
+
299
+ // Skip all comment lexemes
300
+ void gql_next_lexeme_no_comments(struct gql_scanner *scanner)
301
+ {
302
+ do
303
+ {
304
+ gql_next_lexeme(scanner);
305
+ } while (scanner->lexeme == gql_i_comment);
306
+ }
307
+
308
+ /* TOKEN CLASS HELPERS AND METHODS */
309
+ // Simply add the type of the token and return self for simplicity
310
+ VALUE gql_set_token_type(VALUE self, const char *type)
311
+ {
312
+ rb_iv_set(self, "@type", ID2SYM(rb_intern(type)));
313
+ return self;
314
+ }
315
+
316
+ // Just simply format the string with the token prefix
317
+ VALUE gql_inspect_token(VALUE self)
318
+ {
319
+ VALUE text = rb_call_super(0, 0);
320
+
321
+ if (rb_ivar_defined(self, rb_intern("@type")) == Qfalse)
322
+ return rb_sprintf("<GQLParser::Token %" PRIsVALUE ">", text);
323
+
324
+ VALUE type = rb_iv_get(self, "@type");
325
+ return rb_sprintf("<GQLParser::Token [%" PRIsVALUE "] %" PRIsVALUE ">", type, text);
326
+ }
327
+
328
+ // Check if the token is of the given type
329
+ VALUE gql_token_of_type_check(VALUE self, VALUE other)
330
+ {
331
+ VALUE type = rb_iv_get(self, "@type");
332
+ return rb_equal(type, other);
333
+ }
334
+
335
+ // Add the token module to the object and assign its location information
336
+ VALUE gql_as_token(VALUE self, struct gql_scanner *scanner, int save_type)
337
+ {
338
+ // Initialize the instance
339
+ VALUE instance = rb_class_new_instance(1, &self, QLGParserToken);
340
+
341
+ // Add the location instance variables
342
+ int offset = scanner->begin_line == 1 ? 1 : 0;
343
+ rb_iv_set(instance, "@begin_line", ULONG2NUM(scanner->begin_line));
344
+ rb_iv_set(instance, "@begin_column", ULONG2NUM(scanner->begin_column + offset));
345
+
346
+ offset = scanner->end_line == 1 ? 1 : 0;
347
+ rb_iv_set(instance, "@end_line", ULONG2NUM(scanner->end_line));
348
+ rb_iv_set(instance, "@end_column", ULONG2NUM(scanner->end_column + offset));
349
+
350
+ // Check if it has to save the type
351
+ if (save_type == 1)
352
+ {
353
+ // This only covers value types
354
+ if (scanner->lexeme == gql_iv_integer)
355
+ gql_set_token_type(instance, "int");
356
+ else if (scanner->lexeme == gql_iv_float)
357
+ gql_set_token_type(instance, "float");
358
+ else if (scanner->lexeme == gql_iv_string)
359
+ gql_set_token_type(instance, "string");
360
+ else if (scanner->lexeme == gql_iv_true)
361
+ gql_set_token_type(instance, "boolean");
362
+ else if (scanner->lexeme == gql_iv_false)
363
+ gql_set_token_type(instance, "boolean");
364
+ else if (scanner->lexeme == gql_iv_enum)
365
+ gql_set_token_type(instance, "enum");
366
+ else if (scanner->lexeme == gql_iv_array)
367
+ gql_set_token_type(instance, "array");
368
+ else if (scanner->lexeme == gql_iv_hash)
369
+ gql_set_token_type(instance, "hash");
370
+ else if (scanner->lexeme == gql_iv_heredoc)
371
+ gql_set_token_type(instance, "heredoc");
372
+ }
373
+
374
+ // Return the token instance
375
+ return instance;
376
+ }
377
+
378
+ /* RUBY-BASED HELPERS */
379
+ // Creates a Ruby String from the scanner
380
+ VALUE gql_scanner_to_s(struct gql_scanner *scanner)
381
+ {
382
+ return rb_str_new(scanner->doc + scanner->start_pos, GQL_SCAN_SIZE(scanner));
383
+ }
384
+
385
+ // Same as the above, but already extend it to a parser token
386
+ VALUE gql_scanner_to_token(struct gql_scanner *scanner)
387
+ {
388
+ return gql_as_token(gql_scanner_to_s(scanner), scanner, 0);
389
+ }
390
+
391
+ // Goes over an array and grab all the elements
392
+ VALUE gql_array_to_rb(struct gql_scanner *scanner)
393
+ {
394
+ // Start the array and the temporary element
395
+ VALUE result = rb_ary_new();
396
+ VALUE element;
397
+
398
+ // Save the scan and grab the next char
399
+ GQL_SCAN_NEXT(scanner);
400
+
401
+ // Iterate until it finds the end of the array
402
+ while (scanner->current != ']')
403
+ {
404
+ // If we got to the end of the file and the array was not closed, then we have something wrong
405
+ if (scanner->current == '\0')
406
+ {
407
+ scanner->lexeme = gql_i_unknown;
408
+ return Qnil;
409
+ }
410
+
411
+ // Save the element as an rb token, because we may need the type of each element afterwards
412
+ element = gql_value_to_token(scanner, 0);
413
+
414
+ // If it found an unknown, then we bubble the problem up
415
+ if (scanner->lexeme == gql_i_unknown)
416
+ return Qnil;
417
+
418
+ // Add the value to the array and scan through everything ignorable
419
+ rb_ary_push(result, element);
420
+ GQL_SCAN_WHILE(scanner, GQL_S_IGNORE(scanner->current));
421
+ }
422
+
423
+ // Save where the array has actually ended, change the lexeme and return
424
+ GQL_SCAN_SET_END(scanner, 0);
425
+ scanner->lexeme = gql_iv_array;
426
+ return result;
427
+ }
428
+
429
+ // Turn the current lexeme into its proper ruby object
430
+ VALUE gql_value_to_rb(struct gql_scanner *scanner, int accept_var)
431
+ {
432
+ // EXPERIMENTAL! Skip all the comments
433
+ gql_next_lexeme_no_comments(scanner);
434
+
435
+ // If got a variable and accepts variables,
436
+ // then it's fine and it won't be resolved in here
437
+ if (accept_var == 1 && scanner->lexeme == gql_i_variable)
438
+ return Qnil;
439
+
440
+ // Make sure to save the end position of the value
441
+ GQL_SCAN_SET_END(scanner, 0);
442
+
443
+ // If it's a name, then it can be a keyword or a enum value
444
+ if (scanner->lexeme == gql_i_name)
445
+ {
446
+ scanner->lexeme = gql_name_to_keyword(scanner, GQL_VALUE_KEYWORDS);
447
+ if (scanner->lexeme == gql_iv_true)
448
+ return Qtrue;
449
+ else if (scanner->lexeme == gql_iv_false)
450
+ return Qfalse;
451
+ else if (scanner->lexeme == gql_iv_null)
452
+ return Qnil;
453
+ else
454
+ scanner->lexeme = gql_iv_enum;
455
+ }
456
+
457
+ // Dealing with an array is way more complex, because you have to turn each
458
+ // individual value as an rb value
459
+ if (scanner->lexeme == gql_is_op_brack)
460
+ return gql_array_to_rb(scanner);
461
+
462
+ // If it is a hash, then we can just read through it and later get as a string
463
+ if (scanner->lexeme == gql_is_op_curly)
464
+ scanner->lexeme = gql_read_hash(scanner);
465
+
466
+ // By getting here with a proper value, just return the string of it, which
467
+ // will be dealt in the request
468
+ if (GQL_I_VALUE(scanner->lexeme))
469
+ return gql_scanner_to_s(scanner);
470
+
471
+ // If it got to this point, then it's an unknown
472
+ scanner->lexeme = gql_i_unknown;
473
+ return Qnil;
474
+ }
475
+
476
+ // Same as the above, but already extend it to a parser token
477
+ // IMPORTANT! This might generate a problem because nil, true, and false won't
478
+ // become parser tokens
479
+ VALUE gql_value_to_token(struct gql_scanner *scanner, int accept_var)
480
+ {
481
+ return gql_as_token(gql_value_to_rb(scanner, accept_var), scanner, 1);
482
+ }
data/ext/shared.h ADDED
@@ -0,0 +1,177 @@
1
+ #include "ruby.h"
2
+
3
+ #if !defined RB_INT_PARSE_DEFAULT
4
+ #define RB_INT_PARSE_DEFAULT 0x07
5
+ #endif
6
+
7
+ #define GQL_PUTS(...) gql_debug_print(RSTRING_PTR(rb_sprintf(__VA_ARGS__)))
8
+
9
+ #define GQL_I_STRUCTURE_FST 0x10
10
+ #define GQL_I_STRUCTURE_LST 0x1f
11
+
12
+ #define GQL_I_VALUE_FST 0x20
13
+ #define GQL_I_VALUE_LST 0x2f
14
+
15
+ #define GQL_I_EXECUTION_FST 0x30
16
+ #define GQL_I_EXECUTION_LST 0x3f
17
+
18
+ #define GQL_I_OPERATIONS_FST 0x30
19
+ #define GQL_I_OPERATIONS_LST 0x32
20
+
21
+ #define GQL_I_DEFINITION_FST 0x40
22
+ #define GQL_I_DEFINITION_LST 0x4f
23
+
24
+ #define GQL_I_STRUCTURE(x) (x >= GQL_I_STRUCTURE_FST && x <= GQL_I_STRUCTURE_LST)
25
+ #define GQL_I_VALUE(x) (x >= GQL_I_VALUE_FST && x <= GQL_I_VALUE_LST)
26
+ #define GQL_I_EXECUTION(x) (x >= GQL_I_EXECUTION_FST && x <= GQL_I_EXECUTION_LST)
27
+ #define QGL_I_OPERATION(x) (x >= GQL_I_OPERATIONS_FST && x <= GQL_I_OPERATIONS_LST)
28
+ #define GQL_I_DEFINITION(x) (x >= GQL_I_DEFINITION_FST && x <= GQL_I_DEFINITION_LST)
29
+
30
+ // https://www.asciitable.com/
31
+ #define GQL_S_IGNORE(x) (x == ' ' || x == ',' || x == '\n' || x == '\r' || x == '\t' || x == '\f' || x == '\b')
32
+ #define GQL_S_CHARACTER(x) ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || x == '_')
33
+ #define GQL_S_DIGIT(x) (x >= '0' && x <= '9')
34
+ #define GQL_S_FLOAT_MARK(x) (x == '.' || x == 'e' || x == 'E')
35
+
36
+ #define GQL_SCAN_ERROR(scanner) (scanner->lexeme == gql_i_eof || scanner->lexeme == gql_i_unknown)
37
+ #define GQL_SCAN_SIZE(scanner) (scanner->current_pos - scanner->start_pos)
38
+ #define GQL_SCAN_CHAR(scanner) (scanner->doc[scanner->current_pos])
39
+ #define GQL_SCAN_LOOK(scanner, bytes) (scanner->doc[scanner->current_pos + bytes])
40
+ #define GQL_SCAN_NEXT(scanner) ({ \
41
+ scanner->current_pos++; \
42
+ scanner->current = GQL_SCAN_CHAR(scanner); \
43
+ })
44
+ #define GQL_SCAN_NEW_LINE(scanner) ({ \
45
+ scanner->last_ln_at = scanner->current_pos; \
46
+ scanner->current_line++; \
47
+ })
48
+ #define GQL_SCAN_WHILE(scanner, check) ({ \
49
+ while (check) \
50
+ { \
51
+ if (GQL_SCAN_CHAR(scanner) == '\n') \
52
+ { \
53
+ GQL_SCAN_NEW_LINE(scanner); \
54
+ } \
55
+ GQL_SCAN_NEXT(scanner); \
56
+ } \
57
+ })
58
+ #define GQL_SCAN_SET_END(scanner, offset) ({ \
59
+ scanner->end_line = scanner->begin_line; \
60
+ scanner->end_column = scanner->current_pos - offset - scanner->last_ln_at; \
61
+ })
62
+ #define GQL_SCAN_SAVE(scanner, memory) ({ \
63
+ memory[0] = scanner->begin_line; \
64
+ memory[1] = scanner->begin_column; \
65
+ })
66
+
67
+ #define GQL_SAFE_PUSH(source, value) ({ \
68
+ if (NIL_P(source)) \
69
+ source = rb_ary_new(); \
70
+ rb_ary_push(source, value); \
71
+ })
72
+
73
+ enum gql_lexeme
74
+ {
75
+ // Basic identifiers
76
+ gql_i_eof = 0x00,
77
+ gql_i_name = 0x01,
78
+ gql_i_comment = 0x02,
79
+ gql_i_variable = 0x03,
80
+ gql_i_directive = 0x04,
81
+
82
+ // Structure identifiers
83
+ gql_is_op_curly = 0x10,
84
+ gql_is_cl_curly = 0x11,
85
+ gql_is_op_paren = 0x12,
86
+ gql_is_cl_paren = 0x13,
87
+ gql_is_op_brack = 0x14,
88
+ gql_is_cl_brack = 0x15,
89
+ gql_is_colon = 0x16,
90
+ gql_is_equal = 0x17,
91
+ gql_is_period = 0x18,
92
+
93
+ // Value based types
94
+ gql_iv_integer = 0x20,
95
+ gql_iv_float = 0x21,
96
+ gql_iv_string = 0x22,
97
+ gql_iv_true = 0x23,
98
+ gql_iv_false = 0x24,
99
+ gql_iv_null = 0x25,
100
+ gql_iv_enum = 0x26,
101
+ gql_iv_array = 0x27,
102
+ gql_iv_hash = 0x28,
103
+ gql_iv_heredoc = 0x2f,
104
+
105
+ // Execution keywords
106
+ gql_ie_query = 0x30,
107
+ gql_ie_mutation = 0x31,
108
+ gql_ie_subscription = 0x32,
109
+ gql_ie_fragment = 0x33,
110
+ gql_ie_on = 0x34,
111
+
112
+ // Definition keywords
113
+ gql_id_schema = 0x40,
114
+ gql_id_directive = 0x41,
115
+ gql_id_enum = 0x42,
116
+ gql_id_input = 0x43,
117
+ gql_id_interface = 0x44,
118
+ gql_id_scalar = 0x45,
119
+ gql_id_type = 0x46,
120
+ gql_id_union = 0x47,
121
+ gql_id_extend = 0x48,
122
+ gql_id_implements = 0x49,
123
+ gql_id_repeatable = 0x4a,
124
+
125
+ // Something went wrong
126
+ gql_i_unknown = 0xff
127
+ };
128
+
129
+ struct gql_scanner
130
+ {
131
+ unsigned long start_pos;
132
+ unsigned long current_pos;
133
+ unsigned long current_line;
134
+ unsigned long last_ln_at;
135
+ unsigned long begin_line;
136
+ unsigned long begin_column;
137
+ unsigned long end_line;
138
+ unsigned long end_column;
139
+ char *doc;
140
+ char current;
141
+ enum gql_lexeme lexeme;
142
+ };
143
+
144
+ VALUE GQLParser;
145
+ VALUE QLGParserToken;
146
+ VALUE gql_eParserError;
147
+
148
+ const char *GQL_VALUE_KEYWORDS[3];
149
+ const char *GQL_EXECUTION_KEYWORDS[5];
150
+ const char *GQL_DEFINITION_KEYWORDS[12];
151
+
152
+ void gql_debug_print(const char *message);
153
+ struct gql_scanner gql_new_scanner(VALUE source);
154
+
155
+ enum gql_lexeme gql_upgrade_basis(const char *upgrade_from[]);
156
+ enum gql_lexeme gql_name_to_keyword(struct gql_scanner *scanner, const char *upgrade_from[]);
157
+
158
+ enum gql_lexeme gql_read_name(struct gql_scanner *scanner);
159
+ enum gql_lexeme gql_read_comment(struct gql_scanner *scanner);
160
+ enum gql_lexeme gql_read_hash(struct gql_scanner *scanner);
161
+ enum gql_lexeme gql_read_float(struct gql_scanner *scanner);
162
+ enum gql_lexeme gql_read_number(struct gql_scanner *scanner);
163
+ enum gql_lexeme gql_read_string(struct gql_scanner *scanner, int allow_heredoc);
164
+
165
+ void gql_next_lexeme(struct gql_scanner *scanner);
166
+ void gql_next_lexeme_no_comments(struct gql_scanner *scanner);
167
+
168
+ VALUE gql_set_token_type(VALUE self, const char *type);
169
+ VALUE gql_inspect_token(VALUE self);
170
+ VALUE gql_token_of_type_check(VALUE self, VALUE other);
171
+ VALUE gql_as_token(VALUE self, struct gql_scanner *scanner, int save_type);
172
+
173
+ VALUE gql_scanner_to_s(struct gql_scanner *scanner);
174
+ VALUE gql_scanner_to_token(struct gql_scanner *scanner);
175
+ VALUE gql_array_to_rb(struct gql_scanner *scanner);
176
+ VALUE gql_value_to_rb(struct gql_scanner *scanner, int accept_var);
177
+ VALUE gql_value_to_token(struct gql_scanner *scanner, int accept_var);
data/lib/gql_parser.so ADDED
Binary file