rails-graphql 0.2.1 → 1.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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