Constant tree_sitter_javascript::GRAMMAR[][src]

pub const GRAMMAR: &'static str = "module.exports = grammar({\n  name: \'javascript\',\n\n  externals: $ => [\n    $._automatic_semicolon,\n    $._template_chars,\n    $._ternary_qmark,\n  ],\n\n  extras: $ => [\n    $.comment,\n    /[\\s\\p{Zs}\\uFEFF\\u2060\\u200B]/,\n  ],\n\n  supertypes: $ => [\n    $.statement,\n    $.declaration,\n    $.expression,\n    $.primary_expression,\n    $.pattern,\n  ],\n\n  inline: $ => [\n    $._call_signature,\n    $._formal_parameter,\n    $.statement,\n    $._expressions,\n    $._semicolon,\n    $._identifier,\n    $._reserved_identifier,\n    $._jsx_attribute,\n    $._jsx_element_name,\n    $._jsx_child,\n    $._jsx_element,\n    $._jsx_attribute_name,\n    $._jsx_attribute_value,\n    $._jsx_identifier,\n    $._lhs_expression,\n  ],\n\n  precedences: $ => [\n    [\n      \'member\',\n      \'call\',\n      $.update_expression,\n      \'unary_void\',\n      \'binary_exp\',\n      \'binary_times\',\n      \'binary_plus\',\n      \'binary_shift\',\n      \'binary_compare\',\n      \'binary_relation\',\n      \'binary_equality\',\n      \'bitwise_and\',\n      \'bitwise_xor\',\n      \'bitwise_or\',\n      \'logical_and\',\n      \'logical_or\',\n      \'ternary\',\n      $.sequence_expression,\n      $.arrow_function\n    ],\n    [\'assign\', $.primary_expression],\n    [\'member\', \'new\', \'call\', $.expression],\n    [\'declaration\', \'literal\'],\n    [$.primary_expression, $.statement_block, \'object\'],\n    [$.import_statement, $.import],\n    [$.export_statement, $.primary_expression],\n  ],\n\n  conflicts: $ => [\n    [$.primary_expression, $._property_name],\n    [$.primary_expression, $._property_name, $.arrow_function],\n    [$.primary_expression, $.arrow_function],\n    [$.primary_expression, $.method_definition],\n    [$.primary_expression, $.rest_pattern],\n    [$.primary_expression, $.pattern],\n    [$.primary_expression, $._for_header],\n    [$.array, $.array_pattern],\n    [$.object, $.object_pattern],\n    [$.assignment_expression, $.pattern],\n    [$.assignment_expression, $.object_assignment_pattern],\n    [$.labeled_statement, $._property_name],\n    [$.computed_property_name, $.array],\n    [$.binary_expression, $._initializer],\n  ],\n\n  word: $ => $.identifier,\n\n  rules: {\n    program: $ => seq(\n      optional($.hash_bang_line),\n      repeat($.statement)\n    ),\n\n    hash_bang_line: $ => /#!.*/,\n\n    //\n    // Export declarations\n    //\n\n    export_statement: $ => choice(\n      seq(\n        \'export\',\n        choice(\n          seq(\'*\', $._from_clause, $._semicolon),\n          seq(alias($.namespace_import_export, $.namespace_export), $._from_clause, $._semicolon),\n          seq($.export_clause, $._from_clause, $._semicolon),\n          seq($.export_clause, $._semicolon)\n        )\n      ),\n      seq(\n        repeat(field(\'decorator\', $.decorator)),\n        \'export\',\n        choice(\n          field(\'declaration\', $.declaration),\n          seq(\n            \'default\',\n            choice(\n              field(\'declaration\', $.declaration),\n              seq(\n                field(\'value\', $.expression),\n                $._semicolon\n              )\n            )\n          )\n        )\n      )\n    ),\n\n    export_clause: $ => seq(\n      \'{\',\n      commaSep(alias($._import_export_specifier, $.export_specifier)),\n      optional(\',\'),\n      \'}\'\n    ),\n\n    _import_export_specifier: $ => seq(\n      field(\'name\', $.identifier),\n      optional(seq(\n        \'as\',\n        field(\'alias\', $.identifier)\n      ))\n    ),\n\n    declaration: $ => choice(\n      $.function_declaration,\n      $.generator_function_declaration,\n      $.class_declaration,\n      $.lexical_declaration,\n      $.variable_declaration\n    ),\n\n    //\n    // Import declarations\n    //\n\n    import: $ => token(\'import\'),\n\n    import_statement: $ => seq(\n      \'import\',\n      choice(\n        seq($.import_clause, $._from_clause),\n        field(\'source\', $.string)\n      ),\n      $._semicolon\n    ),\n\n    import_clause: $ => choice(\n      alias($.namespace_import_export, $.namespace_import),\n      $.named_imports,\n      seq(\n        $.identifier,\n        optional(seq(\n          \',\',\n          choice(\n            alias($.namespace_import_export, $.namespace_import),\n            $.named_imports\n          )\n        ))\n      )\n    ),\n\n    _from_clause: $ => seq(\n      \"from\", field(\'source\', $.string)\n    ),\n\n    namespace_import_export: $ => seq(\n      \"*\", \"as\", $.identifier\n    ),\n\n    named_imports: $ => seq(\n      \'{\',\n      commaSep(alias($._import_export_specifier, $.import_specifier)),\n      optional(\',\'),\n      \'}\'\n    ),\n\n    //\n    // Statements\n    //\n\n    statement: $ => choice(\n      $.export_statement,\n      $.import_statement,\n      $.debugger_statement,\n      $.expression_statement,\n      $.declaration,\n      $.statement_block,\n\n      $.if_statement,\n      $.switch_statement,\n      $.for_statement,\n      $.for_in_statement,\n      $.while_statement,\n      $.do_statement,\n      $.try_statement,\n      $.with_statement,\n\n      $.break_statement,\n      $.continue_statement,\n      $.return_statement,\n      $.throw_statement,\n      $.empty_statement,\n      $.labeled_statement\n    ),\n\n    expression_statement: $ => seq(\n      $._expressions,\n      $._semicolon\n    ),\n\n    variable_declaration: $ => seq(\n      \'var\',\n      commaSep1($.variable_declarator),\n      $._semicolon\n    ),\n\n    lexical_declaration: $ => seq(\n      field(\'kind\', choice(\'let\', \'const\')),\n      commaSep1($.variable_declarator),\n      $._semicolon\n    ),\n\n    variable_declarator: $ => seq(\n      field(\'name\', choice($.identifier, $._destructuring_pattern)),\n      optional($._initializer)\n    ),\n\n    statement_block: $ => prec.right(seq(\n      \'{\',\n      repeat($.statement),\n      \'}\',\n      optional($._automatic_semicolon)\n    )),\n\n    else_clause: $ => seq(\'else\', $.statement),\n\n    if_statement: $ => prec.right(seq(\n      \'if\',\n      field(\'condition\', $.parenthesized_expression),\n      field(\'consequence\', $.statement),\n      optional(field(\'alternative\', $.else_clause))\n    )),\n\n    switch_statement: $ => seq(\n      \'switch\',\n      field(\'value\', $.parenthesized_expression),\n      field(\'body\', $.switch_body)\n    ),\n\n    for_statement: $ => seq(\n      \'for\',\n      \'(\',\n      field(\'initializer\', choice(\n        $.lexical_declaration,\n        $.variable_declaration,\n        $.expression_statement,\n        $.empty_statement\n      )),\n      field(\'condition\', choice(\n        $.expression_statement,\n        $.empty_statement\n      )),\n      field(\'increment\', optional($._expressions)),\n      \')\',\n      field(\'body\', $.statement)\n    ),\n\n    for_in_statement: $ => seq(\n      \'for\',\n      optional(\'await\'),\n      $._for_header,\n      field(\'body\', $.statement)\n    ),\n\n    _for_header: $ => seq(\n      \'(\',\n      choice(\n        field(\'left\', choice(\n          $._lhs_expression,\n          $.parenthesized_expression,\n        )),\n        seq(\n          field(\'kind\', \'var\'),\n          field(\'left\', choice(\n            $.identifier,\n            $._destructuring_pattern\n          )),\n          optional($._initializer)\n        ),\n        seq(\n          field(\'kind\', choice(\'let\', \'const\')),\n          field(\'left\', choice(\n            $.identifier,\n            $._destructuring_pattern\n          ))\n        )\n      ),\n      field(\'operator\', choice(\'in\', \'of\')),\n      field(\'right\', $._expressions),\n      \')\',\n    ),\n\n    while_statement: $ => seq(\n      \'while\',\n      field(\'condition\', $.parenthesized_expression),\n      field(\'body\', $.statement)\n    ),\n\n    do_statement: $ => seq(\n      \'do\',\n      field(\'body\', $.statement),\n      \'while\',\n      field(\'condition\', $.parenthesized_expression),\n      $._semicolon\n    ),\n\n    try_statement: $ => seq(\n      \'try\',\n      field(\'body\', $.statement_block),\n      optional(field(\'handler\', $.catch_clause)),\n      optional(field(\'finalizer\', $.finally_clause))\n    ),\n\n    with_statement: $ => seq(\n      \'with\',\n      field(\'object\', $.parenthesized_expression),\n      field(\'body\', $.statement)\n    ),\n\n    break_statement: $ => seq(\n      \'break\',\n      field(\'label\', optional(alias($.identifier, $.statement_identifier))),\n      $._semicolon\n    ),\n\n    continue_statement: $ => seq(\n      \'continue\',\n      field(\'label\', optional(alias($.identifier, $.statement_identifier))),\n      $._semicolon\n    ),\n\n    debugger_statement: $ => seq(\n      \'debugger\',\n      $._semicolon\n    ),\n\n    return_statement: $ => seq(\n      \'return\',\n      optional($._expressions),\n      $._semicolon\n    ),\n\n    throw_statement: $ => seq(\n      \'throw\',\n      $._expressions,\n      $._semicolon\n    ),\n\n    empty_statement: $ => \';\',\n\n    labeled_statement: $ => prec.dynamic(-1, seq(\n      field(\'label\', alias(choice($.identifier, $._reserved_identifier), $.statement_identifier)),\n      \':\',\n      field(\'body\', $.statement)\n    )),\n\n    //\n    // Statement components\n    //\n\n    switch_body: $ => seq(\n      \'{\',\n      repeat(choice($.switch_case, $.switch_default)),\n      \'}\'\n    ),\n\n    switch_case: $ => seq(\n      \'case\',\n      field(\'value\', $._expressions),\n      \':\',\n      field(\'body\', repeat($.statement))\n    ),\n\n    switch_default: $ => seq(\n      \'default\',\n      \':\',\n      field(\'body\', repeat($.statement))\n    ),\n\n    catch_clause: $ => seq(\n      \'catch\',\n      optional(seq(\'(\', field(\'parameter\', choice($.identifier, $._destructuring_pattern)), \')\')),\n      field(\'body\', $.statement_block)\n    ),\n\n    finally_clause: $ => seq(\n      \'finally\',\n      field(\'body\', $.statement_block)\n    ),\n\n    parenthesized_expression: $ => seq(\n      \'(\',\n      $._expressions,\n      \')\'\n    ),\n\n    //\n    // Expressions\n    //\n    _expressions: $ => choice(\n      $.expression,\n      $.sequence_expression\n    ),\n\n    expression: $ => choice(\n      $.primary_expression,\n      $._jsx_element,\n      $.jsx_fragment,\n      $.assignment_expression,\n      $.augmented_assignment_expression,\n      $.await_expression,\n      $.unary_expression,\n      $.binary_expression,\n      $.ternary_expression,\n      $.update_expression,\n      $.new_expression,\n      $.yield_expression,\n    ),\n\n    primary_expression: $ => choice(\n      $.subscript_expression,\n      $.member_expression,\n      $.parenthesized_expression,\n      $._identifier,\n      alias($._reserved_identifier, $.identifier),\n      $.this,\n      $.super,\n      $.number,\n      $.string,\n      $.template_string,\n      $.regex,\n      $.true,\n      $.false,\n      $.null,\n      $.import,\n      $.object,\n      $.array,\n      $.function,\n      $.arrow_function,\n      $.generator_function,\n      $.class,\n      $.meta_property,\n      $.call_expression,\n    ),\n\n    yield_expression: $ => prec.right(seq(\n      \'yield\',\n      choice(\n        seq(\'*\', $.expression),\n        optional($.expression)\n      ))),\n\n    object: $ => prec(\'object\', seq(\n      \'{\',\n      commaSep(optional(choice(\n        $.pair,\n        $.spread_element,\n        $.method_definition,\n        alias(\n          choice($.identifier, $._reserved_identifier),\n          $.shorthand_property_identifier\n        )\n      ))),\n      \'}\'\n    )),\n\n    object_pattern: $ => prec(\'object\', seq(\n      \'{\',\n      commaSep(optional(choice(\n        $.pair_pattern,\n        $.rest_pattern,\n        $.object_assignment_pattern,\n        alias(\n          choice($.identifier, $._reserved_identifier),\n          $.shorthand_property_identifier_pattern\n        )\n      ))),\n      \'}\'\n    )),\n\n    assignment_pattern: $ => seq(\n      field(\'left\', $.pattern),\n      \'=\',\n      field(\'right\', $.expression)\n    ),\n\n    object_assignment_pattern: $ => seq(\n      field(\'left\', choice(\n        alias(choice($._reserved_identifier, $.identifier), $.shorthand_property_identifier_pattern),\n        $._destructuring_pattern\n      )),\n      \'=\',\n      field(\'right\', $.expression)\n    ),\n\n    array: $ => seq(\n      \'[\',\n      commaSep(optional(choice(\n        $.expression,\n        $.spread_element\n      ))),\n      \']\'\n    ),\n\n    array_pattern: $ => seq(\n      \'[\',\n      commaSep(optional(choice(\n        $.pattern,\n        $.assignment_pattern,\n      ))),\n      \']\'\n    ),\n\n    _jsx_element: $ => choice($.jsx_element, $.jsx_self_closing_element),\n\n    jsx_element: $ => seq(\n      field(\'open_tag\', $.jsx_opening_element),\n      repeat($._jsx_child),\n      field(\'close_tag\', $.jsx_closing_element)\n    ),\n\n    jsx_fragment: $ => seq(\'<\', \'>\', repeat($._jsx_child), \'<\', \'/\', \'>\'),\n\n    jsx_text: $ => /[^{}<>]+/,\n\n    jsx_expression: $ => seq(\n      \'{\',\n      optional(choice(\n        $.expression,\n        $.sequence_expression,\n        $.spread_element\n      )),\n      \'}\'\n    ),\n\n    _jsx_child: $ => choice(\n      $.jsx_text,\n      $._jsx_element,\n      $.jsx_fragment,\n      $.jsx_expression\n    ),\n\n    jsx_opening_element: $ => prec.dynamic(-1, seq(\n      \'<\',\n      field(\'name\', $._jsx_element_name),\n      repeat(field(\'attribute\', $._jsx_attribute)),\n      \'>\'\n    )),\n\n    jsx_identifier: $ => /[a-zA-Z_$][a-zA-Z\\d_$]*-[a-zA-Z\\d_$\\-]*/,\n\n    _jsx_identifier: $ => choice(\n      alias($.jsx_identifier, $.identifier),\n      $.identifier\n    ),\n\n    nested_identifier: $ => prec(\'member\', seq(\n      choice($.identifier, $.nested_identifier),\n      \'.\',\n      $.identifier\n    )),\n\n    jsx_namespace_name: $ => seq($._jsx_identifier, \':\', $._jsx_identifier),\n\n    _jsx_element_name: $ => choice(\n      $._jsx_identifier,\n      $.nested_identifier,\n      $.jsx_namespace_name,\n    ),\n\n    jsx_closing_element: $ => seq(\n      \'<\',\n      \'/\',\n      field(\'name\', $._jsx_element_name),\n      \'>\'\n    ),\n\n    jsx_self_closing_element: $ => seq(\n      \'<\',\n      field(\'name\', $._jsx_element_name),\n      repeat(field(\'attribute\', $._jsx_attribute)),\n      \'/\',\n      \'>\'\n    ),\n\n    _jsx_attribute: $ => choice($.jsx_attribute, $.jsx_expression),\n\n    _jsx_attribute_name: $ => choice(alias($._jsx_identifier, $.property_identifier), $.jsx_namespace_name),\n\n    jsx_attribute: $ => seq(\n      $._jsx_attribute_name,\n      optional(seq(\n        \'=\',\n        $._jsx_attribute_value\n      ))\n    ),\n\n    _jsx_attribute_value: $ => choice(\n      $.string,\n      $.jsx_expression,\n      $._jsx_element,\n      $.jsx_fragment\n    ),\n\n    class: $ => prec(\'literal\', seq(\n      repeat(field(\'decorator\', $.decorator)),\n      \'class\',\n      field(\'name\', optional($.identifier)),\n      optional($.class_heritage),\n      field(\'body\', $.class_body)\n    )),\n\n    class_declaration: $ => prec(\'declaration\', seq(\n      repeat(field(\'decorator\', $.decorator)),\n      \'class\',\n      field(\'name\', $.identifier),\n      optional($.class_heritage),\n      field(\'body\', $.class_body),\n      optional($._automatic_semicolon)\n    )),\n\n    class_heritage: $ => seq(\'extends\', $.expression),\n\n    function: $ => prec(\'literal\', seq(\n      optional(\'async\'),\n      \'function\',\n      field(\'name\', optional($.identifier)),\n      $._call_signature,\n      field(\'body\', $.statement_block)\n    )),\n\n    function_declaration: $ => prec.right(\'declaration\', seq(\n      optional(\'async\'),\n      \'function\',\n      field(\'name\', $.identifier),\n      $._call_signature,\n      field(\'body\', $.statement_block),\n      optional($._automatic_semicolon)\n    )),\n\n    generator_function: $ => prec(\'literal\', seq(\n      optional(\'async\'),\n      \'function\',\n      \'*\',\n      field(\'name\', optional($.identifier)),\n      $._call_signature,\n      field(\'body\', $.statement_block)\n    )),\n\n    generator_function_declaration: $ => prec.right(\'declaration\', seq(\n      optional(\'async\'),\n      \'function\',\n      \'*\',\n      field(\'name\', $.identifier),\n      $._call_signature,\n      field(\'body\', $.statement_block),\n      optional($._automatic_semicolon)\n    )),\n\n    arrow_function: $ => seq(\n      optional(\'async\'),\n      choice(\n        field(\'parameter\', choice(\n          alias($._reserved_identifier, $.identifier),\n          $.identifier,\n        )),\n        $._call_signature\n      ),\n      \'=>\',\n      field(\'body\', choice(\n        $.expression,\n        $.statement_block\n      ))\n    ),\n\n    // Override\n    _call_signature: $ => field(\'parameters\', $.formal_parameters),\n    _formal_parameter: $ => choice($.pattern, $.assignment_pattern),\n\n    call_expression: $ => choice(\n      prec(\'call\', seq(\n        field(\'function\', $.expression),\n        field(\'arguments\', choice($.arguments, $.template_string))\n      )),\n      prec(\'member\', seq(\n        field(\'function\', $.primary_expression),\n        \'?.\',\n        field(\'arguments\', $.arguments)\n      ))\n    ),\n\n    new_expression: $ => prec.right(\'new\', seq(\n      \'new\',\n      field(\'constructor\', choice($.primary_expression, $.new_expression)),\n      field(\'arguments\', optional(prec.dynamic(1, $.arguments)))\n    )),\n\n    await_expression: $ => prec(\'unary_void\', seq(\n      \'await\',\n      $.expression\n    )),\n\n    member_expression: $ => prec(\'member\', seq(\n      field(\'object\', choice($.expression, $.primary_expression)),\n      choice(\'.\', \'?.\'),\n      field(\'property\', choice(\n        $.private_property_identifier,\n        alias($.identifier, $.property_identifier)))\n    )),\n\n    subscript_expression: $ => prec.right(\'member\', seq(\n      field(\'object\', choice($.expression, $.primary_expression)),\n      optional(\'?.\'),\n      \'[\', field(\'index\', $._expressions), \']\'\n    )),\n\n    _lhs_expression: $ => choice(\n      $.member_expression,\n      $.subscript_expression,\n      $._identifier,\n      alias($._reserved_identifier, $.identifier),\n      $._destructuring_pattern\n    ),\n\n    assignment_expression: $ => prec.right(\'assign\', seq(\n      field(\'left\', choice($.parenthesized_expression, $._lhs_expression)),\n      \'=\',\n      field(\'right\', $.expression)\n    )),\n\n    _augmented_assignment_lhs: $ => choice(\n      $.member_expression,\n      $.subscript_expression,\n      alias($._reserved_identifier, $.identifier),\n      $.identifier,\n      $.parenthesized_expression,\n    ),\n\n    augmented_assignment_expression: $ => prec.right(\'assign\', seq(\n      field(\'left\', $._augmented_assignment_lhs),\n      field(\'operator\', choice(\'+=\', \'-=\', \'*=\', \'/=\', \'%=\', \'^=\', \'&=\', \'|=\', \'>>=\', \'>>>=\',\n                               \'<<=\', \'**=\', \'&&=\', \'||=\', \'??=\')),\n      field(\'right\', $.expression)\n    )),\n\n    _initializer: $ => seq(\n      \'=\',\n      field(\'value\', $.expression)\n    ),\n\n    _destructuring_pattern: $ => choice(\n      $.object_pattern,\n      $.array_pattern\n    ),\n\n    spread_element: $ => seq(\'...\', $.expression),\n\n    ternary_expression: $ => prec.right(\'ternary\', seq(\n      field(\'condition\', $.expression),\n      alias($._ternary_qmark, \'?\'),\n      field(\'consequence\', $.expression),\n      \':\',\n      field(\'alternative\', $.expression)\n    )),\n\n    binary_expression: $ => choice(\n      ...[\n        [\'&&\', \'logical_and\'],\n        [\'||\', \'logical_or\'],\n        [\'>>\', \'binary_shift\'],\n        [\'>>>\', \'binary_shift\'],\n        [\'<<\', \'binary_shift\'],\n        [\'&\', \'bitwise_and\'],\n        [\'^\', \'bitwise_xor\'],\n        [\'|\', \'bitwise_or\'],\n        [\'+\', \'binary_plus\'],\n        [\'-\', \'binary_plus\'],\n        [\'*\', \'binary_times\'],\n        [\'/\', \'binary_times\'],\n        [\'%\', \'binary_times\'],\n        [\'**\', \'binary_exp\'],\n        [\'<\', \'binary_relation\'],\n        [\'<=\', \'binary_relation\'],\n        [\'==\', \'binary_equality\'],\n        [\'===\', \'binary_equality\'],\n        [\'!=\', \'binary_equality\'],\n        [\'!==\', \'binary_equality\'],\n        [\'>=\', \'binary_relation\'],\n        [\'>\', \'binary_relation\'],\n        [\'??\', \'ternary\'],\n        [\'instanceof\', \'binary_relation\'],\n        [\'in\', \'binary_relation\'],\n      ].map(([operator, precedence]) =>\n        prec.left(precedence, seq(\n          field(\'left\', $.expression),\n          field(\'operator\', operator),\n          field(\'right\', $.expression)\n        ))\n      )\n    ),\n\n    unary_expression: $ => prec.left(\'unary_void\', seq(\n      field(\'operator\', choice(\'!\', \'~\', \'-\', \'+\', \'typeof\', \'void\', \'delete\')),\n      field(\'argument\', $.expression)\n    )),\n\n    update_expression: $ => prec.left(choice(\n      seq(\n        field(\'argument\', $.expression),\n        field(\'operator\', choice(\'++\', \'--\'))\n      ),\n      seq(\n        field(\'operator\', choice(\'++\', \'--\')),\n        field(\'argument\', $.expression)\n      ),\n    )),\n\n    sequence_expression: $ => seq(\n      field(\'left\', $.expression),\n      \',\',\n      field(\'right\', choice($.sequence_expression, $.expression))\n    ),\n\n    //\n    // Primitives\n    //\n\n    // Here we tolerate unescaped newlines in double-quoted and\n    // single-quoted string literals.\n    // This is legal in typescript as jsx/tsx attribute values (as of\n    // 2020), and perhaps will be valid in javascript as well in the\n    // future.\n    //\n    string: $ => choice(\n      seq(\n        \'\"\',\n        repeat(choice(\n          alias($.unescaped_double_string_fragment, $.string_fragment),\n          $.escape_sequence\n        )),\n        \'\"\'\n      ),\n      seq(\n        \"\'\",\n        repeat(choice(\n          alias($.unescaped_single_string_fragment, $.string_fragment),\n          $.escape_sequence\n        )),\n        \"\'\"\n      )\n    ),\n\n    // Workaround to https://github.com/tree-sitter/tree-sitter/issues/1156\n    // We give names to the token() constructs containing a regexp\n    // so as to obtain a node in the CST.\n    //\n    unescaped_double_string_fragment: $ =>\n      token.immediate(prec(1, /[^\"\\\\]+/)),\n\n    // same here\n    unescaped_single_string_fragment: $ =>\n      token.immediate(prec(1, /[^\'\\\\]+/)),\n\n    escape_sequence: $ => token.immediate(seq(\n      \'\\\\\',\n      choice(\n        /[^xu0-7]/,\n        /[0-7]{1,3}/,\n        /x[0-9a-fA-F]{2}/,\n        /u[0-9a-fA-F]{4}/,\n        /u{[0-9a-fA-F]+}/\n      )\n    )),\n\n    // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890\n    comment: $ => token(choice(\n      seq(\'//\', /.*/),\n      seq(\n        \'/*\',\n        /[^*]*\\*+([^/*][^*]*\\*+)*/,\n        \'/\'\n      )\n    )),\n\n    template_string: $ => seq(\n      \'`\',\n      repeat(choice(\n        $._template_chars,\n        $.escape_sequence,\n        $.template_substitution\n      )),\n      \'`\'\n    ),\n\n    template_substitution: $ => seq(\n      \'${\',\n      $._expressions,\n      \'}\'\n    ),\n\n    regex: $ => seq(\n      \'/\',\n      field(\'pattern\', $.regex_pattern),\n      token.immediate(\'/\'),\n      optional(field(\'flags\', $.regex_flags))\n    ),\n\n    regex_pattern: $ => token.immediate(prec(-1,\n      repeat1(choice(\n        seq(\n          \'[\',\n          repeat(choice(\n            seq(\'\\\\\', /./), // escaped character\n            /[^\\]\\n\\\\]/       // any character besides \']\' or \'\\n\'\n          )),\n          \']\'\n        ),              // square-bracket-delimited character class\n        seq(\'\\\\\', /./), // escaped character\n        /[^/\\\\\\[\\n]/    // any character besides \'[\', \'\\\', \'/\', \'\\n\'\n      ))\n    )),\n\n    regex_flags: $ => token.immediate(/[a-z]+/),\n\n    number: $ => {\n      const hex_literal = seq(\n        choice(\'0x\', \'0X\'),\n        /[\\da-fA-F](_?[\\da-fA-F])*/\n      )\n\n      const decimal_digits = /\\d(_?\\d)*/\n      const signed_integer = seq(optional(choice(\'-\', \'+\')), decimal_digits)\n      const exponent_part = seq(choice(\'e\', \'E\'), signed_integer)\n\n      const binary_literal = seq(choice(\'0b\', \'0B\'), /[0-1](_?[0-1])*/)\n\n      const octal_literal = seq(choice(\'0o\', \'0O\'), /[0-7](_?[0-7])*/)\n\n      const bigint_literal = seq(choice(hex_literal, binary_literal, octal_literal, decimal_digits), \'n\')\n\n      const decimal_integer_literal = choice(\n        \'0\',\n        seq(optional(\'0\'), /[1-9]/, optional(seq(optional(\'_\'), decimal_digits)))\n      )\n\n      const decimal_literal = choice(\n        seq(decimal_integer_literal, \'.\', optional(decimal_digits), optional(exponent_part)),\n        seq(\'.\', decimal_digits, optional(exponent_part)),\n        seq(decimal_integer_literal, exponent_part),\n        seq(decimal_digits),\n      )\n\n      return token(choice(\n        hex_literal,\n        decimal_literal,\n        binary_literal,\n        octal_literal,\n        bigint_literal,\n      ))\n    },\n\n    // \'undefined\' is syntactically a regular identifier in JavaScript.\n    // However, its main use is as the read-only global variable whose\n    // value is [undefined], for which there\'s no literal representation\n    // unlike \'null\'. We gave it its own rule so it\'s easy to\n    // highlight in text editors and other applications.\n    _identifier: $ => choice(\n      $.undefined,\n      $.identifier\n    ),\n\n    identifier: $ => {\n      const alpha = /[^\\x00-\\x1F\\s\\p{Zs}0-9:;`\"\'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}/\n      const alphanumeric = /[^\\x00-\\x1F\\s\\p{Zs}:;`\"\'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}/\n      return token(seq(alpha, repeat(alphanumeric)))\n    },\n\n    private_property_identifier: $ => {\n      const alpha = /[^\\x00-\\x1F\\s\\p{Zs}0-9:;`\"\'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}/\n      const alphanumeric = /[^\\x00-\\x1F\\s\\p{Zs}:;`\"\'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}/\n      return token(seq(\'#\', alpha, repeat(alphanumeric)))\n    },\n\n    meta_property: $ => seq(\'new\', \'.\', \'target\'),\n\n    this: $ => \'this\',\n    super: $ => \'super\',\n    true: $ => \'true\',\n    false: $ => \'false\',\n    null: $ => \'null\',\n    undefined: $ => \'undefined\',\n\n    //\n    // Expression components\n    //\n\n    arguments: $ => seq(\n      \'(\',\n      commaSep(optional(choice($.expression, $.spread_element))),\n      \')\'\n    ),\n\n    decorator: $ => seq(\n      \'@\',\n      choice(\n        $.identifier,\n        alias($.decorator_member_expression, $.member_expression),\n        alias($.decorator_call_expression, $.call_expression)\n      )\n    ),\n\n    decorator_member_expression: $ => prec(\'member\', seq(\n      field(\'object\', choice(\n        $.identifier,\n        alias($.decorator_member_expression, $.member_expression)\n      )),\n      \'.\',\n      field(\'property\', alias($.identifier, $.property_identifier))\n    )),\n\n    decorator_call_expression: $ => prec(\'call\', seq(\n      field(\'function\', choice(\n        $.identifier,\n        alias($.decorator_member_expression, $.member_expression)\n      )),\n      field(\'arguments\', $.arguments)\n    )),\n\n    class_body: $ => seq(\n      \'{\',\n      repeat(choice(\n        seq(field(\'member\', $.method_definition), optional(\';\')),\n        seq(field(\'member\', $.field_definition), $._semicolon)\n      )),\n      \'}\'\n    ),\n\n    field_definition: $ => seq(\n      repeat(field(\'decorator\', $.decorator)),\n      optional(\'static\'),\n      field(\'property\', $._property_name),\n      optional($._initializer)\n    ),\n\n    formal_parameters: $ => seq(\n      \'(\',\n      optional(seq(\n        commaSep1($._formal_parameter),\n        optional(\',\')\n      )),\n      \')\'\n    ),\n\n    // This negative dynamic precedence ensures that during error recovery,\n    // unfinished constructs are generally treated as literal expressions,\n    // not patterns.\n    pattern: $ => prec.dynamic(-1, choice(\n      $._lhs_expression,\n      $.rest_pattern\n    )),\n\n    rest_pattern: $ => prec.right(seq(\n      \'...\',\n      $._lhs_expression\n    )),\n\n    method_definition: $ => seq(\n      repeat(field(\'decorator\', $.decorator)),\n      optional(\'static\'),\n      optional(\'async\'),\n      optional(choice(\'get\', \'set\', \'*\')),\n      field(\'name\', $._property_name),\n      field(\'parameters\', $.formal_parameters),\n      field(\'body\', $.statement_block)\n    ),\n\n    pair: $ => seq(\n      field(\'key\', $._property_name),\n      \':\',\n      field(\'value\', $.expression)\n    ),\n\n    pair_pattern: $ => seq(\n      field(\'key\', $._property_name),\n      \':\',\n      field(\'value\', choice($.pattern, $.assignment_pattern))\n    ),\n\n    _property_name: $ => choice(\n      alias(choice(\n        $.identifier,\n        $._reserved_identifier\n      ), $.property_identifier),\n      $.private_property_identifier,\n      $.string,\n      $.number,\n      $.computed_property_name\n    ),\n\n    computed_property_name: $ => seq(\n      \'[\',\n      $.expression,\n      \']\'\n    ),\n\n    _reserved_identifier: $ => choice(\n      \'get\',\n      \'set\',\n      \'async\',\n      \'static\',\n      \'export\'\n    ),\n\n    _semicolon: $ => choice($._automatic_semicolon, \';\')\n  }\n});\n\nfunction commaSep1(rule) {\n  return seq(rule, repeat(seq(\',\', rule)));\n}\n\nfunction commaSep(rule) {\n  return optional(commaSep1(rule));\n}\n";
Expand description

The source of the JavaScript tree-sitter grammar description.