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.