244 lines
5.4 KiB
Ruby
244 lines
5.4 KiB
Ruby
# -*- 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 /\b(?:query|mutation|subscription)\b/, Keyword, :query_definition
|
|
rule /\{/ do
|
|
token Punctuation
|
|
push :query_definition
|
|
push :selection_set
|
|
end
|
|
|
|
rule /\bfragment\b/, Keyword, :fragment_definition
|
|
|
|
rule /\b(?:type|interface|enum)\b/, Keyword, :type_definition
|
|
rule /\b(?:input|schema)\b/, Keyword, :type_definition
|
|
|
|
rule /\bunion\b/, Keyword, :union_definition
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :basic do
|
|
rule /\s+/m, Text::Whitespace
|
|
rule /#.*$/, Comment
|
|
|
|
rule /[!,]/, Punctuation
|
|
end
|
|
|
|
state :has_directives do
|
|
rule /(@#{name})(\s*)(\()/ do
|
|
groups Keyword, Text::Whitespace, Punctuation
|
|
push :arguments
|
|
end
|
|
rule /@#{name}\b/, Keyword
|
|
end
|
|
|
|
state :fragment_definition do
|
|
rule /\bon\b/, Keyword
|
|
|
|
mixin :query_definition
|
|
end
|
|
|
|
state :query_definition do
|
|
mixin :has_directives
|
|
|
|
rule /\b#{name}\b/, Name
|
|
rule /\(/, Punctuation, :variable_definitions
|
|
rule /\{/, Punctuation, :selection_set
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :type_definition do
|
|
rule /\bimplements\b/, Keyword
|
|
rule /\b#{name}\b/, Name
|
|
rule /\(/, Punctuation, :variable_definitions
|
|
rule /\{/, Punctuation, :type_definition_set
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :union_definition do
|
|
rule /\b#{name}\b/, Name
|
|
rule /\=/, Punctuation, :union_definition_variant
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :union_definition_variant do
|
|
rule /\b#{name}\b/ do
|
|
token Name
|
|
pop!
|
|
push :union_definition_pipe
|
|
end
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :union_definition_pipe do
|
|
rule /\|/ do
|
|
token Punctuation
|
|
pop!
|
|
push :union_definition_variant
|
|
end
|
|
|
|
rule /(?!\||\s+|#[^\n]*)/ do
|
|
pop! 2
|
|
end
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :type_definition_set do
|
|
rule /\}/ do
|
|
token Punctuation
|
|
pop! 2
|
|
end
|
|
|
|
rule /\b(#{name})(\s*)(\()/ do
|
|
groups Name, Text::Whitespace, Punctuation
|
|
push :variable_definitions
|
|
end
|
|
rule /\b#{name}\b/, Name
|
|
|
|
rule /:/, Punctuation, :type_names
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :arguments do
|
|
rule /\)/ do
|
|
token Punctuation
|
|
pop!
|
|
end
|
|
|
|
rule /\b#{name}\b/, Name
|
|
rule /:/, Punctuation, :value
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :variable_definitions do
|
|
rule /\)/ do
|
|
token Punctuation
|
|
pop!
|
|
end
|
|
|
|
rule /\$#{name}\b/, Name::Variable
|
|
rule /\b#{name}\b/, Name
|
|
rule /:/, Punctuation, :type_names
|
|
rule /\=/, Punctuation, :value
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :type_names do
|
|
rule /\b(?:Int|Float|String|Boolean|ID)\b/, Name::Builtin, :pop!
|
|
rule /\b#{name}\b/, Name, :pop!
|
|
|
|
rule /\[/, Punctuation, :type_name_list
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :type_name_list do
|
|
rule /\b(?:Int|Float|String|Boolean|ID)\b/, Name::Builtin
|
|
rule /\b#{name}\b/, Name
|
|
|
|
rule /\]/ do
|
|
token Punctuation
|
|
pop! 2
|
|
end
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :selection_set do
|
|
mixin :has_directives
|
|
|
|
rule /\}/ do
|
|
token Punctuation
|
|
pop!
|
|
pop! if state?(:query_definition) || state?(:fragment_definition)
|
|
end
|
|
|
|
rule /\b(#{name})(\s*)(\()/ do
|
|
groups Name, Text::Whitespace, Punctuation
|
|
push :arguments
|
|
end
|
|
|
|
rule /\b(#{name})(\s*)(:)/ do
|
|
groups Name, Text::Whitespace, Punctuation
|
|
end
|
|
|
|
rule /\b#{name}\b/, Name
|
|
|
|
rule /(\.\.\.)(\s+)(on)\b/ do
|
|
groups Punctuation, Text::Whitespace, Keyword
|
|
end
|
|
rule /\.\.\./, Punctuation
|
|
|
|
rule /\{/, Punctuation, :selection_set
|
|
|
|
mixin :basic
|
|
end
|
|
|
|
state :list do
|
|
rule /\]/ do
|
|
token Punctuation
|
|
pop!
|
|
pop! if state?(:value)
|
|
end
|
|
|
|
mixin :value
|
|
end
|
|
|
|
state :object do
|
|
rule /\}/ do
|
|
token Punctuation
|
|
pop!
|
|
pop! if state?(:value)
|
|
end
|
|
|
|
rule /\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)
|
|
}
|
|
}
|
|
|
|
rule /\$#{name}\b/, &pop_unless_list[Name::Variable]
|
|
rule /\b(?:true|false|null)\b/, &pop_unless_list[Keyword::Constant]
|
|
rule /[+-]?[0-9]+\.[0-9]+(?:[eE][+-]?[0-9]+)?/, &pop_unless_list[Num::Float]
|
|
rule /[+-]?[1-9][0-9]*(?:[eE][+-]?[0-9]+)?/, &pop_unless_list[Num::Integer]
|
|
rule /"(\\[\\"]|[^"])*"/, &pop_unless_list[Str::Double]
|
|
rule /\b#{name}\b/, &pop_unless_list[Name]
|
|
|
|
rule /\{/, Punctuation, :object
|
|
rule /\[/, Punctuation, :list
|
|
|
|
mixin :basic
|
|
end
|
|
end
|
|
end
|
|
end
|