File: graphql.rb

package info (click to toggle)
ruby-rouge 4.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,844 kB
  • sloc: ruby: 38,489; sed: 2,071; perl: 152; makefile: 8
file content (261 lines) | stat: -rw-r--r-- 6,064 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
  module Lexers
    class GraphQL < RegexLexer
      desc 'GraphQL'
      tag 'graphql'
      filenames '*.graphql', '*.gql'
      mimetypes 'application/graphql'

      name = /[_A-Za-z][_0-9A-Za-z]*/

      state :root do
        rule %r/\b(?:query|mutation|subscription)\b/, Keyword, :query_definition
        rule %r/\{/ do
          token Punctuation
          push :query_definition
          push :selection_set
        end

        rule %r/\bfragment\b/, Keyword, :fragment_definition

        rule %r/\bscalar\b/, Keyword, :value

        rule %r/\b(?:type|interface|enum)\b/, Keyword, :type_definition

        rule %r/\b(?:input|schema)\b/, Keyword, :type_definition

        rule %r/\bunion\b/, Keyword, :union_definition

        rule %r/\bextend\b/, Keyword

        mixin :basic

        # Markdown descriptions
        rule %r/(""")(\n)(.*?)(\n)(""")/m do |m|
          token Str::Double, m[1]
          token Text::Whitespace, m[2]
          delegate Markdown, m[3]
          token Text::Whitespace, m[4]
          token Str::Double, m[5]
        end
      end

      state :basic do
        rule %r/\s+/m, Text::Whitespace
        rule %r/#.*$/, Comment

        rule %r/[!,]/, Punctuation
      end

      state :has_directives do
        rule %r/(@#{name})(\s*)(\()/ do
          groups Keyword, Text::Whitespace, Punctuation
          push :arguments
        end
        rule %r/@#{name}\b/, Keyword
      end

      state :fragment_definition do
        rule %r/\bon\b/, Keyword

        mixin :query_definition
      end

      state :query_definition do
        mixin :has_directives

        rule %r/\b#{name}\b/, Name
        rule %r/\(/, Punctuation, :variable_definitions
        rule %r/\{/, Punctuation, :selection_set

        mixin :basic
      end

      state :type_definition do
        rule %r/\bimplements\b/, Keyword
        rule %r/\b#{name}\b/, Name
        rule %r/\(/, Punctuation, :variable_definitions
        rule %r/\{/, Punctuation, :type_definition_set

        mixin :basic
      end

      state :union_definition do
        rule %r/\b#{name}\b/, Name
        rule %r/\=/, Punctuation, :union_definition_variant

        mixin :basic
      end

      state :union_definition_variant do
        rule %r/\b#{name}\b/ do
          token Name
          pop!
          push :union_definition_pipe
        end

        mixin :basic
      end

      state :union_definition_pipe do
        rule %r/\|/ do
          token Punctuation
          pop!
          push :union_definition_variant
        end

        rule %r/(?!\||\s+|#[^\n]*)/ do
          pop! 2
        end

        mixin :basic
      end

      state :type_definition_set do
        rule %r/\}/ do
          token Punctuation
          pop! 2
        end

        rule %r/\b(#{name})(\s*)(\()/ do
          groups Name, Text::Whitespace, Punctuation
          push :variable_definitions
        end
        rule %r/\b#{name}\b/, Name

        rule %r/:/, Punctuation, :type_names

        mixin :basic
      end

      state :arguments do
        rule %r/\)/ do
          token Punctuation
          pop!
        end

        rule %r/\b#{name}\b/, Name
        rule %r/:/, Punctuation, :value

        mixin :basic
      end

      state :variable_definitions do
        rule %r/\)/ do
          token Punctuation
          pop!
        end

        rule %r/\$#{name}\b/, Name::Variable
        rule %r/\b#{name}\b/, Name
        rule %r/:/, Punctuation, :type_names
        rule %r/\=/, Punctuation, :value

        mixin :basic
      end

      state :type_names do
        rule %r/\b(?:Int|Float|String|Boolean|ID)\b/, Name::Builtin, :pop!
        rule %r/\b#{name}\b/, Name, :pop!

        rule %r/\[/, Punctuation, :type_name_list

        mixin :basic
      end

      state :type_name_list do
        rule %r/\b(?:Int|Float|String|Boolean|ID)\b/, Name::Builtin
        rule %r/\b#{name}\b/, Name

        rule %r/\]/ do
          token Punctuation
          pop! 2
        end

        mixin :basic
      end

      state :selection_set do
        mixin :has_directives

        rule %r/\}/ do
          token Punctuation
          pop!
          pop! if state?(:query_definition) || state?(:fragment_definition)
        end

        rule %r/\b(#{name})(\s*)(\()/ do
          groups Name, Text::Whitespace, Punctuation
          push :arguments
        end

        rule %r/\b(#{name})(\s*)(:)/ do
          groups Name, Text::Whitespace, Punctuation
        end

        rule %r/\b#{name}\b/, Name

        rule %r/(\.\.\.)(\s+)(on)\b/ do
          groups Punctuation, Text::Whitespace, Keyword
        end
        rule %r/\.\.\./, Punctuation

        rule %r/\{/, Punctuation, :selection_set

        mixin :basic
      end

      state :list do
        rule %r/\]/ do
          token Punctuation
          pop!
          pop! if state?(:value)
        end

        mixin :value
      end

      state :object do
        rule %r/\}/ do
          token Punctuation
          pop!
          pop! if state?(:value)
        end

        rule %r/\b(#{name})(\s*)(:)/ do
          groups Name, Text::Whitespace, Punctuation
          push :value
        end

        mixin :basic
      end

      state :value do
        pop_unless_list = ->(t) {
          ->(m) {
            token t
            pop! unless state?(:list)
          }
        }

        # Multiline strings
        rule %r/""".*?"""/m, Str::Double

        rule %r/\$#{name}\b/, &pop_unless_list[Name::Variable]
        rule %r/\b(?:true|false|null)\b/, &pop_unless_list[Keyword::Constant]
        rule %r/[+-]?[0-9]+\.[0-9]+(?:[eE][+-]?[0-9]+)?/, &pop_unless_list[Num::Float]
        rule %r/[+-]?[1-9][0-9]*(?:[eE][+-]?[0-9]+)?/, &pop_unless_list[Num::Integer]
        rule %r/"(\\[\\"]|[^"])*"/, &pop_unless_list[Str::Double]
        rule %r/\b#{name}\b/, &pop_unless_list[Name]

        rule %r/\{/, Punctuation, :object
        rule %r/\[/, Punctuation, :list

        mixin :basic
      end
    end
  end
end