tree-sitter-graphql 0.1.0

GraphQL grammar for tree-sitter
Documentation
module.exports = grammar({
  name: "graphql",

  extras: ($) => [/[\s\uFEFF\u0009\u0020\u000A\u000D]/, $.comma, $.comment],

  rules: {
    source_file: ($) => $.document,
    document: ($) => repeat1($.definition),
    definition: ($) =>
      choice(
        $.executable_definition,
        $.type_system_definition,
        $.type_system_extension
      ),
    executable_definition: ($) =>
      choice($.operation_definition, $.fragment_definition),
    type_system_definition: ($) =>
      choice($.schema_definition, $.type_definition, $.directive_definition),
    type_system_extension: ($) => choice($.schema_extension, $.type_extension),
    schema_definition: ($) =>
      seq(
        optional($.description),
        "schema",
        optional($.directives),
        "{",
        repeat1($.root_operation_type_definition),
        "}"
      ),
    schema_extension: ($) =>
      seq(
        "extend",
        "schema",
        optional($.directives),
        "{",
        $.root_operation_type_definition,
        "}"
      ),
    type_extension: ($) =>
      choice(
        $.scalar_type_extension,
        $.object_type_extension,
        $.interface_type_extension,
        $.union_type_extension,
        $.enum_type_extension,
        $.input_object_type_extension
      ),
    scalar_type_extension: ($) => seq("extend", "scalar", $.name, $.directives),
    object_type_extension: ($) =>
      prec.right(
        choice(
          seq(
            "extend",
            "type",
            $.name,
            optional($.implements_interfaces),
            optional($.directives),
            $.fields_definition
          ),
          seq(
            "extend",
            "type",
            $.name,
            optional($.implements_interfaces),
            optional($.directives)
          )
        )
      ),
    interface_type_extension: ($) =>
      prec.right(
        choice(
          seq(
            "extend",
            "interface",
            $.name,
            optional($.implements_interfaces),
            optional($.directives),
            $.fields_definition
          ),
          seq(
            "extend",
            "interface",
            $.name,
            optional($.implements_interfaces),
            optional($.directives)
          )
        )
      ),
    union_type_extension: ($) =>
      prec.right(
        choice(
          seq(
            "extend",
            "union",
            $.name,
            optional($.directives),
            $.union_member_types
          ),
          seq("extend", "union", $.name, optional($.directives))
        )
      ),
    enum_type_extension: ($) =>
      prec.right(
        choice(
          seq(
            "extend",
            "enum",
            $.name,
            optional($.directives),
            $.enum_values_definition
          ),
          seq("extend", "enum", $.name, optional($.directives))
        )
      ),
    input_object_type_extension: ($) =>
      prec.right(
        choice(
          seq(
            "extend",
            "input",
            $.name,
            optional($.directives),
            repeat1($.input_fields_definition)
          ),
          seq("extend", "input", $.name, optional($.directives))
        )
      ),
    input_fields_definition: ($) =>
      seq("{", repeat1($.input_value_definition), "}"),
    enum_values_definition: ($) =>
      seq("{", repeat1($.enum_value_definition), "}"),
    enum_value_definition: ($) =>
      seq(optional($.description), $.enum_value, optional($.directives)),
    implements_interfaces: ($) =>
      choice(
        seq($.implements_interfaces, "&", $.named_type),
        seq("implements", optional("&"), $.named_type)
      ),
    fields_definition: ($) => seq("{", repeat1($.field_definition), "}"),
    field_definition: ($) =>
      seq(
        optional($.description),
        $.name,
        optional($.arguments_definition),
        ":",
        $.type,
        optional($.directives)
      ),
    arguments_definition: ($) =>
      seq("(", repeat1($.input_value_definition), ")"),
    input_value_definition: ($) =>
      seq(
        optional($.description),
        $.name,
        ":",
        $.type,
        optional($.default_value),
        optional($.directives)
      ),
    default_value: ($) => seq("=", $.value),
    union_member_types: ($) =>
      choice(
        seq($.union_member_types, "|", $.named_type),
        seq("=", optional("|"), $.named_type)
      ),
    root_operation_type_definition: ($) =>
      seq($.operation_type, ":", $.named_type),
    operation_definition: ($) =>
      choice(
        $.selection_set,
        seq(
          $.operation_type,
          optional($.name),
          optional($.variable_definitions),
          optional($.directives),
          $.selection_set
        )
      ),
    operation_type: ($) => choice("query", "mutation", "subscription"),
    type_definition: ($) =>
      choice(
        $.scalar_type_definition,
        $.object_type_definition,
        $.interface_type_definition,
        $.union_type_definition,
        $.enum_type_definition,
        $.input_object_type_definition
      ),
    scalar_type_definition: ($) =>
      prec.right(
        seq(optional($.description), "scalar", $.name, optional($.directives))
      ),
    object_type_definition: ($) =>
      prec.right(
        seq(
          optional($.description),
          "type",
          $.name,
          optional($.implements_interfaces),
          optional($.directives),
          optional($.fields_definition)
        )
      ),
    interface_type_definition: ($) =>
      prec.right(
        seq(
          optional($.description),
          "interface",
          $.name,
          optional($.implements_interfaces),
          optional($.directives),
          optional($.fields_definition)
        )
      ),
    union_type_definition: ($) =>
      prec.right(
        seq(
          optional($.description),
          "union",
          $.name,
          optional($.directives),
          optional($.union_member_types)
        )
      ),
    enum_type_definition: ($) =>
      prec.right(
        seq(
          optional($.description),
          "enum",
          $.name,
          optional($.directives),
          optional($.enum_values_definition)
        )
      ),
    input_object_type_definition: ($) =>
      prec.right(
        seq(
          optional($.description),
          "input",
          $.name,
          optional($.directives),
          optional($.input_fields_definition)
        )
      ),
    variable_definitions: ($) => seq("(", repeat1($.variable_definition), ")"),
    variable_definition: ($) =>
      seq(
        $.variable,
        ":",
        $.type,
        optional($.default_value),
        optional($.directives),
        optional($.comma)
      ),
    selection_set: ($) => seq("{", repeat1($.selection), "}"),
    selection: ($) => choice($.field, $.inline_fragment, $.fragment_spread),
    field: ($) =>
      seq(
        optional($.alias),
        $.name,
        optional($.arguments),
        optional($.directive),
        optional($.selection_set)
      ),
    alias: ($) => seq($.name, ":"),
    arguments: ($) => seq("(", repeat1($.argument), ")"),
    argument: ($) => seq($.name, ":", $.value),
    value: ($) =>
      choice(
        $.variable,
        $.string_value,
        $.int_value,
        $.float_value,
        $.boolean_value,
        $.null_value,
        $.enum_value,
        $.list_value,
        $.object_value
      ),
    variable: ($) => seq("$", $.name),
    string_value: ($) =>
      choice(
        seq('"""', /([^"]|\n|""?[^"])*/, '"""'),
        seq('"', /[^"\\\n]*/, '"')
      ),
    int_value: ($) => /-?(0|[1-9][0-9]*)/,
    float_value: ($) =>
      token(
        seq(
          /-?(0|[1-9][0-9]*)/,
          choice(
            /\.[0-9]+/,
            /(e|E)(\+|-)?[0-9]+/,
            seq(/\.[0-9]+/, /(e|E)(\+|-)?[0-9]+/)
          )
        )
      ),
    boolean_value: ($) => choice("true", "false"),
    null_value: ($) => "null",
    enum_value: ($) => $.name,
    list_value: ($) => seq("[", repeat($.value), "]"),
    object_value: ($) => seq("{", repeat($.object_field), "}"),
    object_field: ($) => seq($.name, ":", $.value, optional($.comma)),
    fragment_spread: ($) => seq("...", $.fragment_name, optional($.directives)),
    fragment_definition: ($) =>
      seq(
        "fragment",
        $.fragment_name,
        $.type_condition,
        optional($.directives),
        $.selection_set
      ),
    fragment_name: ($) => $.name,
    inline_fragment: ($) =>
      seq(
        "...",
        optional($.type_condition),
        optional($.directives),
        $.selection_set
      ),
    type_condition: ($) => seq("on", $.named_type),
    directives: ($) => repeat1($.directive),
    directive: ($) => seq("@", $.name, optional($.arguments)),
    directive_definition: ($) =>
      prec.right(
        1,
        seq(
          optional($.description),
          "directive",
          "@",
          $.name,
          optional($.arguments_definition),
          optional("repeatable"),
          "on",
          $.directive_locations
        )
      ),
    directive_locations: ($) =>
      choice(
        seq($.directive_locations, "|", $.directive_location),
        seq(optional("|"), $.directive_location)
      ),
    directive_location: ($) =>
      choice($.executable_directive_location, $.type_system_directive_location),
    executable_directive_location: ($) =>
      choice(
        "QUERY",
        "MUTATION",
        "SUBSCRIPTION",
        "FIELD",
        "FRAGMENT_DEFINITION",
        "FRAGMENT_SPREAD",
        "INLINE_FRAGMENT",
        "VARIABLE_DEFINITION"
      ),
    type_system_directive_location: ($) =>
      choice(
        "SCHEMA",
        "SCALAR",
        "OBJECT",
        "FIELD_DEFINITION",
        "ARGUMENT_DEFINITION",
        "INTERFACE",
        "UNION",
        "ENUM",
        "ENUM_VALUE",
        "INPUT_OBJECT",
        "INPUT_FIELD_DEFINITION"
      ),
    type: ($) => choice($.named_type, $.list_type, $.non_null_type),
    named_type: ($) => $.name,
    list_type: ($) => seq("[", $.type, "]"),
    non_null_type: ($) => choice(seq($.named_type, "!"), seq($.list_type, "!")),
    name: ($) => /[_A-Za-z][_0-9A-Za-z]*/,
    comment: ($) => token(seq("#", /.*/)),
    comma: ($) => ",",
    description: ($) => $.string_value,
  },
});